learning_ai_invt_trdg/mobile/components/ProductAvailabilityGate.tsx

98 lines
2.5 KiB
TypeScript

import { useEffect, useState } from 'react';
import type { ReactNode } from 'react';
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native';
import { mobileKillSwitchClient } from '@/lib/runtime';
import { Colors, Fonts, Spacing } from '@/constants/theme';
type AvailabilityStatus = 'loading' | 'available' | 'maintenance' | 'product_disabled';
export function ProductAvailabilityGate({ children }: { children: ReactNode }) {
const [status, setStatus] = useState<AvailabilityStatus>('loading');
const [message, setMessage] = useState<string | undefined>();
useEffect(() => {
let active = true;
async function loadAvailability() {
try {
const result = await mobileKillSwitchClient.check();
if (!active) {
return;
}
if (result.disabled) {
setStatus('product_disabled');
setMessage(result.message ?? 'Trading access is temporarily disabled.');
return;
}
setStatus('available');
} catch (error) {
console.warn('[ProductAvailabilityGate] Failed to evaluate kill switch.', error);
if (active) {
setStatus('available');
}
}
}
void loadAvailability();
return () => {
active = false;
};
}, []);
if (status === 'loading') {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color={Colors.accent.green} />
<Text style={styles.title}>Loading trading workspace...</Text>
</View>
);
}
if (status !== 'available') {
return (
<View style={styles.centered}>
<Text style={styles.eyebrow}>CONTROL PLANE</Text>
<Text style={styles.title}>
{status === 'maintenance' ? 'Trading under maintenance' : 'Trading temporarily unavailable'}
</Text>
{message ? <Text style={styles.body}>{message}</Text> : null}
</View>
);
}
return <>{children}</>;
}
const styles = StyleSheet.create({
centered: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: Colors.background.primary,
padding: Spacing.screenPadding,
gap: 12,
},
eyebrow: {
fontFamily: Fonts.inter.black,
fontSize: 11,
letterSpacing: 2.5,
color: Colors.accent.green,
},
title: {
fontFamily: Fonts.inter.black,
fontSize: 24,
color: Colors.text.primary,
textAlign: 'center',
},
body: {
fontFamily: Fonts.inter.medium,
fontSize: 14,
lineHeight: 22,
color: Colors.text.secondary,
textAlign: 'center',
maxWidth: 320,
},
});