mirror of
https://github.com/lukevella/rallly.git
synced 2025-06-05 04:02:21 +02:00
♻️ Update how we store poll status (#957)
This commit is contained in:
parent
7670db6778
commit
04211ac168
10 changed files with 108 additions and 186 deletions
|
@ -75,12 +75,7 @@ export function PollsPage() {
|
|||
data.length > 0 ? (
|
||||
<div className="mx-auto grid max-w-3xl gap-3 sm:gap-4">
|
||||
{data.map((poll) => {
|
||||
const { title, id: pollId, createdAt, closed: paused } = poll;
|
||||
const status = poll.event
|
||||
? "closed"
|
||||
: paused
|
||||
? "paused"
|
||||
: "live";
|
||||
const { title, id: pollId, createdAt, status } = poll;
|
||||
return (
|
||||
<div
|
||||
key={poll.id}
|
||||
|
|
|
@ -34,8 +34,6 @@ export const EventCard = () => {
|
|||
),
|
||||
);
|
||||
|
||||
const status = poll?.event ? "closed" : poll?.closed ? "paused" : "live";
|
||||
|
||||
if (!poll) {
|
||||
return null;
|
||||
}
|
||||
|
@ -49,7 +47,7 @@ export const EventCard = () => {
|
|||
/>
|
||||
<div className="bg-pattern p-4 sm:flex sm:flex-row-reverse sm:justify-between sm:px-6">
|
||||
<div className="mb-2">
|
||||
<PollStatusBadge status={status} />
|
||||
<PollStatusBadge status={poll.status} />
|
||||
</div>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start gap-4 sm:gap-6">
|
||||
|
|
|
@ -42,7 +42,7 @@ import {
|
|||
import ManagePoll from "@/components/poll/manage-poll";
|
||||
import NotificationsToggle from "@/components/poll/notifications-toggle";
|
||||
import { LegacyPollContextProvider } from "@/components/poll/poll-context-provider";
|
||||
import { PollStatus } from "@/components/poll-status";
|
||||
import { PollStatusLabel } from "@/components/poll-status";
|
||||
import { Skeleton } from "@/components/skeleton";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { useUser } from "@/components/user-provider";
|
||||
|
@ -53,7 +53,6 @@ import { NextPageWithLayout } from "../../types";
|
|||
|
||||
const StatusControl = () => {
|
||||
const poll = usePoll();
|
||||
const state = poll.event ? "closed" : poll.closed ? "paused" : "live";
|
||||
const queryClient = trpc.useUtils();
|
||||
const reopen = trpc.polls.reopen.useMutation({
|
||||
onMutate: () => {
|
||||
|
@ -110,7 +109,7 @@ const StatusControl = () => {
|
|||
<DropdownMenu modal={false}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button>
|
||||
<PollStatus status={state} />
|
||||
<PollStatusLabel status={poll.status} />
|
||||
<ChevronDownIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { PollStatus } from "@rallly/database";
|
||||
import { cn } from "@rallly/ui";
|
||||
import { CheckCircleIcon, PauseCircleIcon, RadioIcon } from "lucide-react";
|
||||
|
||||
import { Trans } from "@/components/trans";
|
||||
import { IconComponent } from "@/types";
|
||||
|
||||
export type PollState = "live" | "paused" | "closed";
|
||||
|
||||
const LabelWithIcon = ({
|
||||
icon: Icon,
|
||||
children,
|
||||
|
@ -23,11 +22,11 @@ const LabelWithIcon = ({
|
|||
);
|
||||
};
|
||||
|
||||
export const PollStatus = ({
|
||||
export const PollStatusLabel = ({
|
||||
status,
|
||||
className,
|
||||
}: {
|
||||
status: PollState;
|
||||
status: PollStatus;
|
||||
className?: string;
|
||||
}) => {
|
||||
switch (status) {
|
||||
|
@ -43,7 +42,7 @@ export const PollStatus = ({
|
|||
<Trans i18nKey="pollStatusPaused" defaults="Paused" />
|
||||
</LabelWithIcon>
|
||||
);
|
||||
case "closed":
|
||||
case "finalized":
|
||||
return (
|
||||
<LabelWithIcon icon={CheckCircleIcon} className={className}>
|
||||
<Trans i18nKey="pollStatusClosed" defaults="Finalized" />
|
||||
|
@ -52,13 +51,13 @@ export const PollStatus = ({
|
|||
}
|
||||
};
|
||||
|
||||
export const PollStatusBadge = ({ status }: { status: PollState }) => {
|
||||
export const PollStatusBadge = ({ status }: { status: PollStatus }) => {
|
||||
return (
|
||||
<PollStatus
|
||||
<PollStatusLabel
|
||||
className={cn("rounded-full border py-0.5 pl-1.5 pr-3 text-sm", {
|
||||
"border-blue-500 text-blue-500": status === "live",
|
||||
"border-gray-500 text-gray-500": status === "paused",
|
||||
"border-green-500 text-green-500": status === "closed",
|
||||
"border-green-500 text-green-500": status === "finalized",
|
||||
})}
|
||||
status={status}
|
||||
/>
|
||||
|
|
|
@ -65,7 +65,7 @@ const NotificationsToggle: React.FunctionComponent = () => {
|
|||
loading={watch.isLoading || unwatch.isLoading}
|
||||
icon={isWatching ? BellRingIcon : BellOffIcon}
|
||||
data-testid="notifications-toggle"
|
||||
disabled={poll.demo || user.isGuest}
|
||||
disabled={user.isGuest}
|
||||
className="flex items-center gap-2 px-2.5"
|
||||
onClick={async () => {
|
||||
if (user.isGuest) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { User, VoteType } from "@rallly/database";
|
||||
import { PollStatus, User, VoteType } from "@rallly/database";
|
||||
|
||||
export type GetPollApiResponse = {
|
||||
id: string;
|
||||
|
@ -9,10 +9,9 @@ export type GetPollApiResponse = {
|
|||
user: User | null;
|
||||
timeZone: string | null;
|
||||
adminUrlId: string;
|
||||
status: PollStatus;
|
||||
participantUrlId: string;
|
||||
closed: boolean;
|
||||
legacy: boolean;
|
||||
demo: boolean;
|
||||
createdAt: Date;
|
||||
deleted: boolean;
|
||||
};
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
import { prisma, VoteType } from "@rallly/database";
|
||||
import dayjs from "dayjs";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
const participantData: Array<{ name: string; votes: VoteType[] }> = [
|
||||
{
|
||||
name: "Reed",
|
||||
votes: ["yes", "no", "yes", "no"],
|
||||
},
|
||||
{
|
||||
name: "Susan",
|
||||
votes: ["yes", "yes", "yes", "no"],
|
||||
},
|
||||
{
|
||||
name: "Johnny",
|
||||
votes: ["no", "no", "yes", "yes"],
|
||||
},
|
||||
{
|
||||
name: "Ben",
|
||||
votes: ["yes", "yes", "yes", "yes"],
|
||||
},
|
||||
];
|
||||
|
||||
const optionValues = ["2022-12-14", "2022-12-15", "2022-12-16", "2022-12-17"];
|
||||
|
||||
export const createPoll = async () => {
|
||||
const pollId = nanoid();
|
||||
|
||||
const adminUrlId = nanoid();
|
||||
|
||||
const options: Array<{ start: Date; id: string }> = [];
|
||||
|
||||
for (let i = 0; i < optionValues.length; i++) {
|
||||
options.push({ id: nanoid(), start: new Date(optionValues[i]) });
|
||||
}
|
||||
|
||||
const participants: Array<{
|
||||
name: string;
|
||||
id: string;
|
||||
userId: string;
|
||||
createdAt: Date;
|
||||
}> = [];
|
||||
|
||||
const votes: Array<{
|
||||
optionId: string;
|
||||
participantId: string;
|
||||
type: VoteType;
|
||||
}> = [];
|
||||
|
||||
for (let i = 0; i < participantData.length; i++) {
|
||||
const { name, votes: participantVotes } = participantData[i];
|
||||
const participantId = nanoid();
|
||||
participants.push({
|
||||
id: participantId,
|
||||
name,
|
||||
userId: "user-demo",
|
||||
createdAt: dayjs()
|
||||
.add(i * -1, "minutes")
|
||||
.toDate(),
|
||||
});
|
||||
|
||||
options.forEach((option, index) => {
|
||||
votes.push({
|
||||
optionId: option.id,
|
||||
participantId,
|
||||
type: participantVotes[index],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.poll.create({
|
||||
data: {
|
||||
id: pollId,
|
||||
title: "Lunch Meeting",
|
||||
location: "Starbucks, 901 New York Avenue",
|
||||
description: `Hey everyone, please choose the dates when you are available to meet for our monthly get together. Looking forward to see you all!`,
|
||||
demo: true,
|
||||
adminUrlId,
|
||||
participantUrlId: nanoid(),
|
||||
userId: "guest-user",
|
||||
options: {
|
||||
createMany: {
|
||||
data: options,
|
||||
},
|
||||
},
|
||||
participants: {
|
||||
createMany: {
|
||||
data: participants,
|
||||
},
|
||||
},
|
||||
votes: {
|
||||
createMany: {
|
||||
data: votes,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return pollId;
|
||||
};
|
||||
|
||||
export const deletePoll = async (pollId: string) => {
|
||||
await prisma.$transaction([
|
||||
prisma.vote.deleteMany({
|
||||
where: {
|
||||
pollId,
|
||||
},
|
||||
}),
|
||||
prisma.option.deleteMany({
|
||||
where: {
|
||||
pollId,
|
||||
},
|
||||
}),
|
||||
prisma.participant.deleteMany({
|
||||
where: {
|
||||
pollId,
|
||||
},
|
||||
}),
|
||||
prisma.comment.deleteMany({
|
||||
where: {
|
||||
pollId,
|
||||
},
|
||||
}),
|
||||
prisma.poll.deleteMany({
|
||||
where: {
|
||||
id: pollId,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue