Adds frontend for cms page
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MoreHorizontal } from 'lucide-react';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import type { CmsInstance, CmsInstanceStatus } from '@/api/types';
|
||||
|
||||
function statusBadgeVariant(status: CmsInstanceStatus) {
|
||||
if (status === 'Available') return 'secondary';
|
||||
if (status === 'NotAvailable') return 'destructive';
|
||||
return 'outline';
|
||||
}
|
||||
|
||||
function formatDate(iso: string | null): string {
|
||||
if (!iso) return '—';
|
||||
return new Date(iso).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' });
|
||||
}
|
||||
|
||||
interface CmsInstanceListProps {
|
||||
instances: CmsInstance[];
|
||||
onSetStatus: (instance: CmsInstance) => void;
|
||||
}
|
||||
|
||||
export function CmsInstanceList({ instances, onSetStatus }: CmsInstanceListProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>{t('cms.table.name')}</TableHead>
|
||||
<TableHead>{t('cms.table.url')}</TableHead>
|
||||
<TableHead>{t('cms.table.status')}</TableHead>
|
||||
<TableHead>{t('cms.table.lastContact')}</TableHead>
|
||||
<TableHead>{t('cms.table.disableMessage')}</TableHead>
|
||||
<TableHead>{t('cms.table.actions')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{instances.map((instance) => (
|
||||
<TableRow
|
||||
key={instance.id}
|
||||
data-testid="cms-instance-row"
|
||||
className={instance.status === 'Inactive' ? 'opacity-50' : ''}
|
||||
>
|
||||
<TableCell>{instance.name}</TableCell>
|
||||
<TableCell>{instance.url}</TableCell>
|
||||
<TableCell>
|
||||
<Badge
|
||||
variant={statusBadgeVariant(instance.status)}
|
||||
data-testid="cms-instance-status-badge"
|
||||
>
|
||||
{t(`cms.status.${instance.status}`)}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>{formatDate(instance.lastContactedAt)}</TableCell>
|
||||
<TableCell>{instance.disableMessage ?? '—'}</TableCell>
|
||||
<TableCell>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
data-testid="cms-instance-actions-trigger"
|
||||
>
|
||||
<MoreHorizontal className="size-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem
|
||||
data-testid="cms-instance-set-status"
|
||||
onClick={() => onSetStatus(instance)}
|
||||
>
|
||||
{t('cms.actions.setStatus')}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user