import { useQuery } from "@tanstack/react-query"; import { Bell, Plus, RotateCcw } from "lucide-react"; import { useState } from "react"; import { useNavigate } from "react-router"; import { EmptyState } from "~/client/components/empty-state"; import { StatusDot } from "~/client/components/status-dot"; import { Button } from "~/client/components/ui/button"; import { Card } from "~/client/components/ui/card"; import { Input } from "~/client/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/client/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/client/components/ui/table"; import type { Route } from "./+types/notifications"; import { listNotificationDestinations } from "~/client/api-client"; import { listNotificationDestinationsOptions } from "~/client/api-client/@tanstack/react-query.gen"; export const handle = { breadcrumb: () => [{ label: "Notifications" }], }; export function meta(_: Route.MetaArgs) { return [ { title: "Zerobyte - Notifications" }, { name: "description", content: "Manage notification destinations for backup alerts.", }, ]; } export const clientLoader = async () => { const result = await listNotificationDestinations(); if (result.data) return result.data; return []; }; export default function Notifications({ loaderData }: Route.ComponentProps) { const [searchQuery, setSearchQuery] = useState(""); const [typeFilter, setTypeFilter] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const clearFilters = () => { setSearchQuery(""); setTypeFilter(""); setStatusFilter(""); }; const navigate = useNavigate(); const { data } = useQuery({ ...listNotificationDestinationsOptions(), initialData: loaderData, refetchInterval: 10000, refetchOnWindowFocus: true, }); const filteredNotifications = data?.filter((notification) => { const matchesSearch = notification.name.toLowerCase().includes(searchQuery.toLowerCase()); const matchesType = !typeFilter || notification.type === typeFilter; const matchesStatus = !statusFilter || (statusFilter === "enabled" ? notification.enabled : !notification.enabled); return matchesSearch && matchesType && matchesStatus; }) || []; const hasNoNotifications = data.length === 0; const hasNoFilteredNotifications = filteredNotifications.length === 0 && !hasNoNotifications; if (hasNoNotifications) { return ( navigate("/notifications/create")}> Create Destination } /> ); } return (
setSearchQuery(e.target.value)} /> {(searchQuery || typeFilter || statusFilter) && ( )}
Name Type Status {hasNoFilteredNotifications ? (

No destinations match your filters.

) : ( filteredNotifications.map((notification) => ( navigate(`/notifications/${notification.id}`)} > {notification.name} {notification.type} )) )}
{filteredNotifications.length} destination {filteredNotifications.length !== 1 ? "s" : ""}
); }