Highly ambitious ATProtocol AppView service and sdks
at fix-postgres 115 lines 3.0 kB view raw
1import { Link, useNavigate } from "react-router-dom"; 2import { ChevronDown } from "lucide-react"; 3 4interface SliceSubNavProps { 5 handle: string; 6 rkey: string; 7 sliceName?: string; 8 activeTab: 9 | "overview" 10 | "records" 11 | "jetstream" 12 | "sync" 13 | "oauth" 14 | "settings"; 15 isOwner?: boolean; 16} 17 18export function SliceSubNav( 19 { handle, rkey, sliceName, activeTab, isOwner = false }: SliceSubNavProps, 20) { 21 const navigate = useNavigate(); 22 23 const allTabs = [ 24 { 25 value: "overview", 26 label: "Overview", 27 path: `/profile/${handle}/slice/${rkey}`, 28 ownerOnly: false, 29 }, 30 { 31 value: "records", 32 label: "Records", 33 path: `/profile/${handle}/slice/${rkey}/records`, 34 ownerOnly: false, 35 }, 36 { 37 value: "jetstream", 38 label: "Jetstream", 39 path: `/profile/${handle}/slice/${rkey}/jetstream`, 40 ownerOnly: false, 41 }, 42 { 43 value: "sync", 44 label: "Sync", 45 path: `/profile/${handle}/slice/${rkey}/sync`, 46 ownerOnly: true, 47 }, 48 { 49 value: "oauth", 50 label: "OAuth", 51 path: `/profile/${handle}/slice/${rkey}/oauth`, 52 ownerOnly: true, 53 }, 54 { 55 value: "settings", 56 label: "Settings", 57 path: `/profile/${handle}/slice/${rkey}/settings`, 58 ownerOnly: true, 59 }, 60 ]; 61 62 // Filter tabs based on ownership 63 const tabs = allTabs.filter(tab => !tab.ownerOnly || isOwner); 64 65 const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => { 66 const selectedTab = tabs.find((tab) => tab.value === e.target.value); 67 if (selectedTab) { 68 navigate(selectedTab.path); 69 } 70 }; 71 72 return ( 73 <div className="flex items-center justify-between h-10"> 74 <div className="flex items-center gap-2 text-sm text-zinc-500"> 75 <Link to="/" className="hover:text-zinc-400 transition-colors"> 76 Slices 77 </Link> 78 <span>/</span> 79 <Link 80 to={`/profile/${handle}`} 81 className="hover:text-zinc-400 transition-colors max-w-[130px] truncate" 82 > 83 @{handle} 84 </Link> 85 {sliceName && ( 86 <> 87 <span>/</span> 88 <span className="max-w-[200px] truncate">{sliceName}</span> 89 </> 90 )} 91 </div> 92 <div className="relative inline-block ml-auto"> 93 <ChevronDown 94 size={16} 95 className="absolute left-2 top-1/2 -translate-y-1/2 text-zinc-500 pointer-events-none" 96 /> 97 <select 98 value={activeTab} 99 onChange={handleChange} 100 className="appearance-none bg-transparent text-sm text-white pl-7 pr-3 py-2 cursor-pointer focus:outline-none hover:text-zinc-300 transition-colors text-right" 101 > 102 {tabs.map((tab) => ( 103 <option 104 key={tab.value} 105 value={tab.value} 106 className="bg-zinc-900 text-zinc-300" 107 > 108 {tab.label} 109 </option> 110 ))} 111 </select> 112 </div> 113 </div> 114 ); 115}