Some checks failed
API CI / API Lint (push) Successful in 53s
API CI / API Type Check (push) Failing after 51s
API CI / API Test (push) Successful in 1m32s
API CI / API Build (push) Failing after 1m0s
API CI / Build Docker Image (push) Has been skipped
CD Pipeline / Deploy to Staging (push) Failing after 32s
CI Pipeline / Lint and Type Check (push) Failing after 33s
CI Pipeline / Build (push) Has been skipped
CI Pipeline / Test Backend (push) Failing after 2m1s
CI Pipeline / Test Frontend (push) Failing after 35s
CI Pipeline / Security Scan (push) Failing after 1m12s
Deploy to Staging / Deploy to Staging (push) Failing after 28s
Portal CI / Portal Lint (push) Failing after 19s
Portal CI / Portal Type Check (push) Failing after 18s
Portal CI / Portal Test (push) Failing after 19s
Portal CI / Portal Build (push) Failing after 18s
Test Suite / frontend-tests (push) Failing after 30s
Test Suite / api-tests (push) Failing after 44s
Test Suite / blockchain-tests (push) Failing after 27s
Type Check / type-check (map[directory:. name:root]) (push) Failing after 18s
Type Check / type-check (map[directory:api name:api]) (push) Failing after 19s
Type Check / type-check (map[directory:portal name:portal]) (push) Failing after 18s
CD Pipeline / Deploy to Production (push) Has been skipped
Add sankofa.nexus marketing site with institutional grade scorecards, server-side metadata/title, dynamic icons, favicon rewrite, and instant landing render without session-loading flash; split authenticated AppShell from unauthenticated corporate chrome. Co-authored-by: Cursor <cursoragent@cursor.com>
82 lines
2.7 KiB
TypeScript
82 lines
2.7 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/Card';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface PreviewAction {
|
|
href: string;
|
|
label: string;
|
|
}
|
|
|
|
interface FeaturePreviewPageProps {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
status?: 'preview' | 'request-only' | 'active';
|
|
bullets: readonly string[];
|
|
primaryAction?: PreviewAction;
|
|
secondaryAction?: PreviewAction;
|
|
}
|
|
|
|
export function FeaturePreviewPage({
|
|
eyebrow,
|
|
title,
|
|
description,
|
|
status = 'preview',
|
|
bullets,
|
|
primaryAction,
|
|
secondaryAction,
|
|
}: FeaturePreviewPageProps) {
|
|
const primaryActionClassName =
|
|
'inline-flex h-10 items-center justify-center rounded-md bg-gray-700 px-4 text-base font-medium text-white transition-colors hover:bg-gray-600';
|
|
const secondaryActionClassName =
|
|
'inline-flex h-10 items-center justify-center rounded-md border border-gray-600 bg-transparent px-4 text-base font-medium text-white transition-colors hover:bg-gray-800';
|
|
|
|
return (
|
|
<div className="mx-auto max-w-4xl px-4 py-10">
|
|
<div className="mb-8">
|
|
<p className="mb-2 text-sm font-medium uppercase tracking-wide text-orange-400">{eyebrow}</p>
|
|
<div className="mb-3 flex items-center gap-3">
|
|
<h1 className="text-3xl font-bold text-white">{title}</h1>
|
|
<Badge variant={status === 'active' ? 'default' : 'secondary'}>
|
|
{status === 'request-only' ? 'Request Only' : status === 'active' ? 'Active' : 'Preview'}
|
|
</Badge>
|
|
</div>
|
|
<p className="max-w-3xl text-gray-400">{description}</p>
|
|
</div>
|
|
|
|
<Card className="border-gray-800 bg-gray-900/70">
|
|
<CardHeader>
|
|
<CardTitle className="text-white">Current Scope</CardTitle>
|
|
<CardDescription>
|
|
This route is now real and intentionally describes the supported boundary for this workspace area.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<ul className="space-y-2 text-sm text-gray-300">
|
|
{bullets.map((bullet) => (
|
|
<li key={bullet}>• {bullet}</li>
|
|
))}
|
|
</ul>
|
|
|
|
<div className="flex flex-col gap-3 pt-2 sm:flex-row">
|
|
{primaryAction ? (
|
|
<Link href={primaryAction.href} className={cn(primaryActionClassName)}>
|
|
{primaryAction.label}
|
|
</Link>
|
|
) : null}
|
|
{secondaryAction ? (
|
|
<Link href={secondaryAction.href} className={cn(secondaryActionClassName)}>
|
|
{secondaryAction.label}
|
|
</Link>
|
|
) : null}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|