Imported from root-Akira/Nutyum (
AGENTS.md). Install upstream withnpx skills add root-Akira/Nutyum. Copyright stays with the author.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ before writing any code. Heed deprecation notices.
IMPORTANT — No action without permission
Do NOT commit, push, or take any action (including file edits, installations, etc.) without the user explicitly asking you to. Wait for instructions.
Project: Nutyum — Premium Makhana Snacks
Tech Stack
- Frontend: Next.js 16.2.9 / React 19.2.4 / TypeScript 5 / Tailwind v4
- Animations: Framer Motion 12 + GSAP 3.15
- State: Zustand 5
- Forms: react-hook-form 7 + Zod 4
- Database: Supabase (PostgreSQL) + Drizzle ORM (Phase 2)
- Auth: NextAuth.js v5 (Phase 3)
- Payments: Razorpay (Phase 3)
- Deployment: Vercel
Session: 2026-07-27
- Logo & favicon update — navbar, email, checkout, admin panel all updated to use
/main%20logo.png(localpublic/folder) instead of deleted Supabase storage URL. Favicon resized to 192x192 square with white background. Admin login sidebar logo size increased. - Vercel deploy fix —
vercel.jsoncron*/30 * * * *blocked all builds on Hobby plan (limited to 1 cron/day). Changed to0 0 * * *. GitHub Vercel integration was also broken (missing webhook) — reinstalled Vercel GitHub App. Token-based deploy now working. - Admin panel TypeScript fix —
toast('...', 'warning')changed to'info'(not in union type). - Abandoned Razorpay order handling — added
cancellation_reasoncolumn toorderstable, migration backfills fromnotes+order_status_logs. Customer cancellation now writes tocancellation_reasoninstead of stuffing intonotes. Cron job (/api/cron/abandoned-orders) auto-cancels Razorpay orders stuck inplacedfor >2h.vercel.jsonconfigures*/30 * * * *cron schedule. Admin panel shows reason on order list + detail. Frontend order detail shows reason in cancelled banner. RequiresCRON_SECRETenv var on Vercel main site.
Session: 2026-07-01
Completed
- Robust error handling in API routes — 41 routes, 0 errors
- Navbar 70px, glass effect, hero carousel smooth animation
- Default address enforcement —
unsetAllDefaults()before setting new default - Account section — Profile, Orders, Wishlist, Addresses, Change Password all verified
- Hydration fix — passthrough provider replaced
next-themes - Coming Soon products —
isComingSoon+launchDate, badge, purchase disabled - BestSellers tabs — toggle Best Sellers / Coming Soon
- Our Origins — lucide SVG icons (Leaf, Globe, Mountain)
Repositories
- Main website →
https://github.com/root-Akira/Nutyum(this repo) - Admin panel →
https://github.com/root-Akira/Nutyum-admin(separate repo)
Session: 2026-07-02
Completed
- Admin panel scaffolded — Vite + React 19 + TS 6 + Tailwind v4
- Auth, Dashboard, Products (list/form), Orders (list/detail), Customers, Reviews, Coupons, CMS, Settings (shipping/payments/site)
Session: 2026-07-08
Completed
- Loading states & flash fixes — shop page no longer shows
STATIC_PRODUCTSfallback then replaces with real data (shows spinner while loading); product detail page same pattern; API caching headers (s-maxage=30, stale-while-revalidate=60) on/api/products - Block/unblock customers — admin detail page: Block/Unblock button with ConfirmModal; uses
supabaseAdmin.auth.admin.updateUserById()withban_duration: '876000h'(block) or'none'(unblock); syncsis_blockedtopublic.users; invalidates customer list query on success - Blocked badge on customer list — added
blockedstatus toStatusBadge(red "Blocked" label); list uses'blocked'instead of'cancelled' - Blocked user sign-in message —
CredentialsSigninsubclassBlockedErrorwith code"blocked";auth.tschecksusers.is_blockedbefore sign-in;SignInForm.tsxshows "Your account has been blocked. Please contact support." onresult.code === "blocked" - Session invalidation for blocked users —
jwtcallback queriesusers.is_blockedon every request; returns empty token if blocked, effectively logging them out - Loading states —
loading.tsxatapp/,app/shop/,app/shop/[slug]/,app/account/; spinner on/account/profilepage while profile data loads; form skeletons on adminproduct-form.tsxandcoupon-form.tsxedit modes; loading state on/account/account-settingsprofile section - Account redirect fix — moved
/account→/account/profileredirect frompage.tsxtonext.config.tsasync redirects(); deletedapp/account/page.tsxto eliminateAccountPageperformance.measure()error - Banners removed — deleted
banners.tsx, removed fromApp.tsxlazy import + route, removed fromsidebar.tsxnav link +ImageIconimport, removed fromdashboard-layout.tsxpath map - CMS Pages connected —
GET /api/cms/content?slug=:slugAPI route;/pages/[slug]dynamic route renders HTML content with prose styles;lib/cms.tsshared fetch helper; admin CMS Pages has "Seed Default Pages" button (inserts about/faq/contact with default HTML viaupsert ignoreDuplicates) - Out of stock button fix — added
variantsLoadingstate;outOfStocknow waits for variants to finish loading before deciding, preventing "Add to Cart" flash when all variants are OOS - You May Also Like alignment — horizontal scroll cards now have fixed
w-[260px]wrapper for consistent card sizing - Wishlist heart on BestSellers — added WishlistButton to BestSellers product cards
- ProductCard responsive width —
w-full max-w-[260px]instead of fixedw-[260px]to eliminate gap in grid layouts - Sidebar Sign Out — moved from Account Settings page to sidebar below Account Settings
- Hydration fix — replaced
next-themeswith passthrough provider to eliminate DOM attribute mismatch - Account section audit — all pages and API routes verified (Profile, Orders, Wishlist, Account Settings, addresses, change password)
- Coming Soon products —
isComingSoon+launchDateon Product type, DB migration (0004), seed update, badge logic, purchase disabled - BestSellers tabs — toggle between Best Sellers / Coming Soon with original gold badge design; "We are planning to bring something new!" when empty
- Our Origins icons — emojis replaced with lucide SVG icons (Leaf, Globe, Mountain) + glass effect
- No-action-without-permission rule — added to AGENTS.md
Main Website
- Set
is_best_seller=trueon DB products — 3 products already flagged ✅ - Razorpay payments integration (High)
- Google OAuth — configure
AUTH_GOOGLE_ID+AUTH_GOOGLE_SECRET(Medium) - Error boundaries —
app/error.tsx,app/global-error.tsx,app/not-found.tsxcreated - Align DB schemas — added
is_out_of_stock,image_alts,compare_price,sku,stock+ TypeScript types +mapDbToProductmapping - Bulk Order page — replace static wholesale page with real inquiry form + API (pending client feedback)
Admin Panel — Setup
- Run
supabase-migration.sqlin Supabase SQL Editor — all 10 tables created, default data inserted, users synced ✅ - Tighten RLS policies — admin role only (ss5494602@gmail.com) ✅
- Zod validation on admin forms — product, coupon, site settings forms (High/Medium)
- Configure SMTP for production email sending (password reset, order confirmations) (Low)
Admin Panel — Features Not Yet Built
- Variants per product (pack sizes / flavors)
- Bulk actions (prices, stock, delete)
- Stock history / low-stock threshold config
- Invoice generation / packing slips
- Block/unblock customers
- Auto-discounts
- Promotional pop-ups
- Courier partner integration
- Refund management
- GST / tax settings
- Analytics & reports (CSV export)
- Marketing tools (abandoned cart, campaigns, referral)
- Email/SMS notification templates
- Activity log / role-based access / auto-logout
Deployment
- Main site live at
https://nutyum.in✅ - Admin panel live at
https://admin.nutyum.in✅ - Google OAuth — configure
AUTH_GOOGLE_ID+AUTH_GOOGLE_SECRET(needs Cloud Console setup) - SMTP — configure for production email
Blocked (need Supabase Dashboard SQL Editor)
- Direct Postgres unreachable (IPv6 only, no route)
-
public.userstable + auth trigger created ✅ -
admin_replycolumn onreviews— Storage JSON fallback removed, using DB directly ✅ - DB schema drift on
productstable -
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS show_in_store BOOLEAN NOT NULL DEFAULT false;— done ✅
Nutyum Admin Panel — /home/akira/Downloads/nutyum-admin/
Tech Stack
- Vite 8 + React 19 + TypeScript 6 + Tailwind v4
- Supabase JS client (same project as main Nutyum)
- React Router v7 — SPA routing, lazy-loaded pages
- TanStack Query v5 — server state, cache, refetch intervals
- Lucide React — icons (matches main site)
Theme
Nutyum palette: #173D22 (green primary), #E0961A (gold accent), #FAF7EE (cream bg), #FFFEFB (card bg)
Features Built
| # | Section | Pages | Status |
|---|---|---|---|
| 1 | Auth | Login, ProtectedRoute, session timeout | ✅ |
| 2 | Dashboard | Stats cards (orders/revenue/pending/low-stock), recent orders, top products | ✅ |
| 3 | Products | List (search), Add/Edit form (images, stock, price, SEO, coming-soon toggle, tags, nutrition, ingredients, categories, vibes) | ✅ |
| 4 | Orders | List (filter by status, search), Detail (items, address, timeline, status update, tracking, internal notes, status history) | ✅ |
| 5 | Customers | List (search), Detail (profile, order history, addresses, stats) | ✅ |
| 6 | Reviews | Pending/approved tabs, approve/reject/delete, admin reply modal | ✅ |
| 7 | Coupons | List (search), Add/Edit form (type, value, min-order, dates, usage limits) | ✅ |
| 8 | CMS | Banners (add/delete/reorder), CMS Pages (list/edit HTML content), Vibes (add/list/delete) | ✅ |
| 9 | Settings | Shipping zones (add/delete), Payments (transaction log), Site Settings (store info, COD, maintenance mode, social links) | ✅ |
Running
cd /home/akira/Downloads/nutyum-admin
npm run dev # Vite dev server (default port 5173)
npm run build # tsc + vite build
Session: 2026-07-21
- COD payment implemented — checkout page shows Pay Online / Cash on Delivery radio buttons (fetches
cod_enabled/cod_chargefrom/api/site-settings). COD charge replaces shipping cost when > 0 (shows "₹X (COD)" instead of "FREE"). Order API handles COD flow: skips Razorpay, confirms immediately, sends confirmation email, clears cart. - Footer — removed Shop column. Connect column shows store email/phone/address/GST fetched from site_settings. Removed Blog link. Removed Journal from navbar.
- Admin site settings — removed Currency and Low Stock Threshold fields (user wanted only COD options). Low Stock Threshold restored on request. Currency hardcoded as INR.
Session: 2026-07-17
- Production login fixed —
NEXT_PUBLIC_SUPABASE_URLat module scope wasundefinedin auth server chunk (webpack DefinePlugin didn't inline it). Fixed by usingSUPABASE_URL(non-public, runtimeprocess.env) as primary fallback across all server files. - All DB operations fixed — Same
NEXT_PUBLIC_replacement issue affectedsupabase-fetch.ts,cms.ts,products.ts, and all API routes. Fixed all 7+ files. - Admin panel env vars added —
VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY,VITE_SUPABASE_SERVICE_ROLEconfigured on Vercel. - Main website — Login, cart, wishlist, addresses, profile, products, reviews, CMS pages all verified connected to database and working.
- Admin panel — Login page rendering at
admin.nutyum.in. - Google OAuth — Configured
AUTH_GOOGLE_ID+AUTH_GOOGLE_SECRETon Vercel. Auto-links new/existing Supabase Auth users by email. Working atnutyum.in/signin. - SMTP/Emails — Resend configured via Supabase SMTP. Custom HTML templates for Confirm Signup + Reset Password. Transactional email helper (
lib/email.ts) built with order confirmation/shipping/cancellation templates. - Client-side Supabase fix — Moved forgot password to server-side API route to avoid
NEXT_PUBLIC_replacement issue. Reset password form uses hardcoded Supabase URL fallback. - Pending: Razorpay payments + Checkout page (needed for order emails to work).
DB Tables Needed in Supabase
orders— order data with status/payment trackingorder_items— line items per orderorder_status_logs— status change historyproducts— product details (already exists)reviews— customer reviews (already exists)coupons— discount couponsbanners— homepage bannerscms_pages— static page contentshipping_zones— shipping rates by regionsite_settings— store-wide config (single row)users— customer profiles (already exists in auth schema)