import { cn } from "@rallly/ui"; import { Button } from "@rallly/ui/button"; import type { DialogProps } from "@rallly/ui/dialog"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@rallly/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, } from "@rallly/ui/form"; import { RadioGroup, RadioGroupItem } from "@rallly/ui/radio-group"; import dayjs from "dayjs"; import { Trans } from "next-i18next"; import React from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { trpc } from "@/app/providers"; import { DateIconInner } from "@/components/date-icon"; import { useParticipants } from "@/components/participants-provider"; import { ConnectedScoreSummary } from "@/components/poll/score-summary"; import { VoteSummaryProgressBar } from "@/components/vote-summary-progress-bar"; import { usePoll } from "@/contexts/poll"; import { useDayjs } from "@/utils/dayjs"; const formSchema = z.object({ selectedOptionId: z.string(), notify: z.enum(["none", "all", "attendees"]), }); type FinalizeFormData = z.infer; type OptionScore = { yes: string[]; ifNeedBe: string[]; no: string[]; }; const useScoreByOptionId = () => { const { participants: responses } = useParticipants(); const { options } = usePoll(); return React.useMemo(() => { const scoreByOptionId: Record = {}; options.forEach((option) => { scoreByOptionId[option.id] = { yes: [], ifNeedBe: [], no: [], }; }); responses?.forEach((response) => { response.votes.forEach((vote) => { scoreByOptionId[vote.optionId]?.[vote.type].push(response.id); }); }); return scoreByOptionId; }, [responses, options]); }; function DateIcon({ start }: { start: Date }) { const poll = usePoll(); const { adjustTimeZone } = useDayjs(); const d = adjustTimeZone(start, !poll.timeZone); return ; } export const FinalizePollForm = ({ name, onSubmit, }: { name: string; onSubmit?: (data: FinalizeFormData) => void; }) => { const poll = usePoll(); const { adjustTimeZone } = useDayjs(); const scoreByOptionId = useScoreByOptionId(); const { participants } = useParticipants(); const options = [...poll.options] .sort((a, b) => { const aYes = scoreByOptionId[a.id].yes.length; const bYes = scoreByOptionId[b.id].yes.length; const aIfNeedBe = scoreByOptionId[a.id].ifNeedBe.length; const bIfNeedBe = scoreByOptionId[b.id].ifNeedBe.length; const aTotal = aYes + aIfNeedBe; const bTotal = bYes + bIfNeedBe; if (aTotal !== bTotal) { return bTotal - aTotal; } if (aYes !== bYes) { return bYes - aYes; } return bIfNeedBe - aIfNeedBe; }) .map((option) => { return { ...option, votes: scoreByOptionId[option.id] }; }); const form = useForm({ defaultValues: { selectedOptionId: options[0].id, notify: "all", }, }); return (
{ onSubmit?.(data); })} > { return ( {options.map((option) => { const start = adjustTimeZone( option.startTime, !poll.timeZone, ); const end = adjustTimeZone( dayjs(option.startTime).add(option.duration, "minute"), !poll.timeZone, ); return ( ); })} ); }} /> ); }; export function FinalizePollDialog(props: DialogProps) { const poll = usePoll(); const scheduleEvent = trpc.polls.book.useMutation(); return ( { scheduleEvent.mutate({ pollId: poll.id, optionId: data.selectedOptionId, notify: data.notify, }); props.onOpenChange?.(false); }} /> ); }