learning_ai_invt_trdg/web/src/components/ProductAccessibilityGate.tsx

97 lines
2.4 KiB
TypeScript

import { useEffect, useState } from 'react';
import type { ReactNode } from 'react';
import { tradingKillSwitchClient } from '../lib/runtime';
interface AccessibilityState {
status: 'loading' | 'available' | 'maintenance' | 'product_disabled';
message?: string;
}
const initialState: AccessibilityState = {
status: 'loading',
};
export function ProductAccessibilityGate({ children }: { children: ReactNode }) {
const [state, setState] = useState<AccessibilityState>(initialState);
useEffect(() => {
let active = true;
async function loadAvailability() {
try {
const result = await tradingKillSwitchClient.check();
if (!active) {
return;
}
if (result.disabled) {
setState({
status: 'product_disabled',
message: result.message ?? 'Trading access is temporarily disabled.',
});
return;
}
setState({ status: 'available' });
} catch (error) {
console.warn('[ProductAccessibilityGate] Failed to evaluate kill switch.', error);
if (active) {
setState({ status: 'available' });
}
}
}
void loadAvailability();
return () => {
active = false;
};
}, []);
if (state.status === 'loading') {
return <CenteredMessage title="Loading trading workspace..." />;
}
if (state.status !== 'available') {
return (
<CenteredMessage
title={state.status === 'maintenance' ? 'Trading under maintenance' : 'Trading temporarily unavailable'}
body={state.message}
/>
);
}
return <>{children}</>;
}
function CenteredMessage({ title, body }: { title: string; body?: string }) {
return (
<div
style={{
minHeight: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: '#0a0b0d',
color: '#f5f5f5',
padding: '2rem',
}}
>
<div
style={{
maxWidth: '32rem',
border: '1px solid rgba(255,255,255,0.08)',
borderRadius: '1rem',
padding: '2rem',
background: 'rgba(18, 20, 24, 0.92)',
boxShadow: '0 20px 60px rgba(0,0,0,0.35)',
}}
>
<h1 style={{ margin: 0, fontSize: '1.5rem', marginBottom: '0.75rem' }}>{title}</h1>
{body ? (
<p style={{ margin: 0, color: 'rgba(255,255,255,0.72)', lineHeight: 1.6 }}>{body}</p>
) : null}
</div>
</div>
);
}