'use client'; import { useEffect, useState } from 'react'; import { useRouter, useParams } from 'next/navigation'; import type { FirmConfig } from '@/types'; /** * Read-only view of one firm's account types and banned symbols. * * Both are owned by the master dashboard now. This page renders from the local * catalog cache rather than linking straight out to the master, because the * moment you most want to know what an account type says is the moment the * master is unreachable. */ function fmtSize(n: number) { return n >= 1000 ? `${n / 1000}k` : String(n); } function fmtMoney(n: number) { return `$${n.toLocaleString(undefined, { maximumFractionDigits: 2 })}`; } export default function FirmSettingsPage() { const router = useRouter(); const params = useParams(); const id = params.id as string; const [firm, setFirm] = useState(null); const [masterUrl, setMasterUrl] = useState(null); const [loadError, setLoadError] = useState(''); useEffect(() => { fetch(`/api/firms/${id}`) .then((r) => { if (!r.ok) throw new Error('Not found'); return r.json() as Promise; }) .then(setFirm) .catch(() => setLoadError('Failed to load firm')); fetch('/api/firm-catalog') .then((r) => r.json()) .then((meta: { masterUrl?: string | null }) => setMasterUrl(meta.masterUrl ?? null)) .catch(() => {}); }, [id]); if (loadError) { return (

{loadError}

); } const firmsPageUrl = masterUrl ? new URL('/firms', masterUrl).toString() : null; return (

{firm?.firm ?? '…'}

/ Account Types
Account types and banned symbols are managed on the master dashboard and pulled from it — this is a read-only copy of the last successful sync. {firmsPageUrl && ( <> {' '} Edit on master → )}
{['Label', 'Prefix', 'Account Size', 'Profit Target', 'Consistency', 'Min Day P&L', 'Min Trading Days', 'Max Contracts', 'After First W/D'].map((h) => ( ))} {firm && firm.accounts.length === 0 && ( )} {firm?.accounts.map((acc) => ( ))}
{h}
No account types — add them on the master dashboard
{acc.label} {acc.prefix} {fmtSize(acc.accountSize)} {fmtMoney(acc.profitTarget)} {Math.round(acc.consistency * 100)}% {acc.minDayPnL <= -999 ? '—' : fmtMoney(acc.minDayPnL)} {acc.minTradingDays} {acc.maxPositionSize === 0 ? 'No limit' : acc.maxPositionSize} {acc.targetSameEquity ? 'Same equity' : acc.withdrawalStages.length === 0 ? 'Base values' : `${acc.withdrawalStages.length} stage${acc.withdrawalStages.length === 1 ? '' : 's'}`}

Banned Symbols

{!firm || firm.bannedSymbols.length === 0 ? ( None ) : (
{firm.bannedSymbols.map((sym) => ( {sym} ))}
)}
); }