reusable tabs component

This commit is contained in:
Josh Hawkins 2025-10-31 08:13:54 -05:00
parent 5f4de57bc3
commit 348d40d7fd

View File

@ -119,12 +119,6 @@ export default function SearchDetailDialog({
100, 100,
); );
// tracking details state
const [trackingTimeIndex, setTrackingTimeIndex] = useState<
number | undefined
>(undefined);
// dialog and mobile page // dialog and mobile page
const [isOpen, setIsOpen] = useState(search != undefined); const [isOpen, setIsOpen] = useState(search != undefined);
@ -184,6 +178,42 @@ export default function SearchDetailDialog({
} }
}, [pageToggle, searchTabs, setSearchPage]); }, [pageToggle, searchTabs, setSearchPage]);
// Tabs component for reuse
const tabsComponent = (
<ScrollArea className="w-full whitespace-nowrap">
<div className="flex flex-row">
<ToggleGroup
className="*:rounded-md *:px-3 *:py-4"
type="single"
size="sm"
value={pageToggle}
onValueChange={(value: SearchTab) => {
if (value) {
setPageToggle(value);
}
}}
>
{Object.values(searchTabs).map((item) => (
<ToggleGroupItem
key={item}
className={`flex scroll-mx-10 items-center justify-between gap-2 ${page == "details" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
value={item}
data-nav-item={item}
aria-label={`Select ${item}`}
>
{item == "details" && <FaRegListAlt className="size-4" />}
{item == "snapshot" && <FaImage className="size-4" />}
{item == "video" && <FaVideo className="size-4" />}
{item == "tracking_details" && <PiPath className="size-4" />}
<div className="smart-capitalize">{t(`type.${item}`)}</div>
</ToggleGroupItem>
))}
</ToggleGroup>
<ScrollBar orientation="horizontal" className="h-0" />
</div>
</ScrollArea>
);
if (!search) { if (!search) {
return; return;
} }
@ -220,8 +250,15 @@ export default function SearchDetailDialog({
</Description> </Description>
</Header> </Header>
{isDesktop ? ( {isDesktop ? (
page === "tracking_details" ? (
<TrackingDetails
className="size-full"
event={search as unknown as Event}
tabs={tabsComponent}
/>
) : (
<div className="flex h-full gap-4 overflow-hidden"> <div className="flex h-full gap-4 overflow-hidden">
<div className="scrollbar-container flex-[3] overflow-y-auto"> <div className="scrollbar-container flex-[3] overflow-y-hidden">
{page === "snapshot" && search.has_snapshot && ( {page === "snapshot" && search.has_snapshot && (
<ObjectSnapshotTab <ObjectSnapshotTab
search={ search={
@ -240,15 +277,6 @@ export default function SearchDetailDialog({
{page === "video" && search.has_clip && ( {page === "video" && search.has_clip && (
<VideoTab search={search} /> <VideoTab search={search} />
)} )}
{page === "tracking_details" && (
<TrackingDetails
event={search as unknown as Event}
showImage={true}
showLifecycle={false}
timeIndex={trackingTimeIndex}
setTimeIndex={setTrackingTimeIndex}
/>
)}
{(page === "details" || {(page === "details" ||
(!search.has_snapshot && page === "snapshot") || (!search.has_snapshot && page === "snapshot") ||
(!search.has_clip && page === "video")) && ( (!search.has_clip && page === "video")) && (
@ -268,44 +296,7 @@ export default function SearchDetailDialog({
)} )}
</div> </div>
<div className="flex flex-[2] flex-col gap-4 overflow-hidden"> <div className="flex flex-[2] flex-col gap-4 overflow-hidden">
<ScrollArea className="w-full whitespace-nowrap"> {tabsComponent}
<div className="flex flex-row">
<ToggleGroup
className="*:rounded-md *:px-3 *:py-4"
type="single"
size="sm"
value={pageToggle}
onValueChange={(value: SearchTab) => {
if (value) {
setPageToggle(value);
}
}}
>
{Object.values(searchTabs).map((item) => (
<ToggleGroupItem
key={item}
className={`flex scroll-mx-10 items-center justify-between gap-2 ${page == "details" ? "last:mr-20" : ""} ${pageToggle == item ? "" : "*:text-muted-foreground"}`}
value={item}
data-nav-item={item}
aria-label={`Select ${item}`}
>
{item == "details" && (
<FaRegListAlt className="size-4" />
)}
{item == "snapshot" && <FaImage className="size-4" />}
{item == "video" && <FaVideo className="size-4" />}
{item == "tracking_details" && (
<PiPath className="size-4" />
)}
<div className="smart-capitalize">
{t(`type.${item}`)}
</div>
</ToggleGroupItem>
))}
</ToggleGroup>
<ScrollBar orientation="horizontal" className="h-0" />
</div>
</ScrollArea>
<div className="scrollbar-container flex-1 overflow-y-auto"> <div className="scrollbar-container flex-1 overflow-y-auto">
{page == "details" && ( {page == "details" && (
<ObjectDetailsTab <ObjectDetailsTab
@ -337,19 +328,10 @@ export default function SearchDetailDialog({
showThumbnail={false} showThumbnail={false}
/> />
)} )}
{page == "tracking_details" && (
<TrackingDetails
className="w-full overflow-x-hidden"
event={search as unknown as Event}
showImage={false}
showLifecycle={true}
timeIndex={trackingTimeIndex}
setTimeIndex={setTrackingTimeIndex}
/>
)}
</div> </div>
</div> </div>
</div> </div>
)
) : ( ) : (
<> <>
<ScrollArea <ScrollArea
@ -419,10 +401,6 @@ export default function SearchDetailDialog({
<TrackingDetails <TrackingDetails
className="w-full overflow-x-hidden" className="w-full overflow-x-hidden"
event={search as unknown as Event} event={search as unknown as Event}
showImage={true}
showLifecycle={true}
timeIndex={trackingTimeIndex}
setTimeIndex={setTrackingTimeIndex}
/> />
)} )}
</> </>