Skip to content

Scaffold a new Med Tracker page. First ask the user for:

  1. Page name (PascalCase, e.g. Notifications)
  2. Route path (e.g. /notifications)
  3. Nav label EN (e.g. Notifications)
  4. Nav label zh-TW (e.g. 通知)
  5. Lucide icon (e.g. Bell)
  6. Nav section: add to sidebar nav or skip?

Then implement ALL of the following steps:

Step 1 — Create the page component

frontend/src/pages/{kebab-name}/{Name}Page.tsx

tsx
import { useTranslation } from 'react-i18next'

function {Name}Page() {
  const { t } = useTranslation()

  return (
    <div className="p-6 space-y-6">
      <div className="rounded-xl border border-border bg-surface p-6 nm-convex">
        <h1 className="text-2xl font-semibold text-text-primary">
          {t('nav.{camelName}')}
        </h1>
        <p className="mt-2 text-text-secondary">{t('common.comingSoon', 'Coming soon')}</p>
      </div>
    </div>
  )
}

export default {Name}Page

Step 2 — Register lazy route in App.tsx

In frontend/src/App.tsx, add:

tsx
const {Name}Page = React.lazy(() => import('./pages/{kebab-name}/{Name}Page'))

And add route inside <Route path="/" element={<AppLayout />}>:

tsx
<Route path="{route-path}" element={<{Name}Page />} />

Step 3 — Add sidebar nav item (if requested)

In frontend/src/components/layout/Sidebar.tsx, add to the appropriate nav array:

tsx
{ path: '{route-path}', label: t('nav.{camelName}'), icon: {Icon} }

Import the Lucide icon at the top.

Step 4 — Add i18n keys to BOTH locale files

frontend/src/i18n/locales/en.json — add under "nav":

json
"{camelName}": "{EN label}"

frontend/src/i18n/locales/zh-TW.json — add under "nav":

json
"{camelName}": "{zh-TW label}"

Step 5 — Create test file

frontend/src/pages/{kebab-name}/{Name}Page.test.tsx

tsx
import { render, screen } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { describe, it, expect, vi } from 'vitest'
import {Name}Page from './{Name}Page'

vi.mock('@/hooks/useReminderScheduler', () => ({ useReminderScheduler: vi.fn() }))
vi.mock('@/hooks/useBiomarkerAlerts', () => ({ useBiomarkerAlerts: () => ({ alerts: [] }) }))

describe('{Name}Page', () => {
  it('renders without crashing', () => {
    render(<MemoryRouter><{Name}Page /></MemoryRouter>)
    expect(screen.getByRole('heading')).toBeInTheDocument()
  })
})

Reminders

  • export default at the bottom is sufficient — no named export needed for React.lazy
  • nm-convex class applies only in Neo themes; safe to include always (no-op in default theme)
  • Run npx vitest run src/pages/{kebab-name}/ to verify test passes
  • If adding to Sidebar, always update BOTH en.json AND zh-TW.json

Read-only documentation bundle of the Med Tracker agent stack. AU compliance baked in (AHPRA + Privacy Act 1988 + Spam Act 2003).