A mobile-first grocery commerce frontend with role-based dashboards, location-aware product discovery, cart checkout, RajaOngkir shipping, and Xendit payment handoff.
Market Snap Web adalah frontend untuk aplikasi online grocery berbasis cabang toko. Customer melihat produk dari toko terdekat, mengelola cart, membuat order, memilih kurir, dan diarahkan ke invoice pembayaran. Admin dan admin store memiliki dashboard terpisah untuk operasional toko, produk, order, diskon, inventory, dan laporan.
Project ini dibuat sebagai repo frontend terpisah dan terhubung ke Market Snap API melalui NEXT_PUBLIC_API_URL.
Production handover: salin
.env.example, isi identitas bisnis milik pembeli, lalu bacaSECURITY.md,THIRD_PARTY_NOTICES.md,docs/DEPLOYMENT.md,docs/PWA_SEO.md,docs/TROUBLESHOOTING.md, dandocs/HANDOVER_CHECKLIST.md. Mode demo aktif secara default agar source code tidak mengarang identitas atau statistik bisnis.
- Preview Assets
- Features
- Tech Stack
- User Roles
- Project Structure
- Getting Started
- Environment Variables
- API Integration
- Available Scripts
- Deploy to Vercel
- Production Checklist
- Mobile-first grocery landing page with hero, category, promo, nearest store, and product sections.
- Location-aware catalog powered by the backend nearest-store API.
- Product listing, product detail, store detail, and stock visibility by selected branch.
- Guest cart persisten di browser, merge ke cart akun setelah login/OAuth, dan secure HttpOnly session untuk fitur akun.
- Checkout form with RajaOngkir destination ID, courier selection, and payment method.
- Xendit payment redirect when the API returns
payment.redirectUrl. - Customer profile, address page, checkout page, and order tracking pages.
- Protected admin dashboard for
adminandsuper_admin. - Store management, product management, category page, inventory report, user list, and store admin creation page.
- API-backed create forms for admin resources.
- Protected dashboard for
store_admin. - Store product view, category view, discount management, inventory management, order management, and assigned store page.
| Area | Technology |
|---|---|
| Framework | Next.js App Router |
| UI | React 19 |
| Language | TypeScript |
| Styling | Tailwind CSS 4 and custom CSS modules |
| Routing Guard | Next proxy |
| State | React hooks and local storage |
| API | Market Snap Express API |
| Deployment | Vercel |
Login response dari API menentukan dashboard tujuan user. JWT sesi hanya berada di cookie HttpOnly milik API; local storage menyimpan profil non-sensitif untuk tampilan, sedangkan cookie market-snap-role dipakai sebagai guard UI optimistis. Semua otorisasi sensitif tetap diverifikasi backend.
| API Role | Web Role | Redirect |
|---|---|---|
user |
customer |
/dashboard/customer |
admin |
admin |
/dashboard/admin |
super_admin |
admin |
/dashboard/admin |
store_admin |
adminStore |
/dashboard/adminStore |
web
├── app
│ ├── dashboard
│ │ ├── admin
│ │ ├── adminStore
│ │ └── customer
│ ├── login
│ ├── register
│ ├── favicon.ico
│ ├── globals.css
│ ├── icon.png
│ ├── layout.tsx
│ └── page.tsx
├── components
│ ├── dashboard
│ └── forms
├── lib
│ ├── api-contracts.ts
│ ├── api.ts
│ ├── dashboard-api.ts
│ └── types.ts
├── public
├── scripts
├── styles
├── proxy.ts
├── package.json
└── vercel.jsonClone the repository and install dependencies.
npm installRun the development server.
npm run devOpen the app:
http://localhost:3000If port 3000 is already used:
npm run dev -- -p 3200Create .env.local in the web project and point NEXT_PUBLIC_API_URL to your Market Snap API base URL. In production, set the same variable in Vercel and make sure the API WEB_ORIGIN matches the deployed web domain.
Main frontend helpers:
| File | Responsibility |
|---|---|
lib/api.ts |
Auth, catalog, cart, and checkout API client |
lib/api-contracts.ts |
API response and request contracts |
lib/dashboard-api.ts |
Dashboard snapshot fetcher |
Protected browser requests use the API session cookie with credentials: "include".
Cookie: market_snap_session=<httpOnly>/dashboard/customer/cart creates an order by sending this payload to POST /orders:
{
"total": 150000,
"destinationId": "41068",
"courier": "jne",
"paymentMethod": "xendit",
"location": { "lat": -6.2608, "lng": 106.8107 },
"items": [
{ "productId": "PRODUCT_ID", "quantity": 2, "price": 50000 }
]
}Expected API behavior:
- Use
locationto select the nearest branch. - Use
destinationIdandcourierto calculate shipping through RajaOngkir. - Use
paymentMethod: "xendit"to create a Xendit payment link. - Return
payment.redirectUrlso the web can redirect the customer to payment.
npm run dev # Start local development server
npm run build # Build production assets
npm run start # Start production server
npm run lint # Run ESLint
npm run type-check # Run TypeScript without emitting files
npm test # Run unit tests
npm run test:e2e # Run Playwright route/E2E smoke tests after buildMarket Snap keeps stable local assets under public/brand, public/banners, public/categories, public/products, public/illustrations, and public/placeholders.
Regenerate the SVG asset set after changing seed product/category names:
node scripts/generate-market-assets.mjsThis folder can be deployed as a standalone frontend repository.
- Push the
webfolder contents to a GitHub repository, for examplemarket-snap-web. - Import the repository in Vercel.
- Use the
Next.jsframework preset. - Set install command to
npm install. - Set build command to
npm run build. - Add
NEXT_PUBLIC_API_URLin Vercel Environment Variables. - Deploy the API first, then use the API deployment URL in this web project.
NEXT_PUBLIC_API_URLpoints to the deployed API domain.- API
WEB_ORIGINpoints to the deployed web domain. - API has valid
JWT_SECRET, database URL, RajaOngkir key, and Xendit key. - Customer, admin, and store admin accounts exist in the database.
- Product, store, inventory, and category data exist before testing checkout.
- Vercel build passes with
npm run build.



