import { useGetMediaList } from "@/features/media/use-media"; import { createFileRoute } from "@tanstack/react-router"; import { Button } from "@/components/ui/button"; import { AuthenticatedImage } from "@/components/media/authenticated-image"; import type { Media } from "@/domain/types"; import { useMemo, useState } from "react"; import { MediaViewer } from "@/components/media/media-viewer"; import { groupMediaByDate } from "@/lib/date-utils"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; export const Route = createFileRoute("/media/")({ component: MediaPage, }); function MediaPage() { const [sortBy, setSortBy] = useState("created_at"); const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc"); const [mimeType, setMimeType] = useState(undefined); const [filters, setFilters] = useState([]); // Filter input state const [filterField, setFilterField] = useState('original_filename'); const [customFieldName, setCustomFieldName] = useState(''); const [filterOperator, setFilterOperator] = useState('like'); const [filterValue, setFilterValue] = useState(''); const { data, isLoading, error, fetchNextPage, hasNextPage, isFetchingNextPage, } = useGetMediaList(1, 20, sortBy, sortOrder, mimeType, filters); const [selectedMedia, setSelectedMedia] = useState(null); const allMedia = useMemo( () => data?.pages.flatMap((page) => page.data) ?? [], [data] ); const groupedMedia = useMemo(() => groupMediaByDate(allMedia), [allMedia]); const groupEntries = useMemo( () => Array.from(groupedMedia.entries()), [groupedMedia] ); const handleAddFilter = () => { const field = filterField === 'custom' ? customFieldName : filterField; if (field && filterValue) { const newFilter = `${field}:${filterOperator}:${filterValue}`; setFilters([...filters, newFilter]); setFilterValue(''); // Clear value after adding } }; const handleRemoveFilter = (index: number) => { const newFilters = [...filters]; newFilters.splice(index, 1); setFilters(newFilters); }; return (

All Photos

{sortBy === "custom" && ( { if (e.target.value) setSortBy(e.target.value); }} onKeyDown={(e) => { if (e.key === 'Enter') { setSortBy(e.currentTarget.value); } }} /> )}
{/* Advanced Filters */}
Add Filter: {filterField === 'custom' && ( setCustomFieldName(e.target.value)} /> )} setFilterValue(e.target.value)} placeholder="Value" className="border rounded px-2 py-1 text-sm w-[150px]" onKeyDown={(e) => e.key === 'Enter' && handleAddFilter()} />
{/* Active Filters List */} {filters.length > 0 && (
{filters.map((f, i) => (
{f.replace(/:/g, ' ')}
))}
)}
{isLoading &&

Loading photos...

} {error &&

Error loading photos: {error.message}

} {data && (
{groupEntries.map(([title, media]) => (

{title}

{media.map((media) => (
setSelectedMedia(media)} >
))}
))}
)} {hasNextPage && (
)} { if (!open) { setSelectedMedia(null); } }} />
); }