Add locale support (#228)

This commit is contained in:
Luke Vella 2022-07-21 12:12:35 +01:00 committed by GitHub
parent 800af20132
commit 416a17c5b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 967 additions and 467 deletions

View file

@ -1,12 +1,14 @@
import { AnimatePresence, motion } from "framer-motion";
import { useTranslation } from "next-i18next";
import { Trans, useTranslation } from "next-i18next";
import * as React from "react";
import { useMeasure } from "react-use";
import smoothscroll from "smoothscroll-polyfill";
import ArrowLeft from "@/components/icons/arrow-left.svg";
import ArrowRight from "@/components/icons/arrow-right.svg";
import Check from "@/components/icons/check.svg";
import Plus from "@/components/icons/plus-sm.svg";
import { Button } from "../button";
import ArrowLeft from "../icons/arrow-left.svg";
import ArrowRight from "../icons/arrow-right.svg";
import { useParticipants } from "../participants-provider";
import { usePoll } from "../poll-context";
import TimeZonePicker from "../time-zone-picker";
@ -14,11 +16,10 @@ import ParticipantRow from "./desktop-poll/participant-row";
import ParticipantRowForm from "./desktop-poll/participant-row-form";
import { PollContext } from "./desktop-poll/poll-context";
import PollHeader from "./desktop-poll/poll-header";
import { useAddParticipantMutation } from "./mutations";
if (typeof window !== "undefined") {
smoothscroll.polyfill();
}
import {
useAddParticipantMutation,
useUpdateParticipantMutation,
} from "./mutations";
const MotionButton = motion(Button);
@ -27,7 +28,8 @@ const minSidebarWidth = 200;
const Poll: React.VoidFunctionComponent = () => {
const { t } = useTranslation("app");
const { poll, options, targetTimeZone, setTargetTimeZone } = usePoll();
const { poll, options, targetTimeZone, setTargetTimeZone, userAlreadyVoted } =
usePoll();
const { participants } = useParticipants();
@ -35,7 +37,7 @@ const Poll: React.VoidFunctionComponent = () => {
const [editingParticipantId, setEditingParticipantId] =
React.useState<string | null>(null);
const actionColumnWidth = 140;
const actionColumnWidth = 100;
const columnWidth = Math.min(
130,
Math.max(
@ -65,7 +67,8 @@ const Poll: React.VoidFunctionComponent = () => {
const maxScrollPosition =
columnWidth * options.length - columnWidth * numberOfVisibleColumns;
const shouldShowNewParticipantForm = !poll.closed;
const [shouldShowNewParticipantForm, setShouldShowNewParticipantForm] =
React.useState(!poll.closed && !userAlreadyVoted);
const pollWidth =
sidebarWidth + options.length * columnWidth + actionColumnWidth;
@ -87,6 +90,8 @@ const Poll: React.VoidFunctionComponent = () => {
);
};
const updateParticipant = useUpdateParticipantMutation();
const participantListContainerRef = React.useRef<HTMLDivElement>(null);
return (
<PollContext.Provider
@ -192,28 +197,93 @@ const Poll: React.VoidFunctionComponent = () => {
isEditing ? participant.id : null,
);
}}
onSubmit={async ({ name, votes }) => {
await updateParticipant.mutateAsync({
participantId: participant.id,
pollId: poll.id,
votes,
name,
});
}}
/>
);
})}
</div>
) : null}
{shouldShowNewParticipantForm ? (
{shouldShowNewParticipantForm &&
!poll.closed &&
!editingParticipantId ? (
<ParticipantRowForm
className="border-t bg-gray-50"
className="shrink-0 border-t bg-gray-50"
onSubmit={async ({ name, votes }) => {
const participant = await addParticipant.mutateAsync({
await addParticipant.mutateAsync({
name,
votes,
pollId: poll.id,
});
setTimeout(() => {
participantListContainerRef.current
?.querySelector(`[data-participantid=${participant.id}]`)
?.scrollIntoView();
}, 100);
setShouldShowNewParticipantForm(false);
}}
/>
) : null}
{!poll.closed ? (
<div className="flex h-14 shrink-0 items-center border-t bg-gray-50 px-3">
{shouldShowNewParticipantForm || editingParticipantId ? (
<div className="flex items-center space-x-3">
<Button
key="submit"
form="participant-row-form"
htmlType="submit"
type="primary"
icon={<Check />}
loading={
addParticipant.isLoading || updateParticipant.isLoading
}
>
{t("save")}
</Button>
<Button
onClick={() => {
if (editingParticipantId) {
setEditingParticipantId(null);
} else {
setShouldShowNewParticipantForm(false);
}
}}
>
{t("cancel")}
</Button>
<div className="text-sm">
<Trans
t={t}
i18nKey="saveInstruction"
values={{
save: t("save"),
}}
components={{ b: <strong /> }}
/>
</div>
</div>
) : (
<div className="flex w-full items-center space-x-3">
<Button
key="add-participant"
onClick={() => {
setShouldShowNewParticipantForm(true);
}}
icon={<Plus />}
>
{t("addParticipant")}
</Button>
{userAlreadyVoted ? (
<div className="flex items-center text-sm text-gray-400">
<Check className="mr-1 h-5" />
<div>{t("alreadyVoted")}</div>
</div>
) : null}
</div>
)}
</div>
) : null}
</div>
</div>
</PollContext.Provider>