Files
alrahma_sunday_school_api/docs/stubs/PermissionsMatrix.tsx
T
2026-06-11 03:22:12 -04:00

116 lines
5.1 KiB
TypeScript

'use client'
type Access = 'full' | 'partial' | 'none'
interface Feature {
label: string
manager: Access
managerNote?: string
agent: Access
agentNote?: string
}
const FEATURES: Feature[] = [
{ label: 'View fleet & vehicles', manager: 'full', agent: 'full' },
{ label: 'Add / edit vehicles', manager: 'full', agent: 'none' },
{ label: 'Publish / unpublish vehicle', manager: 'full', agent: 'none' },
{ label: 'Upload vehicle photos', manager: 'full', agent: 'none' },
{ label: 'View reservations', manager: 'full', agent: 'full' },
{ label: 'Create reservations', manager: 'full', agent: 'full' },
{ label: 'Cancel reservations', manager: 'full', agent: 'partial', agentNote: 'Own only' },
{ label: 'Check-in / check-out', manager: 'full', agent: 'full' },
{ label: 'Damage inspection', manager: 'full', agent: 'full' },
{ label: 'Customer CRM — view', manager: 'full', agent: 'full' },
{ label: 'Customer CRM — edit', manager: 'full', agent: 'partial', agentNote: 'Notes only' },
{ label: 'Approve driver licenses', manager: 'full', agent: 'none' },
{ label: 'Flag / blacklist customer', manager: 'full', agent: 'none' },
{ label: 'Offers & promotions', manager: 'full', agent: 'none' },
{ label: 'Analytics & reports', manager: 'full', agent: 'none' },
{ label: 'Contract & invoice PDF', manager: 'full', agent: 'full' },
{ label: 'Billing & subscription', manager: 'none', agent: 'none' },
{ label: 'Invite / remove staff', manager: 'none', agent: 'none' },
{ label: 'Brand & site settings', manager: 'none', agent: 'none' },
{ label: 'Payment settings', manager: 'none', agent: 'none' },
]
function AccessCell({ access, note }: { access: Access; note?: string }) {
if (access === 'full') {
return (
<div className="flex items-center gap-1.5">
<svg className="w-3.5 h-3.5 text-green-600 dark:text-green-400 flex-shrink-0" fill="none" viewBox="0 0 14 14">
<path d="M2.5 7L5.5 10L11.5 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
<span className="text-xs text-zinc-700 dark:text-zinc-300">Full</span>
</div>
)
}
if (access === 'partial') {
return (
<div className="flex items-center gap-1.5">
<div className="w-3.5 h-3.5 flex-shrink-0 flex items-center justify-center">
<div className="w-2.5 h-0.5 rounded bg-amber-500" />
</div>
<span className="text-xs text-amber-700 dark:text-amber-400">{note ?? 'Limited'}</span>
</div>
)
}
return (
<div className="flex items-center gap-1.5">
<div className="w-3.5 h-3.5 flex-shrink-0 flex items-center justify-center">
<div className="w-2 h-0.5 rounded bg-zinc-300 dark:bg-zinc-600" />
</div>
<span className="text-xs text-zinc-400 dark:text-zinc-600">No access</span>
</div>
)
}
export default function PermissionsMatrix() {
return (
<div>
<div className="mb-4">
<h2 className="text-base font-medium text-zinc-900 dark:text-white">Role permissions</h2>
<p className="text-sm text-zinc-500 dark:text-zinc-400 mt-0.5">
What each role can do across the dashboard. Owners have full access to everything.
</p>
</div>
<div className="border border-zinc-200 dark:border-zinc-700 rounded-xl overflow-hidden">
{/* Header */}
<div className="grid grid-cols-[1fr_120px_120px] bg-zinc-50 dark:bg-zinc-800/50 border-b border-zinc-200 dark:border-zinc-700">
<div className="px-4 py-2.5 text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">
Feature
</div>
<div className="px-4 py-2.5 text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wide border-l border-zinc-200 dark:border-zinc-700">
Manager
</div>
<div className="px-4 py-2.5 text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wide border-l border-zinc-200 dark:border-zinc-700">
Agent
</div>
</div>
{/* Rows */}
{FEATURES.map((feature, i) => (
<div
key={feature.label}
className={[
'grid grid-cols-[1fr_120px_120px]',
i < FEATURES.length - 1 ? 'border-b border-zinc-100 dark:border-zinc-800' : '',
i % 2 === 0 ? '' : 'bg-zinc-50/50 dark:bg-zinc-800/20',
].join(' ')}
>
<div className="px-4 py-2.5 text-xs text-zinc-600 dark:text-zinc-400">
{feature.label}
</div>
<div className="px-4 py-2.5 border-l border-zinc-100 dark:border-zinc-800">
<AccessCell access={feature.manager} note={feature.managerNote} />
</div>
<div className="px-4 py-2.5 border-l border-zinc-100 dark:border-zinc-800">
<AccessCell access={feature.agent} note={feature.agentNote} />
</div>
</div>
))}
</div>
</div>
)
}