redesign the homepage
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
import { localizedPath, type Locale, type RouteId } from '@/lib/localization/config';
|
||||
|
||||
export type DestinationStatus = 'active' | 'disabled' | 'placeholder' | 'blocked';
|
||||
export type DestinationKind =
|
||||
| 'internal-route'
|
||||
| 'external-url'
|
||||
| 'modal'
|
||||
| 'drawer'
|
||||
| 'form'
|
||||
| 'scheduler';
|
||||
|
||||
export type DestinationKey =
|
||||
| 'book-demo'
|
||||
| 'contact-sales'
|
||||
| 'product-tour'
|
||||
| 'pricing'
|
||||
| 'sign-in'
|
||||
| 'forgot-password'
|
||||
| 'privacy'
|
||||
| 'terms'
|
||||
| 'accessibility'
|
||||
| 'cookie-settings'
|
||||
| 'support';
|
||||
|
||||
export interface DestinationReference {
|
||||
key: DestinationKey;
|
||||
kind: DestinationKind;
|
||||
status: DestinationStatus;
|
||||
routeId?: RouteId;
|
||||
href?: string;
|
||||
featureFlag?: string;
|
||||
issueId?: string;
|
||||
external?: boolean;
|
||||
allowedLocales: readonly Locale[];
|
||||
reason: string;
|
||||
}
|
||||
|
||||
const allLocales = ['en', 'fr', 'ar'] as const satisfies readonly Locale[];
|
||||
|
||||
const baseDestinations: Record<DestinationKey, DestinationReference> = {
|
||||
'book-demo': {
|
||||
key: 'book-demo',
|
||||
kind: 'modal',
|
||||
status: 'blocked',
|
||||
featureFlag: 'demoSubmissionEnabled',
|
||||
issueId: 'P9-002/P9-003',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'Production CRM and legal consent decisions are not approved.',
|
||||
},
|
||||
'contact-sales': {
|
||||
key: 'contact-sales',
|
||||
kind: 'external-url',
|
||||
status: 'blocked',
|
||||
issueId: 'P9-015',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'No approved sales destination exists.',
|
||||
},
|
||||
'product-tour': {
|
||||
key: 'product-tour',
|
||||
kind: 'modal',
|
||||
status: 'blocked',
|
||||
issueId: 'P9-012',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'No approved product-tour medium or transcript exists.',
|
||||
},
|
||||
pricing: {
|
||||
key: 'pricing',
|
||||
kind: 'internal-route',
|
||||
status: 'placeholder',
|
||||
issueId: 'P9-008',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'Public pricing and packaging are not approved.',
|
||||
},
|
||||
'sign-in': {
|
||||
key: 'sign-in',
|
||||
kind: 'internal-route',
|
||||
status: 'active',
|
||||
routeId: 'sign-in',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'Sign-in is now served from the homepage app.',
|
||||
},
|
||||
'forgot-password': {
|
||||
key: 'forgot-password',
|
||||
kind: 'internal-route',
|
||||
status: 'active',
|
||||
routeId: 'forgot-password',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'Password reset flow is now served from the homepage app.',
|
||||
},
|
||||
privacy: {
|
||||
key: 'privacy',
|
||||
kind: 'internal-route',
|
||||
status: 'placeholder',
|
||||
routeId: 'privacy',
|
||||
issueId: 'P9-003',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'The privacy destination resolves to a gated placeholder pending legal copy.',
|
||||
},
|
||||
terms: {
|
||||
key: 'terms',
|
||||
kind: 'internal-route',
|
||||
status: 'placeholder',
|
||||
routeId: 'terms',
|
||||
issueId: 'P9-003',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'The terms destination resolves to a gated placeholder pending legal copy.',
|
||||
},
|
||||
accessibility: {
|
||||
key: 'accessibility',
|
||||
kind: 'internal-route',
|
||||
status: 'placeholder',
|
||||
routeId: 'accessibility',
|
||||
issueId: 'P13-002',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'The accessibility destination resolves to a gated placeholder pending approval.',
|
||||
},
|
||||
'cookie-settings': {
|
||||
key: 'cookie-settings',
|
||||
kind: 'modal',
|
||||
status: 'blocked',
|
||||
issueId: 'P9-004',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'Consent categories and a consent-management mechanism are not approved.',
|
||||
},
|
||||
support: {
|
||||
key: 'support',
|
||||
kind: 'external-url',
|
||||
status: 'blocked',
|
||||
issueId: 'P9-015',
|
||||
allowedLocales: allLocales,
|
||||
reason: 'No approved public support destination exists.',
|
||||
},
|
||||
};
|
||||
|
||||
export interface DestinationRuntimeContext {
|
||||
demoSubmissionEnabled: boolean;
|
||||
demoMode: 'blocked' | 'local';
|
||||
}
|
||||
|
||||
export function destinationRegistry(
|
||||
context: DestinationRuntimeContext,
|
||||
): Record<DestinationKey, DestinationReference> {
|
||||
const demo = baseDestinations['book-demo'];
|
||||
return {
|
||||
...baseDestinations,
|
||||
'book-demo': {
|
||||
...demo,
|
||||
status: context.demoSubmissionEnabled && context.demoMode === 'local' ? 'active' : 'blocked',
|
||||
reason:
|
||||
context.demoSubmissionEnabled && context.demoMode === 'local'
|
||||
? 'Local validation adapter is active; no external lead is created.'
|
||||
: demo.reason,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveDestination(
|
||||
key: DestinationKey,
|
||||
locale: Locale,
|
||||
context: DestinationRuntimeContext,
|
||||
): DestinationReference {
|
||||
const destination = destinationRegistry(context)[key];
|
||||
if (!destination.allowedLocales.includes(locale)) {
|
||||
return {
|
||||
...destination,
|
||||
status: 'blocked',
|
||||
reason: 'Destination is unavailable for this locale.',
|
||||
};
|
||||
}
|
||||
if (destination.routeId) {
|
||||
return { ...destination, href: localizedPath(destination.routeId, locale) };
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
Reference in New Issue
Block a user