68 lines · 2.6 KB
import { createFileRoute, Link } from "@tanstack/react-router";
import { requireSignedIn } from "~/lib/route-guards";
import { z } from "zod";
import { listNotifications, markNotifications } from "~/fns/account";
import { useAction } from "~/hooks/use-action";
import { Button, buttonClass } from "~/ui/Button";
import { Badge } from "~/ui/Badge";
import { EmptyState } from "~/ui/EmptyState";
import { PageContainer } from "~/ui/PageContainer";
import { Panel } from "~/ui/Panel";
import { RelativeTime } from "~/ui/RelativeTime";
import { cn } from "~/utils/cn";
import { Heading } from "~/ui/Heading";

export const Route = createFileRoute("/notifications")({
  validateSearch: z.object({ all: z.boolean().optional() }),
  beforeLoad: ({ context, location }) => {
    requireSignedIn({ context, location });
  },
  loaderDeps: ({ search }) => ({ all: search.all ?? false }),
  loader: ({ deps }) => listNotifications({ data: { all: deps.all } }),
  component: NotificationsPage,
});

function NotificationsPage() {
  const notifications = Route.useLoaderData();
  const { all } = Route.useSearch();
  const mark = useAction(markNotifications);
  return (
    <PageContainer className="max-w-4xl space-y-4">
      <div className="flex items-center justify-between">
        <Heading size="xl">Notifications</Heading>
        <div className="flex gap-2">
          <Link to="/notifications" search={{ all: !all }} className={buttonClass("ghost", "sm")}>
            {all ? "Unread only" : "Show all"}
          </Link>
          <Button size="sm" onClick={() => mark.run({ data: { ids: null } })} pending={mark.pending}>
            Mark all read
          </Button>
        </div>