import { ReactNode, useState } from "react"; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ViewStyle, TextStyle, } from "react-native"; import { LucideIcon } from "../../icons"; import { gameUIColors } from "../gameUI"; import { ModalHeader } from "./ModalHeader"; import { CopyButton } from "./CopyButton"; interface DetailViewProps { children: ReactNode; style?: ViewStyle; } export function DetailView({ children, style }: DetailViewProps) { return {children}; } interface HeaderProps { title: string; subtitle?: string; onClose?: () => void; onBack?: () => void; actions?: ReactNode; } DetailView.Header = function Header({ title, subtitle, onClose, onBack, actions, }: HeaderProps) { return ( {actions && {actions}} ); }; interface SectionProps { title: string; icon?: LucideIcon; children: ReactNode; defaultOpen?: boolean; collapsible?: boolean; style?: ViewStyle; badge?: string | number; } DetailView.Section = function Section({ title, icon: Icon, children, defaultOpen = true, collapsible = true, style, badge, }: SectionProps) { const [isOpen, setIsOpen] = useState(defaultOpen); if (!collapsible) { return ( {Icon && } {title} {badge !== undefined && ( {badge} )} {children} ); } return ( setIsOpen(!isOpen)} > {Icon && } {title} {badge !== undefined && ( {badge} )} {isOpen && {children}} ); }; interface RowProps { label: string; value?: string | number | ReactNode; copyable?: boolean; style?: ViewStyle; labelStyle?: TextStyle; valueStyle?: TextStyle; } DetailView.Row = function Row({ label, value, copyable = false, style, labelStyle, valueStyle, }: RowProps) { const stringValue = typeof value === "string" || typeof value === "number" ? String(value) : null; return ( {label} {typeof value === "string" || typeof value === "number" ? ( {value} ) : ( value )} {copyable && stringValue && ( )} ); }; interface DataSectionProps { title: string; data: unknown; icon?: LucideIcon; defaultOpen?: boolean; style?: ViewStyle; } DetailView.DataSection = function DataSection({ title, data, icon, defaultOpen = false, style, }: DataSectionProps) { return ( {JSON.stringify(data, null, 2)} ); }; interface StatusBarProps { status: "success" | "error" | "warning" | "pending" | "info"; message?: string; style?: ViewStyle; } DetailView.StatusBar = function StatusBar({ status, message, style, }: StatusBarProps) { const statusColors = { success: gameUIColors.success, error: gameUIColors.error, warning: gameUIColors.warning, pending: gameUIColors.warning, info: gameUIColors.primary, }; const color = statusColors[status]; return ( {message && ( {message} )} ); }; interface TimelineProps { items: { label: string; value: string; status?: "success" | "error" | "pending"; }[]; style?: ViewStyle; } DetailView.Timeline = function Timeline({ items, style }: TimelineProps) { return ( {items.map((item, index) => ( {index < items.length - 1 && } {item.label} {item.value} ))} ); }; interface ContentProps { children: ReactNode; scrollable?: boolean; style?: ViewStyle; } DetailView.Content = function Content({ children, scrollable = true, style, }: ContentProps) { if (scrollable) { return {children}; } return {children}; }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: gameUIColors.background, }, content: { flex: 1, padding: 16, }, section: { marginBottom: 16, backgroundColor: gameUIColors.panel, borderRadius: 8, overflow: "hidden", }, sectionHeader: { flexDirection: "row", alignItems: "center", padding: 12, gap: 8, }, sectionHeaderTouchable: {}, sectionTitle: { flex: 1, fontSize: 14, fontWeight: "600", color: gameUIColors.text, }, sectionBadge: { backgroundColor: gameUIColors.primary + "20", paddingHorizontal: 8, paddingVertical: 2, borderRadius: 4, }, sectionBadgeText: { fontSize: 11, fontWeight: "600", color: gameUIColors.primary, }, sectionContent: { padding: 12, paddingTop: 0, }, row: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: gameUIColors.border + "20", }, rowLabel: { flex: 1, fontSize: 13, color: gameUIColors.secondary, }, rowValueContainer: { flexDirection: "row", alignItems: "center", flex: 2, gap: 8, }, rowValue: { flex: 1, fontSize: 13, color: gameUIColors.text, textAlign: "right", }, dataContainer: { backgroundColor: gameUIColors.background, borderRadius: 6, padding: 12, }, dataText: { fontSize: 12, fontFamily: "monospace", color: gameUIColors.text, }, statusBar: { flexDirection: "row", alignItems: "center", padding: 12, borderWidth: 1, borderRadius: 8, gap: 8, marginVertical: 8, }, statusDot: { width: 8, height: 8, borderRadius: 4, }, statusMessage: { fontSize: 13, fontWeight: "500", }, timeline: { paddingVertical: 8, }, timelineItem: { flexDirection: "row", position: "relative", }, timelineDot: { width: 8, height: 8, borderRadius: 4, backgroundColor: gameUIColors.primary, marginTop: 4, marginRight: 12, }, timelineLine: { position: "absolute", left: 3.5, top: 12, bottom: -4, width: 1, backgroundColor: gameUIColors.border + "40", }, timelineContent: { flex: 1, marginBottom: 12, }, timelineLabel: { fontSize: 12, color: gameUIColors.secondary, marginBottom: 2, }, timelineValue: { fontSize: 13, color: gameUIColors.text, }, });