# React Components - FRD Documentation

> **Usage:** React component templates for documentation pages
> **Loaded in:** step-06-doc-html.md
> **Context7:** /facebook/react, /lucide-icons/lucide-react

---

## FrdDocPage Component

```tsx
// web/smartstack-web/src/pages/docs/business/{app}/{module}/FrdDocPage.tsx

import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
  FileText,
  Users,
  Shield,
  CheckCircle,
  AlertTriangle,
  ChevronRight,
  ArrowRight,
  List,
  Layout,
  Database
} from 'lucide-react';
import type { FrdData } from './types';

// Import data (generated from FRD)
import { frdData } from './frdData';

// Priority Badge Component
function PriorityBadge({ priority }: { priority: string }) {
  const colors = {
    Must: 'bg-red-500/10 text-red-600',
    Should: 'bg-yellow-500/10 text-yellow-600',
    Could: 'bg-blue-500/10 text-blue-600'
  };
  return (
    <span className={`px-2 py-0.5 rounded text-xs font-medium ${colors[priority as keyof typeof colors] || 'bg-gray-500/10 text-gray-600'}`}>
      {priority}
    </span>
  );
}

// Numbered Section Component
function NumberedSection({
  number,
  title,
  icon: Icon,
  children
}: {
  number: number;
  title: string;
  icon: React.ComponentType<{ className?: string }>;
  children: React.ReactNode;
}) {
  return (
    <section id={`section-${number}`} className="scroll-mt-4">
      <h2 className="text-xl font-semibold mb-4 flex items-center gap-3">
        <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">
          {number}
        </span>
        <Icon className="w-5 h-5 text-[var(--color-primary-600)]" />
        {title}
      </h2>
      <div className="card p-6">
        {children}
      </div>
    </section>
  );
}

// Export page component
export function {ModuleName}FrdDocPage() {
  const { t } = useTranslation('docs-business');

  return (
    <div className="space-y-8">
      {/* Component implementation follows standard patterns */}
    </div>
  );
}

export function {ModuleName}FrdDocPage() {
  const { t } = useTranslation('docs-business');

  return (
    <div className="space-y-8">
      {/* Breadcrumb */}
      <nav className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
        <Link to="/docs" className="hover:text-[var(--color-primary-600)]">
          {t('breadcrumb.docs')}
        </Link>
        <span>/</span>
        <Link to="/docs/business" className="hover:text-[var(--color-primary-600)]">
          {t('breadcrumb.business')}
        </Link>
        <span>/</span>
        <Link to={`/docs/business/${frdData.applicationName.toLowerCase()}`} className="hover:text-[var(--color-primary-600)]">
          {t(`apps.${frdData.applicationName.toLowerCase()}.name`)}
        </Link>
        <span>/</span>
        <span>{t(`modules.${frdData.moduleName.toLowerCase()}.name`)}</span>
      </nav>

      {/* Header */}
      <header>
        <div className="flex items-center gap-2 mb-2">
          <span className="px-2 py-0.5 rounded bg-[var(--color-primary-600)]/10 text-[var(--color-primary-600)] text-xs font-medium">
            {frdData.featureId}
          </span>
          <span className="px-2 py-0.5 rounded bg-green-500/10 text-green-600 text-xs font-medium">
            v{frdData.version}
          </span>
        </div>
        <h1 className="text-3xl font-bold mb-4 flex items-center gap-3">
          <FileText className="w-8 h-8 text-[var(--color-primary-600)]" />
          {t(`modules.${frdData.moduleName.toLowerCase()}.title`)}
        </h1>
        <p className="text-lg text-[var(--text-secondary)]">
          {t(`modules.${frdData.moduleName.toLowerCase()}.subtitle`)}
        </p>
      </header>

      {/* Table of Contents */}
      <div className="card p-4 bg-[var(--bg-secondary)]">
        <h2 className="font-semibold mb-3 flex items-center gap-2">
          <List className="w-4 h-4" />
          {t('common.tableOfContents')}
        </h2>
        <nav className="grid grid-cols-2 md:grid-cols-3 gap-2">
          {['overview', 'useCases', 'businessRules', 'permissions', 'wireframes', 'api'].map((section, idx) => (
            <a
              key={section}
              href={`#section-${idx + 1}`}
              className="flex items-center gap-2 p-2 rounded hover:bg-[var(--bg-tertiary)] text-sm"
            >
              <ChevronRight className="w-4 h-4 text-[var(--color-primary-600)]" />
              {t(`sections.${section}`)}
            </a>
          ))}
        </nav>
      </div>

      {/* Sections follow standard pattern - see templates-react.md */}

      {/* Section 1: Overview */}
      <NumberedSection number={1} title={t('sections.overview')} icon={Layout}>
        <p className="text-[var(--text-secondary)] mb-4">
          {t(`modules.${frdData.moduleName.toLowerCase()}.overview`)}
        </p>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-4">
          <div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
            <div className="text-2xl font-bold text-[var(--color-primary-600)]">
              {frdData.useCases.length}
            </div>
            <div className="text-sm text-[var(--text-secondary)]">{t('stats.useCases')}</div>
          </div>
          <div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
            <div className="text-2xl font-bold text-[var(--color-primary-600)]">
              {frdData.businessRules.length}
            </div>
            <div className="text-sm text-[var(--text-secondary)]">{t('stats.businessRules')}</div>
          </div>
          <div className="p-4 rounded-lg bg-[var(--bg-secondary)] text-center">
            <div className="text-2xl font-bold text-[var(--color-primary-600)]">
              {frdData.permissions.length}
            </div>
            <div className="text-sm text-[var(--text-secondary)]">{t('stats.permissions')}</div>
          </div>
        </div>
      </NumberedSection>

      {/* Section 2: Use Cases */}
      <NumberedSection number={2} title={t('sections.useCases')} icon={Users}>
        <div className="space-y-4">
          {frdData.useCases.map((uc) => (
            <div key={uc.id} className="border border-[var(--border-color)] rounded-lg p-4">
              <div className="flex items-center justify-between mb-2">
                <h3 className="font-semibold flex items-center gap-2">
                  <span className="px-2 py-0.5 rounded bg-[var(--color-primary-600)]/10 text-[var(--color-primary-600)] text-xs font-mono">
                    {uc.id}
                  </span>
                  {uc.name}
                </h3>
                <span className="text-sm text-[var(--text-secondary)]">
                  {t('labels.actor')}: {uc.actor}
                </span>
              </div>
              <p className="text-sm text-[var(--text-secondary)] mb-2">{uc.description}</p>
              <div className="flex items-center gap-2 text-xs">
                <Shield className="w-3 h-3 text-amber-500" />
                <code className="bg-[var(--bg-secondary)] px-2 py-0.5 rounded">{uc.permission}</code>
              </div>
            </div>
          ))}
        </div>
      </NumberedSection>

      {/* Section 3: Business Rules */}
      <NumberedSection number={3} title={t('sections.businessRules')} icon={CheckCircle}>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="bg-[var(--bg-secondary)]">
                <th className="text-left py-2 px-3 rounded-tl-lg">ID</th>
                <th className="text-left py-2 px-3">{t('labels.rule')}</th>
                <th className="text-left py-2 px-3">{t('labels.category')}</th>
                <th className="text-left py-2 px-3 rounded-tr-lg">{t('labels.priority')}</th>
              </tr>
            </thead>
            <tbody>
              {frdData.businessRules.map((br, idx) => (
                <tr key={br.id} className={idx % 2 === 1 ? 'bg-[var(--bg-secondary)]/50' : ''}>
                  <td className="py-2 px-3 font-mono text-[var(--color-primary-600)]">{br.id}</td>
                  <td className="py-2 px-3">{br.rule}</td>
                  <td className="py-2 px-3 text-[var(--text-secondary)]">{br.category}</td>
                  <td className="py-2 px-3"><PriorityBadge priority={br.priority} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </NumberedSection>

      {/* Section 4: Permissions */}
      <NumberedSection number={4} title={t('sections.permissions')} icon={Shield}>
        <div className="space-y-3">
          {frdData.permissions.map((perm) => (
            <div key={perm.path} className="flex items-center justify-between p-3 rounded-lg bg-[var(--bg-secondary)]">
              <div>
                <code className="text-sm font-mono text-[var(--color-primary-600)]">{perm.path}</code>
                <p className="text-sm text-[var(--text-secondary)] mt-1">{perm.description}</p>
              </div>
              <div className="flex gap-1">
                {perm.roles.map((role) => (
                  <span key={role} className="px-2 py-0.5 rounded bg-[var(--bg-tertiary)] text-xs">
                    {role}
                  </span>
                ))}
              </div>
            </div>
          ))}
        </div>

        {/* Permission Warning */}
        <div className="mt-4 p-4 rounded-lg bg-amber-500/10 border border-amber-500/20 flex items-start gap-3">
          <AlertTriangle className="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5" />
          <div>
            <div className="font-medium text-amber-600">{t('warnings.permissionCheck')}</div>
            <p className="text-sm text-[var(--text-secondary)]">
              {t('warnings.permissionCheckDescription')}
            </p>
          </div>
        </div>
      </NumberedSection>

      {/* Section 5: Wireframes */}
      <NumberedSection number={5} title={t('sections.wireframes')} icon={Layout}>
        <div className="border-2 border-dashed border-[var(--border-color)] rounded-lg p-6">
          <div className="text-center text-sm text-[var(--text-tertiary)] mb-4">
            {t('common.wireframePreview')}
          </div>
          <div className="space-y-4">
            <div className="h-12 bg-[var(--bg-secondary)] rounded flex items-center px-4 justify-between">
              <span className="text-sm">[Header + Navigation]</span>
              <span className="text-sm">[User Menu]</span>
            </div>
            <div className="grid grid-cols-4 gap-4">
              <div className="col-span-1 h-64 bg-[var(--bg-secondary)] rounded p-4">
                <span className="text-sm">[Filters]</span>
              </div>
              <div className="col-span-3 h-64 bg-[var(--bg-secondary)] rounded p-4">
                <span className="text-sm">[Data Table]</span>
              </div>
            </div>
          </div>
        </div>
      </NumberedSection>

      {/* Section 6: API Endpoints */}
      <NumberedSection number={6} title={t('sections.api')} icon={Database}>
        <div className="overflow-x-auto">
          <table className="w-full text-sm font-mono">
            <thead>
              <tr className="bg-[var(--bg-secondary)]">
                <th className="text-left py-2 px-3 rounded-tl-lg">Method</th>
                <th className="text-left py-2 px-3">Endpoint</th>
                <th className="text-left py-2 px-3 rounded-tr-lg">Permission</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td className="py-2 px-3"><span className="px-2 py-0.5 rounded bg-green-500/10 text-green-600">GET</span></td>
                <td className="py-2 px-3">/api/business/{'{module}'}</td>
                <td className="py-2 px-3 text-[var(--text-secondary)]">.read</td>
              </tr>
              <tr className="bg-[var(--bg-secondary)]/50">
                <td className="py-2 px-3"><span className="px-2 py-0.5 rounded bg-blue-500/10 text-blue-600">POST</span></td>
                <td className="py-2 px-3">/api/business/{'{module}'}</td>
                <td className="py-2 px-3 text-[var(--text-secondary)]">.create</td>
              </tr>
              <tr>
                <td className="py-2 px-3"><span className="px-2 py-0.5 rounded bg-yellow-500/10 text-yellow-600">PUT</span></td>
                <td className="py-2 px-3">/api/business/{'{module}'}/{'{id}'}</td>
                <td className="py-2 px-3 text-[var(--text-secondary)]">.update</td>
              </tr>
              <tr className="bg-[var(--bg-secondary)]/50">
                <td className="py-2 px-3"><span className="px-2 py-0.5 rounded bg-red-500/10 text-red-600">DELETE</span></td>
                <td className="py-2 px-3">/api/business/{'{module}'}/{'{id}'}</td>
                <td className="py-2 px-3 text-[var(--text-secondary)]">.delete</td>
              </tr>
            </tbody>
          </table>
        </div>
      </NumberedSection>

      {/* Navigation Footer */}
      <div className="flex justify-between pt-6 border-t border-[var(--border-color)]">
        <Link
          to={`/docs/business/${frdData.applicationName.toLowerCase()}`}
          className="flex items-center gap-2 text-[var(--text-secondary)] hover:text-[var(--color-primary-600)]"
        >
          <ArrowRight className="w-4 h-4 rotate-180" />
          {t('nav.backToApp')}
        </Link>
        <Link
          to="/docs/business"
          className="flex items-center gap-2 text-[var(--color-primary-600)]"
        >
          {t('nav.allModules')}
          <ArrowRight className="w-4 h-4" />
        </Link>
      </div>
    </div>
  );
}
```
