import { Listbox } from "@headlessui/react"; import { Participant, Vote } from "@prisma/client"; import clsx from "clsx"; import { AnimatePresence, motion } from "framer-motion"; import { useTranslation } from "next-i18next"; import * as React from "react"; import { Controller, FormProvider, useForm } from "react-hook-form"; import smoothscroll from "smoothscroll-polyfill"; import ChevronDown from "@/components/icons/chevron-down.svg"; import Pencil from "@/components/icons/pencil.svg"; import PlusCircle from "@/components/icons/plus-circle.svg"; import Save from "@/components/icons/save.svg"; import Trash from "@/components/icons/trash.svg"; import { usePoll } from "@/components/poll-context"; import { requiredString } from "../../utils/form-validation"; import Button from "../button"; import { styleMenuItem } from "../menu-styles"; import NameInput from "../name-input"; import TimeZonePicker from "../time-zone-picker"; import { useUserName } from "../user-name-context"; import PollOptions from "./mobile-poll/poll-options"; import TimeSlotOptions from "./mobile-poll/time-slot-options"; import { useAddParticipantMutation, useUpdateParticipantMutation, } from "./mutations"; import { ParticipantForm, PollProps } from "./types"; import { useDeleteParticipantModal } from "./use-delete-participant-modal"; import UserAvater from "./user-avatar"; if (typeof window !== "undefined") { smoothscroll.polyfill(); } const MobilePoll: React.VoidFunctionComponent = ({ pollId }) => { const pollContext = usePoll(); const { poll, targetTimeZone, setTargetTimeZone } = pollContext; const { timeZone, participants, role } = poll; const [, setUserName] = useUserName(); const participantById = participants.reduce< Record >((acc, curr) => { acc[curr.id] = { ...curr }; return acc; }, {}); const form = useForm({ defaultValues: { name: "", votes: [], }, }); const { reset, handleSubmit, control, formState } = form; const [selectedParticipantId, setSelectedParticipantId] = React.useState(); const selectedParticipant = selectedParticipantId ? participantById[selectedParticipantId] : undefined; const [editable, setEditable] = React.useState(() => participants.length > 0 ? false : true, ); const [shouldShowSaveButton, setShouldShowSaveButton] = React.useState(false); const formRef = React.useRef(null); React.useEffect(() => { const setState = () => { if (formRef.current) { const rect = formRef.current.getBoundingClientRect(); const saveButtonIsVisible = rect.bottom <= window.innerHeight; setShouldShowSaveButton( !saveButtonIsVisible && formRef.current.getBoundingClientRect().top < window.innerHeight / 2, ); } }; setState(); window.addEventListener("scroll", setState, true); return () => { window.removeEventListener("scroll", setState, true); }; }, []); const { t } = useTranslation("app"); const { mutate: updateParticipantMutation } = useUpdateParticipantMutation(pollId); const { mutate: addParticipantMutation } = useAddParticipantMutation(pollId); const confirmDeleteParticipant = useDeleteParticipantModal(); const submitContainerRef = React.useRef(null); const scrollToSave = () => { if (submitContainerRef.current) { window.scrollTo({ top: document.documentElement.scrollTop + submitContainerRef.current.getBoundingClientRect().bottom - window.innerHeight + 100, behavior: "smooth", }); } }; return (
{ return new Promise((resolve, reject) => { if (selectedParticipant) { updateParticipantMutation( { participantId: selectedParticipant.id, pollId, ...data, }, { onSuccess: () => { resolve(data); setEditable(false); }, onError: reject, }, ); } else { addParticipantMutation(data, { onSuccess: (newParticipant) => { setSelectedParticipantId(newParticipant.id); resolve(data); setEditable(false); }, onError: reject, }); } }); })} >
{selectedParticipant ? (
{selectedParticipant.name}
) : ( t("participantCount", { count: participants.length }) )}
{t("participantCount", { count: participants.length })} {participants.map((participant) => (
{participant.name}
))}
{!poll.closed && !editable ? ( selectedParticipant ? (
{role === "admin" ? (
) : ( ) ) : null} {editable ? ( ) : null}
{timeZone ? ( ) : null}
{(() => { switch (pollContext.pollType) { case "date": return ( ); case "timeSlot": return ( ); } })()} {shouldShowSaveButton && editable ? ( ) : null} {editable ? (
( )} />
) : null}
); }; export default MobilePoll;