import React from 'react'; import { YStack, XStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Pressable } from '@tamagui/react-native-web-lite'; import { useAdminTheme } from '../theme'; export function MobileCard({ children, className, ...rest }: React.ComponentProps) { const { surface, border, shadow } = useAdminTheme(); return ( {children} ); } export function PillBadge({ tone = 'muted', children, }: { tone?: 'success' | 'warning' | 'muted'; children: React.ReactNode; }) { const { theme } = useAdminTheme(); const palette: Record = { success: { bg: String(theme.backgroundStrong?.val ?? '#ecfdf3'), text: String(theme.green10?.val ?? '#047857'), border: String(theme.green6?.val ?? '#bbf7d0'), }, warning: { bg: String(theme.yellow3?.val ?? '#fffbeb'), text: String(theme.yellow11?.val ?? '#92400e'), border: String(theme.yellow6?.val ?? '#fef3c7'), }, muted: { bg: String(theme.gray3?.val ?? '#f3f4f6'), text: String(theme.gray11?.val ?? '#374151'), border: String(theme.gray6?.val ?? '#e5e7eb'), }, }; const colors = palette[tone] ?? palette.muted; return ( {children} ); } export function CTAButton({ label, onPress, tone = 'primary', fullWidth = true, disabled = false, loading = false, }: { label: string; onPress: () => void; tone?: 'primary' | 'ghost' | 'danger'; fullWidth?: boolean; disabled?: boolean; loading?: boolean; }) { const { primary, surface, border, text, danger } = useAdminTheme(); const isPrimary = tone === 'primary'; const isDanger = tone === 'danger'; const isDisabled = disabled || loading; const backgroundColor = isDanger ? danger : isPrimary ? primary : surface; const borderColor = isPrimary || isDanger ? 'transparent' : border; const labelColor = isPrimary || isDanger ? 'white' : text; return ( {label} ); } export function KpiTile({ icon: IconCmp, label, value, }: { icon: React.ComponentType<{ size?: number; color?: string }>; label: string; value: string | number; }) { const { accentSoft, primary, text } = useAdminTheme(); return ( {label} {value} ); } export function SkeletonCard({ height = 80 }: { height?: number }) { return ( ); } export function ActionTile({ icon: IconCmp, label, color, onPress, disabled = false, delayMs = 0, }: { icon: React.ComponentType<{ size?: number; color?: string }>; label: string; color: string; onPress?: () => void; disabled?: boolean; delayMs?: number; }) { const { textStrong } = useAdminTheme(); return ( {label} ); } export function FloatingActionButton({ onPress, label, icon: IconCmp, }: { onPress: () => void; label: string; icon: React.ComponentType<{ size?: number; color?: string }>; }) { const { primary, shadow } = useAdminTheme(); const [pressed, setPressed] = React.useState(false); return ( setPressed(true)} onPressOut={() => setPressed(false)} onPointerLeave={() => setPressed(false)} style={{ position: 'fixed', right: 18, bottom: 'calc(env(safe-area-inset-bottom, 0px) + 96px)', zIndex: 60, transform: pressed ? 'scale(0.96)' : 'scale(1)', opacity: pressed ? 0.92 : 1, transition: 'transform 140ms ease, opacity 140ms ease', }} aria-label={label} > {label} ); }