import { NavLink, Outlet, useParams } from 'react-router-dom'; import { Database, Copy, Upload } from 'lucide-react'; import { IconTile } from '@/components/ui/icon-tile'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { cn } from '@/lib/utils'; import { useBuckets } from '@/hooks/useApi'; import { toast } from 'sonner'; interface TabSpec { to: string; label: string; end?: boolean; } const tabs: TabSpec[] = [ { to: 'objects', label: 'Objects' }, { to: 'permissions', label: 'Permissions' }, { to: 'website', label: 'Website' }, { to: 'settings', label: 'Settings' }, ]; function formatBytes(n?: number) { if (n == null) return ''; if (n < 1024) return `${n} B`; const units = ['KB', 'MB', 'GB', 'TB']; let v = n / 1024; for (const u of units) { if (v < 1024) return `${v.toFixed(v >= 10 ? 0 : 1)} ${u}`; v /= 1024; } return `${v.toFixed(0)} PB`; } export function BucketDetailShell() { const { bucketName = '' } = useParams<{ bucketName: string }>(); const { data: buckets = [] } = useBuckets(); const bucket = buckets.find((b) => b.name === bucketName); const s3Url = `s3://${bucketName}`; const copyUrl = async () => { try { await navigator.clipboard.writeText(s3Url); toast.success('URL copied'); } catch { toast.error('Failed to copy'); } }; return (
{/* Hero */}
} tone="primary" size="lg" />

{bucketName}

{s3Url}

Active {bucket?.objectCount != null && {bucket.objectCount.toLocaleString()} objects} {bucket?.size != null && {formatBytes(bucket.size)}}
{/* Tabs */}
); }