"use client"; import Link from "next/link"; import { useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { UserPlusIcon } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Command, CommandEmpty, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { scheduleContactPingAction } from "@/server/actions"; import { useViewerZone } from "@/components/viewer-zone"; import { civilDay } from "@/lib/time"; import { DateField } from "@/components/ui/date-field"; export type PingCandidate = { id: string; name: string; detail: string }; /** * Put someone on the chase list. * * This used to be a date box on the contact record, which is the wrong place * twice over: you were reading about a person, not planning your week, and * scheduling anything meant remembering who to open first. Here the question * is the other way round — who am I chasing, and when — which is the question * this page exists to answer. */ export function PingScheduler({ contacts }: { contacts: PingCandidate[] }) { const router = useRouter(); const [open, setOpen] = useState(false); const [person, setPerson] = useState(null); const zone = useViewerZone(); // A week out on the reader's calendar. `toISOString` would have offered them // UTC's day, which is the wrong one on one side of Greenwich or the other. const [date, setDate] = useState(() => civilDay(new Date(Date.now() + 7 * 86_400_000), zone), ); const [pending, startTransition] = useTransition(); const schedule = () => { if (!person) return; startTransition(async () => { try { await scheduleContactPingAction(person.id, date); toast.success(`${person.name} is on the list`); setPerson(null); router.refresh(); } catch (error) { toast.error(error instanceof Error ? error.message : "Could not schedule that."); } }); }; if (contacts.length === 0) { return (

Nobody on file yet. A recruiter, a hiring manager, the friend who might put in a word — once somebody is on file you can line up who to chase from here.

); } return (
Nobody by that name. {contacts.map((contact) => ( { setPerson(contact); setOpen(false); }} >
{contact.name}
{contact.detail && (
{contact.detail}
)}
))}
); }