Skip to content

Repository files navigation

Yarify Admin

Internal staff panel for Yarify. Next.js 16 App Router, React 19, Tailwind 4, shadcn/ui.

Specs: ../docs/06-CHECKLIST-Admin-UI.md (screens) and ../docs/05-CHECKLIST-Admin-API.md (contract). Working rules: CLAUDE.md.

Running it

npm install
npm run dev      # http://localhost:3000

Sign in with either demo account (shown on the login screen, click a row to fill the form):

Email Password Role
bhaskar@yarify.app yarify-demo-2026 superadmin
ops@yarify.app yarify-demo-2026 admin

Sign in as the admin account to see the role gating: the Team section disappears from the sidebar, and /team explains itself rather than 404ing.

Minimum window width is 1280px. Below 1024px the panel shows a notice instead of a broken table, which is deliberate (UI doc §0.4).

Current state: UI only, mock data

Every screen is complete and interactive, backed by an in-memory dataset in lib/mock/. Nothing talks to ../api yet. What works end to end against the mocks:

  • Suspending a user flips their row everywhere and writes an audit entry
  • Approving a verification grants the badge and clears it from the queue
  • Two "admins" cannot both claim one submission
  • Sending a campaign walks a real progress bar and lands final delivery stats
  • Deactivating a prompt or language persists; deleting an in-use one is refused
  • Adding a team member reveals a generated password exactly once

A new verification submission is injected 45 seconds after load so the live-notification path (toast, queue prepend, sidebar badge) can be seen without a backend.

Data is deterministic, seeded from a fixed PRNG with a fixed "now" of 2026-08-06T10:00. The same screenshot reproduces on every reload and on any machine, so approved designs do not drift. State resets on reload.

Swapping in the real API

One flag, then one branch per module. No dummy code is left behind, because the real transport already exists and is typed.

  1. Set NEXT_PUBLIC_USE_MOCKS=false in .env.local.
  2. Generate types from the live contract and delete the hand-written ones:
    npm run api:types      # ../api/openapi.json -> lib/api/schema.d.ts
    Re-export the names from lib/api/types.ts off the generated file, or keep that file as the single import surface and have it re-export. Nothing else imports the mock layer.
  3. In each lib/api/endpoints/*.ts, delete the code after the if (!USE_MOCKS) branch. The real http.get / http.post calls are already written above it.
  4. Delete lib/mock/ and lib/api/endpoints/session.ts (mock-only actor resolution).
  5. Replace the polling in lib/notifications/provider.tsx with a Socket.IO connection to the /admin namespace. The store, badges and toast throttling stay as they are; the polling path remains the documented fallback for when the socket is down.
  6. The three placeholder image helpers in lib/mock/media.ts become CloudFront and signed S3 URLs. Every consumer already treats them as opaque strings.

lib/api/http.ts is finished production code: single-flight refresh, one retry per 401, in-memory access token, credentials: 'include' for the httpOnly refresh cookie, and the error envelope parsed into ApiError.

Architecture

app/
├── login/                 login-01 block, adapted (no register, no reset, no social)
├── force-password/        unskippable first-login gate
└── (dash)/                sidebar-08 shell + auth boot + providers
    ├── page.tsx           dashboard: 8 KPI tiles, 4 charts, 2 activity panels
    ├── users/             list (11 columns, keyset paging) + detail (6 tabs, suspend)
    ├── reviews/           split queue + selfie-vs-photos compare + signals
    ├── marketing/push/    list + composer + detail
    ├── content/           prompts + languages
    ├── team/              superadmin only
    ├── audit/             read-only, grouped filters
    └── settings/
components/                9 custom wrappers, everything else is shadcn
lib/
├── api/                   types, config flag, http, token, errors, keys, endpoints/
├── mock/                  the only place that knows the data is fake
├── auth/                  AdminAuthProvider, usePermission, <Can>
├── notifications/          badge store + provider
└── hooks/                 useCursorList, useLocalFlag

Scripts

npm run dev
npm run build
npm run lint         # eslint, including the React Compiler rules
npm run typecheck    # tsc --noEmit
npm run api:types    # regenerate lib/api/schema.d.ts from ../api/openapi.json

components/ui/** and hooks/use-mobile.ts are generated by shadcn add and are excluded from lint. Do not hand-edit them.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages