- {/* Backdrop */}
-
toggleCart(false)}
- />
-
- {/* Drawer */}
-
- {/* Header */}
-
-
-
- {t('cart.title')}
-
- {t('cart.items', { count: items.length })}
-
-
-
-
-
- {/* Cart Items */}
-
- {items.length === 0 ? (
-
-
-
{t('cart.empty')}
-
-
- ) : (
- items.map((item) => (
-
-
-

-
-
-
-
{item.productName}
- {item.variantSize && (
-
{item.variantSize}
- )}
-
{formatPrice(item.price)}
-
-
-
-
{item.quantity}
-
-
-
-
-
-
- ))
- )}
-
-
- {/* Footer */}
- {items.length > 0 && (
-
-
- {t('cart.subtotal')}
- {formatPrice(getCartTotal())}
-
-
{t('cart.shippingNote')}
-
toggleCart(false)}
- className="btn-primary w-full py-4 text-center block uppercase tracking-widest text-sm"
- >
- {t('cart.proceed')}
-
-
- )}
-
-
- )
-}
diff --git a/apps/ssr/src/components/ScrollToTop.tsx b/apps/ssr/src/components/ScrollToTop.tsx
deleted file mode 100644
index 86e1187..0000000
--- a/apps/ssr/src/components/ScrollToTop.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-"use client";
-import { useEffect } from 'react'
-import { usePathname } from 'next/navigation'
-
-/**
- * Scrolls window to top on every route change (Next.js version).
- */
-export default function ScrollToTop() {
- const pathname = usePathname()
-
- useEffect(() => {
- window.scrollTo({ top: 0, behavior: 'instant' })
- }, [pathname])
-
- return null
-}
diff --git a/apps/ssr/tsconfig.json b/apps/ssr/tsconfig.json
deleted file mode 100644
index cf9c65d..0000000
--- a/apps/ssr/tsconfig.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2017",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "react-jsx",
- "incremental": true,
- "plugins": [
- {
- "name": "next"
- }
- ],
- "paths": {
- "@/*": ["./src/*"]
- }
- },
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts",
- ".next/dev/types/**/*.ts",
- "**/*.mts"
- ],
- "exclude": ["node_modules"]
-}
diff --git a/apps/website/.env.production b/apps/website/.env.production
index 4d396c4..e2d63b2 100644
--- a/apps/website/.env.production
+++ b/apps/website/.env.production
@@ -1,2 +1,2 @@
-VITE_LIFF_ID="2009944751-5IYZT5kH"
-VITE_API_URL="https://api.homaroma.shop/api"
+# Production - ชี้ไป Backend จริงบน server
+NEXT_PUBLIC_API_URL=https://api.homaroma.shop/api
diff --git a/apps/website/.gitignore b/apps/website/.gitignore
index e49999d..f8d9b7b 100644
--- a/apps/website/.gitignore
+++ b/apps/website/.gitignore
@@ -1,26 +1,44 @@
-# Logs
-logs
-*.log
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/versions
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
+.pnpm-debug.log*
-node_modules
-dist
-dist-ssr
-*.local
+# env files
+.env
+.env.local # secret ไว้บน dev เครื่องตัวเอง
+.env*.local
+# .env.production ← อนุญาตให้ commit (ไม่มี secret ใดๆ)
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
+# vercel
+.vercel
-!.env.production
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/apps/ssr/AGENTS.md b/apps/website/AGENTS.md
similarity index 100%
rename from apps/ssr/AGENTS.md
rename to apps/website/AGENTS.md
diff --git a/apps/ssr/CLAUDE.md b/apps/website/CLAUDE.md
similarity index 100%
rename from apps/ssr/CLAUDE.md
rename to apps/website/CLAUDE.md
diff --git a/apps/website/README.md b/apps/website/README.md
index 7dbf7eb..e215bc4 100644
--- a/apps/website/README.md
+++ b/apps/website/README.md
@@ -1,73 +1,36 @@
-# React + TypeScript + Vite
+This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+## Getting Started
-Currently, two official plugins are available:
+First, run the development server:
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
-
-## React Compiler
-
-The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
-
-## Expanding the ESLint configuration
-
-If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
-
-```js
-export default defineConfig([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
-
- // Remove tseslint.configs.recommended and replace with this
- tseslint.configs.recommendedTypeChecked,
- // Alternatively, use this for stricter rules
- tseslint.configs.strictTypeChecked,
- // Optionally, add this for stylistic rules
- tseslint.configs.stylisticTypeChecked,
-
- // Other configs...
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+# or
+bun dev
```
-You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-```js
-// eslint.config.js
-import reactX from 'eslint-plugin-react-x'
-import reactDom from 'eslint-plugin-react-dom'
+You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-export default defineConfig([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
- // Enable lint rules for React
- reactX.configs['recommended-typescript'],
- // Enable lint rules for React DOM
- reactDom.configs.recommended,
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
-```
+This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
diff --git a/apps/ssr/eslint.config.mjs b/apps/website/eslint.config.mjs
similarity index 100%
rename from apps/ssr/eslint.config.mjs
rename to apps/website/eslint.config.mjs
diff --git a/apps/ssr/next.config.ts b/apps/website/next.config.ts
similarity index 100%
rename from apps/ssr/next.config.ts
rename to apps/website/next.config.ts
diff --git a/apps/website/package.json b/apps/website/package.json
index b0b3ec4..7f86303 100644
--- a/apps/website/package.json
+++ b/apps/website/package.json
@@ -1,41 +1,40 @@
{
- "name": "website",
+ "name": "homaroma-website",
+ "version": "0.1.0",
"private": true,
- "version": "0.0.0",
- "type": "module",
"scripts": {
- "dev": "vite",
- "build": "tsc -b && vite build",
- "lint": "eslint .",
- "preview": "vite preview"
+ "dev": "next dev -p 3001",
+ "build": "next build",
+ "start": "next start",
+ "lint": "eslint"
},
"dependencies": {
+ "next": "16.2.4",
+ "react": "19.2.4",
+ "react-dom": "19.2.4",
"@homaroma/types": "workspace:*",
- "@line/liff": "^2.28.0",
- "i18next": "^26.0.4",
- "lucide-react": "^1.17.0",
- "react": "^19.2.4",
- "react-dom": "^19.2.4",
- "react-i18next": "^17.0.2",
- "react-router-dom": "^7.14.0",
- "zustand": "^5.0.12"
+ "lucide-react": "^0.475.0",
+ "zustand": "^5.0.0",
+ "i18next": "^24.0.0",
+ "react-i18next": "^15.0.0",
+ "axios": "^1.7.0"
},
"devDependencies": {
- "@eslint/js": "^9.39.4",
- "@tailwindcss/postcss": "^4.2.2",
- "@types/node": "^24.12.0",
- "@types/react": "^19.2.14",
- "@types/react-dom": "^19.2.3",
- "@vitejs/plugin-react": "^6.0.1",
- "autoprefixer": "^10.4.27",
- "eslint": "^9.39.4",
- "eslint-plugin-react-hooks": "^7.0.1",
- "eslint-plugin-react-refresh": "^0.5.2",
- "globals": "^17.4.0",
- "postcss": "^8.5.8",
- "tailwindcss": "^4.2.2",
- "typescript": "~5.9.3",
- "typescript-eslint": "^8.57.0",
- "vite": "^8.0.1"
- }
+ "@tailwindcss/postcss": "^4",
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "eslint": "^9",
+ "eslint-config-next": "16.2.4",
+ "tailwindcss": "^4",
+ "typescript": "^5"
+ },
+ "ignoreScripts": [
+ "sharp",
+ "unrs-resolver"
+ ],
+ "trustedDependencies": [
+ "sharp",
+ "unrs-resolver"
+ ]
}
diff --git a/apps/ssr/postcss.config.mjs b/apps/website/postcss.config.mjs
similarity index 100%
rename from apps/ssr/postcss.config.mjs
rename to apps/website/postcss.config.mjs
diff --git a/apps/ssr/public/file.svg b/apps/website/public/file.svg
similarity index 100%
rename from apps/ssr/public/file.svg
rename to apps/website/public/file.svg
diff --git a/apps/ssr/public/globe.svg b/apps/website/public/globe.svg
similarity index 100%
rename from apps/ssr/public/globe.svg
rename to apps/website/public/globe.svg
diff --git a/apps/ssr/public/next.svg b/apps/website/public/next.svg
similarity index 100%
rename from apps/ssr/public/next.svg
rename to apps/website/public/next.svg
diff --git a/apps/ssr/public/vercel.svg b/apps/website/public/vercel.svg
similarity index 100%
rename from apps/ssr/public/vercel.svg
rename to apps/website/public/vercel.svg
diff --git a/apps/ssr/public/window.svg b/apps/website/public/window.svg
similarity index 100%
rename from apps/ssr/public/window.svg
rename to apps/website/public/window.svg
diff --git a/apps/ssr/src/app/about/page.tsx b/apps/website/src/app/about/page.tsx
similarity index 100%
rename from apps/ssr/src/app/about/page.tsx
rename to apps/website/src/app/about/page.tsx
diff --git a/apps/ssr/src/app/article/[slug]/page.tsx b/apps/website/src/app/article/[slug]/page.tsx
similarity index 100%
rename from apps/ssr/src/app/article/[slug]/page.tsx
rename to apps/website/src/app/article/[slug]/page.tsx
diff --git a/apps/ssr/src/app/category/[id]/page.tsx b/apps/website/src/app/category/[id]/page.tsx
similarity index 100%
rename from apps/ssr/src/app/category/[id]/page.tsx
rename to apps/website/src/app/category/[id]/page.tsx
diff --git a/apps/ssr/src/app/contact/layout.tsx b/apps/website/src/app/contact/layout.tsx
similarity index 100%
rename from apps/ssr/src/app/contact/layout.tsx
rename to apps/website/src/app/contact/layout.tsx
diff --git a/apps/ssr/src/app/contact/page.tsx b/apps/website/src/app/contact/page.tsx
similarity index 100%
rename from apps/ssr/src/app/contact/page.tsx
rename to apps/website/src/app/contact/page.tsx
diff --git a/apps/ssr/src/app/coupons/page.tsx b/apps/website/src/app/coupons/page.tsx
similarity index 100%
rename from apps/ssr/src/app/coupons/page.tsx
rename to apps/website/src/app/coupons/page.tsx
diff --git a/apps/ssr/src/app/faq/layout.tsx b/apps/website/src/app/faq/layout.tsx
similarity index 100%
rename from apps/ssr/src/app/faq/layout.tsx
rename to apps/website/src/app/faq/layout.tsx
diff --git a/apps/ssr/src/app/faq/page.tsx b/apps/website/src/app/faq/page.tsx
similarity index 100%
rename from apps/ssr/src/app/faq/page.tsx
rename to apps/website/src/app/faq/page.tsx
diff --git a/apps/ssr/src/app/favicon.ico b/apps/website/src/app/favicon.ico
similarity index 100%
rename from apps/ssr/src/app/favicon.ico
rename to apps/website/src/app/favicon.ico
diff --git a/apps/ssr/src/app/globals.css b/apps/website/src/app/globals.css
similarity index 100%
rename from apps/ssr/src/app/globals.css
rename to apps/website/src/app/globals.css
diff --git a/apps/ssr/src/app/layout.tsx b/apps/website/src/app/layout.tsx
similarity index 100%
rename from apps/ssr/src/app/layout.tsx
rename to apps/website/src/app/layout.tsx
diff --git a/apps/ssr/src/app/page.tsx b/apps/website/src/app/page.tsx
similarity index 100%
rename from apps/ssr/src/app/page.tsx
rename to apps/website/src/app/page.tsx
diff --git a/apps/ssr/src/app/products/[id]/page.tsx b/apps/website/src/app/products/[id]/page.tsx
similarity index 100%
rename from apps/ssr/src/app/products/[id]/page.tsx
rename to apps/website/src/app/products/[id]/page.tsx
diff --git a/apps/ssr/src/app/scent-guide/page.tsx b/apps/website/src/app/scent-guide/page.tsx
similarity index 100%
rename from apps/ssr/src/app/scent-guide/page.tsx
rename to apps/website/src/app/scent-guide/page.tsx
diff --git a/apps/ssr/src/app/search/layout.tsx b/apps/website/src/app/search/layout.tsx
similarity index 100%
rename from apps/ssr/src/app/search/layout.tsx
rename to apps/website/src/app/search/layout.tsx
diff --git a/apps/ssr/src/app/search/page.tsx b/apps/website/src/app/search/page.tsx
similarity index 100%
rename from apps/ssr/src/app/search/page.tsx
rename to apps/website/src/app/search/page.tsx
diff --git a/apps/ssr/src/app/shop/layout.tsx b/apps/website/src/app/shop/layout.tsx
similarity index 100%
rename from apps/ssr/src/app/shop/layout.tsx
rename to apps/website/src/app/shop/layout.tsx
diff --git a/apps/ssr/src/app/shop/page.tsx b/apps/website/src/app/shop/page.tsx
similarity index 100%
rename from apps/ssr/src/app/shop/page.tsx
rename to apps/website/src/app/shop/page.tsx
diff --git a/apps/ssr/src/app/track/page.tsx b/apps/website/src/app/track/page.tsx
similarity index 100%
rename from apps/ssr/src/app/track/page.tsx
rename to apps/website/src/app/track/page.tsx
diff --git a/apps/ssr/src/components/AddToCartSection.tsx b/apps/website/src/components/AddToCartSection.tsx
similarity index 100%
rename from apps/ssr/src/components/AddToCartSection.tsx
rename to apps/website/src/components/AddToCartSection.tsx
diff --git a/apps/website/src/components/CartDrawer.tsx b/apps/website/src/components/CartDrawer.tsx
index 831221a..9cf87b6 100644
--- a/apps/website/src/components/CartDrawer.tsx
+++ b/apps/website/src/components/CartDrawer.tsx
@@ -1,10 +1,9 @@
-import React from 'react'
-import { X, ShoppingBag, Plus, Minus, Trash2, Tag, ArrowRight } from 'lucide-react'
-import { Link } from 'react-router-dom'
+"use client";
+import { X, ShoppingBag, Plus, Minus, Trash2 } from 'lucide-react'
+import Link from 'next/link'
import { useCartStore } from '../store/cartStore'
import { formatPrice } from '@homaroma/types'
import { useTranslation } from 'react-i18next'
-import { API_BASE } from '../types'
export default function CartDrawer() {
const { t } = useTranslation()
@@ -40,7 +39,7 @@ export default function CartDrawer() {
{/* Cart Items */}
-