Banner informing user has voted

This commit is contained in:
Kalle
2022-06-13 08:57:42 +03:00
parent 52fea7fcc9
commit 019c73c2b8
6 changed files with 70 additions and 68 deletions

View File

@@ -249,3 +249,24 @@ export function usersForVoting(
return shuffle(result.filter(({ user }) => user.id !== loggedInUser.id));
}
const hasVotedStm = sql.prepare(`
SELECT 1
FROM "PlusVote"
WHERE "authorId" = $userId AND "month" = $month AND "year" = $year
`);
export function hasVoted({
month,
year,
user,
}: MonthYear & { user?: Pick<User, "id"> }) {
if (!user) return false;
return Boolean(
hasVotedStm.get({
userId: user.id,
month,
year,
})
);
}

View File

@@ -6,6 +6,7 @@ import * as React from "react";
import { z } from "zod";
import { Avatar } from "~/components/Avatar";
import { Button } from "~/components/Button";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
import { RelativeTime } from "~/components/RelativeTime";
import { PLUS_DOWNVOTE, PLUS_UPVOTE } from "~/constants";
import { db } from "~/db";
@@ -100,14 +101,13 @@ type PlusVotingLoaderData =
relativeTime: string;
timestamp: number;
timing: "starts" | "ends";
voted?: boolean;
}
// user can vote
| {
type: "voting";
usersForVoting: UsersForVoting;
}
// user already voted
| { type: "votingInfo"; votingInfo: { placeholder: true } };
};
export const loader: LoaderFunction = async ({ request }) => {
const user = await getUser(request);
@@ -124,13 +124,18 @@ export const loader: LoaderFunction = async ({ request }) => {
}
const usersForVoting = db.plusVotes.usersForVoting(user);
const hasVoted = db.plusVotes.hasVoted({
user,
...nextNonCompletedVoting(new Date()),
});
if (!usersForVoting) {
if (!usersForVoting || hasVoted) {
return json<PlusVotingLoaderData>({
type: "timeInfo",
relativeTime: formatDistance(endDate, now, { addSuffix: true }),
timestamp: endDate.getTime(),
timing: "ends",
voted: hasVoted,
});
}
@@ -150,9 +155,6 @@ export default function PlusVotingPage() {
case "voting": {
return <Voting {...data} />;
}
case "votingInfo": {
return null;
}
default: {
assertUnreachable(data);
}
@@ -163,13 +165,20 @@ function VotingTimingInfo(
data: Extract<PlusVotingLoaderData, { type: "timeInfo" }>
) {
return (
<div className="text-sm text-center">
{data.timing === "starts"
? "Next voting starts"
: "Voting is currently happening. Ends"}{" "}
<RelativeTime timestamp={data.timestamp}>
{data.relativeTime}
</RelativeTime>
<div className="stack md">
{data.voted ? (
<div className="plus-voting__alert">
<CheckmarkIcon /> You have voted
</div>
) : null}
<div className="text-sm text-center">
{data.timing === "starts"
? "Next voting starts"
: "Voting is currently happening. Ends"}{" "}
<RelativeTime timestamp={data.timestamp}>
{data.relativeTime}
</RelativeTime>
</div>
</div>
);
}

View File

@@ -17,6 +17,7 @@
--theme-warning: #f5f587;
--theme-info: #a3a6ff;
--theme-success: #a3ffae;
--theme-success-transparent: #a3ffae52;
--theme: hsl(255deg 66.7% 75%);
--theme-transparent: hsl(255deg 66.7% 75% / 40%);
--theme-transparent-vibrant: hsl(255deg 78% 65% / 54%);
@@ -29,7 +30,7 @@
--fonts-xl: 1.5rem;
--fonts-lg: 1.2rem;
--fonts-md: 1rem;
--fonts-sm: 0.9rem;
--fonts-sm: 0.92rem;
--fonts-xs: 0.8rem;
--fonts-xxs: 0.7rem;
--extra-bold: 700;

View File

@@ -123,3 +123,25 @@
.plus-voting__progress {
width: 100%;
}
.plus-voting__alert {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--theme-success-transparent);
border-radius: var(--rounded);
color: var(--text);
font-size: var(--fonts-sm);
font-weight: var(--semi-bold);
gap: var(--s-2);
line-height: 0.75;
margin-inline: auto;
padding-block: var(--s-1);
padding-inline-end: var(--s-4);
padding-inline-start: var(--s-3);
}
.plus-voting__alert > svg {
height: 1.75rem;
fill: var(--theme-success);
}

View File

@@ -69,4 +69,6 @@ describe("Plus voting results page", () => {
cy.contains("Sendou");
cy.contains("your score was");
});
// xxx: describe Plus Voting
});

View File

@@ -1,53 +0,0 @@
- /plus
-> Shows if you are suggested or not
- CRUD suggestions for your own tier and below
- CUD disabled when voting is active
- /plus/voting
## Voting is active
-> If not member just show same view as when voting is not active
- When voting the progress is saved in your browser so even if you leave the page you can continue where you left off.
- +1/-1 regardless of region
## Voting is not active
- You will see who passed the last voting and who didn't.
- If you didn't pass the voting and you were a suggestion then you will see your own percentage
- others see who passed and who didn't per tier
- at the top show your own results in green/red per tier
## Tables
- "User"
* "plusTier" 1/2/3
- "PlusSuggestion"
* "text" text
* "authorId" text
* "suggestedId" text
* "month"
* "year"
* "tier" 1/2/3
* "createdAt"
- "PlusVote"
* "month"
* "year"
* "tier"
* "authorId"
* "votedId"
* "score"
unique on month, year, authorId, votedId
# Cypress
- uses different db file
- uses different port
- NODE_ENV = test