import { useEffect, useRef } from "react"; import { Animated, StyleSheet, View, Text, Pressable, Easing, useWindowDimensions } from "react-native"; import { router, useSegments } from "expo-router"; import { useAuth } from "../lib/auth"; import { theme } from "../lib/theme"; // Note: the /crush33 admin hub is intentionally NOT listed here — it's an // admin-only URL, not surfaced to gate staff in the app drawer. const ITEMS: { label: string; icon: string; route: string; seg: string }[] = [ { label: "Scanner", icon: "📷", route: "/", seg: "" }, { label: "Event report", icon: "📊", route: "/stats", seg: "stats" }, { label: "Banquet lookup", icon: "🍽️", route: "/admin", seg: "admin" }, ]; export default function SideMenu({ visible, onClose }: { visible: boolean; onClose: () => void }) { const { operator, signOut } = useAuth(); const segments = useSegments(); const current = segments[0] ?? ""; const { width } = useWindowDimensions(); const panelW = Math.min(320, width * 0.84); const tx = useRef(new Animated.Value(-panelW)).current; const fade = useRef(new Animated.Value(0)).current; useEffect(() => { Animated.parallel([ Animated.timing(tx, { toValue: visible ? 0 : -panelW, duration: 220, easing: Easing.out(Easing.cubic), useNativeDriver: true, }), Animated.timing(fade, { toValue: visible ? 1 : 0, duration: 220, useNativeDriver: true }), ]).start(); }, [visible, panelW, tx, fade]); const go = (item: { route: string; seg: string }) => { onClose(); if (item.seg !== current) router.replace(item.route as any); }; return ( 🐻 Camp Scan {!!operator && {operator}} {ITEMS.map((it) => { const active = it.seg === current; return ( go(it)}> {it.icon} {it.label} ); })} { onClose(); signOut(); }} > 🚪 Sign out ); } const styles = StyleSheet.create({ scrim: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "rgba(0,0,0,0.55)" }, panel: { position: "absolute", top: 0, bottom: 0, left: 0, backgroundColor: theme.card, borderRightWidth: 1, borderRightColor: theme.cardBorder, paddingTop: 54, paddingHorizontal: 14, paddingBottom: 28, }, header: { paddingHorizontal: 8, paddingBottom: 14, borderBottomWidth: 1, borderBottomColor: theme.cardBorder }, logo: { color: theme.text, fontSize: 20, fontWeight: "800" }, operator: { color: theme.textDim, fontSize: 14, marginTop: 3 }, items: { marginTop: 14, gap: 4 }, item: { flexDirection: "row", alignItems: "center", gap: 14, paddingVertical: 14, paddingHorizontal: 12, borderRadius: 12 }, itemActive: { backgroundColor: theme.primary }, itemIcon: { fontSize: 20, width: 26, textAlign: "center" }, itemText: { color: theme.text, fontSize: 17, fontWeight: "600" }, itemTextActive: { color: "#fff", fontWeight: "800" }, spacer: { flex: 1 }, signout: { flexDirection: "row", alignItems: "center", gap: 14, paddingVertical: 14, paddingHorizontal: 12, borderRadius: 12, borderTopWidth: 1, borderTopColor: theme.cardBorder, }, signoutText: { color: theme.dangerBright, fontSize: 17, fontWeight: "700" }, });