Skip to content

Admin — def-exsport-frontend-admin

The internal admin / CMS for the store.

How this page was verified

Read on 2026-09-15 from package.json, next.config.ts, src/middleware.ts, the App Router tree, the Apollo/axios/NextAuth setup and the RBAC hook. Local checkout: /Volumes/xpro/erisristemena/nextjs/def-exsport-frontend-admin.

Stack

FrameworkNext.js 15.5.9 (App Router), React 19.0, TypeScript 5
DataApollo Client 3.12 + @apollo/experimental-nextjs-app-support; axios for file-upload create/update
AuthNextAuth 4 (Credentials + Google), jwt-decode
Formsreact-hook-form + zod
Rich textTinyMCE (Journals only)
UITailwind CSS v3 + a vendored Metronic template (no React component library)

Scripts: dev = next dev --turbopack, build = tsc --project tsconfig.build.json && next build (type-checks first), start = next start. Run locally with PORT=3012. tsconfig has strict: false; next.config.ts sets eslint.ignoreDuringBuilds: true.

Layout

  • src/app/admin/<area>/ — everything is under /admin; //admin/dashboard. Each area has a list page.tsx plus add-* / edit-* / [slug] pages.
  • src/lib/<domain>/index.ts (GraphQL), *.rest.ts (axios multipart), *.type.ts.
  • src/modules/<area>/ — forms and lists. src/components/ — shared building blocks over Metronic; src/metronic/ is vendor template code.

Areas: products (+ variants), heads-types, categories, sub-categories, brands, tags, series, collaborations, members, orders, stores, homepage, discounts, vouchers, flash-sales, journals (+ categories/tags), admins, roles.

How it works

  • Hybrid data access. Reads and file-less writes go through Apollo GraphQL (cache: "no-store"). Create/update with a file upload goes through axios REST (src/lib/http.ts) as multipart, to REST paths like catalogs/products.
  • Backend URL is ${NEXT_PUBLIC_API_URL}/graphql; the axios client shares the base URL.
  • Auth is NextAuth (src/app/auth.ts), Credentials + Google. The token rides in the session and is sent as Bearer. It auto-logs-out on the backend messages "no activity" and "Access token expired".
  • RBAC is data-driven and client-side: src/middleware.ts is only a "logged in?" gate; fine-grained rights come from useAccess(slug, action) (src/hooks/useAccess.tsx), which reads session.user.me.role.menus[] and hides sidebar items and redirects denied pages to /404. The backend enforces the same rights per resolver. See Admin users and RBAC.

Two things that surprise people

  • The dashboard is a stubsrc/app/admin/dashboard/page.tsx renders a bare heading. No analytics yet.
  • Orders are view-onlysrc/lib/orders has queries, no mutations.
  • Middleware mentions /profile and /settings, but those routes do not exist.

Config and quirks

  • next.config.ts: output: "standalone", global X-Robots-Tag: noindex (DEF07-2467), image domains from NEXT_PUBLIC_ASSETS_URL + S3.
  • Env includes NEXT_PUBLIC_TINY_EDITOR_API_KEY (in .env, missing from env.example) and NEXT_PUBLIC_BITESHIP_ENV.
  • The vouchers domain is spelled vourchers (src/lib/vourchers, vourcer.rest.ts); the products list component is Poducts. Cite as-is.

Branch model

Environment branches: main, staging, development. Auto-deploys on push.