Voting history UI done

This commit is contained in:
Kalle 2022-06-05 20:07:47 +03:00
parent 105854335f
commit 2a60b373d8
4 changed files with 149 additions and 13 deletions

View File

@ -56,7 +56,7 @@ const resultsByMonthYearStm = sql.prepare(`
FROM "PlusVotingResult"
JOIN "User" ON "PlusVotingResult"."votedId" = "User".id
WHERE month = $month AND year = $year
ORDER BY RANDOM()
ORDER BY "User"."discordName" COLLATE NOCASE ASC
`);
type PlusVotingResultUser = Pick<

View File

@ -15,7 +15,8 @@ const basicSeeds = [
adminUser,
nzapUser,
users,
initialPlusMembers,
lastMonthsVoting,
lastMonthSuggestions,
thisMonthsSuggestions,
];
@ -74,29 +75,47 @@ function fakeUser() {
};
}
function initialPlusMembers() {
const idToPlusTier = (id: number) => {
if (id < 30) return 1;
if (id < 80) return 2;
if (id <= 150) return 3;
// these ids failed the voting
if (id >= 200 && id <= 209) return 1;
if (id >= 210 && id <= 219) return 2;
if (id >= 220 && id <= 229) return 3;
throw new Error("Invalid id - no plus tier");
};
function lastMonthsVoting() {
const votes: CreateManyPlusVotesArgs = [];
const { month, year } = lastCompletedVoting(new Date());
const tier = (id: number) => {
if (id < 30) return 1;
if (id < 80) return 2;
return 3;
};
const fiveMinutesAgo = new Date(new Date().getTime() - 5 * 60 * 1000);
for (let id = 1; id < 151; id++) {
if (id === 2) continue; // omit N-ZAP user for testing;
const fiveMinutesAgo = new Date(new Date().getTime() - 5 * 60 * 1000);
votes.push({
authorId: 1,
month,
year,
score: 1,
tier: tier(id),
tier: idToPlusTier(id),
validAfter: fiveMinutesAgo,
votedId: id,
});
}
for (let id = 200; id < 225; id++) {
votes.push({
authorId: 1,
month,
year,
score: -1,
tier: idToPlusTier(id),
validAfter: fiveMinutesAgo,
votedId: id,
});
@ -105,6 +124,24 @@ function initialPlusMembers() {
db.plusVotes.createMany(votes);
}
function lastMonthSuggestions() {
const usersSuggested = [
3, 10, 14, 90, 120, 140, 200, 201, 203, 204, 205, 216, 217, 218, 219, 220,
];
const { month, year } = lastCompletedVoting(new Date());
for (const id of usersSuggested) {
db.plusSuggestions.create({
authorId: 1,
month,
year,
suggestedId: id,
text: faker.lorem.lines(),
tier: idToPlusTier(id),
});
}
}
function thisMonthsSuggestions() {
const usersInPlus = db.users
.findAll()

View File

@ -13,6 +13,10 @@ import { roundToTwoDecimalPlaces } from "~/utils/number";
import { getUser, makeTitle } from "~/utils/remix";
import type { Unpacked } from "~/utils/types";
import styles from "~/styles/plus-history.css";
import { discordFullName } from "~/utils/strings";
import { Link } from "react-router-dom";
import { userPage } from "~/utils/urls";
import clsx from "clsx";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
@ -69,7 +73,7 @@ export default function PlusVotingHistoryPage() {
) : (
<span className="plus-history__fail">didn&apos;t pass</span>
)}{" "}
the +1 voting
the +{result.tier} voting
{result.score
? `, your score was ${result.score} (at least 0.5 required to pass)`
: ""}
@ -77,6 +81,45 @@ export default function PlusVotingHistoryPage() {
))}
</ul>
) : null}
<Results />
</div>
);
}
function Results() {
const data = useLoaderData<PlusVotingHistoryLoaderData>();
return (
<div className="stack lg">
{data.results.map((tiersResults) => (
<div className="stack md" key={tiersResults.tier}>
<h3 className="plus-history__tier-header">
<span>+{tiersResults.tier}</span>
</h3>
{(["passed", "failed"] as const).map((status) => (
<div key={status} className="plus-history__passed-info-container">
<h4 className="plus-history__passed-header">
{status === "passed" ? "Passed" : "Didn't pass"} (
{tiersResults[status].length})
</h4>
{tiersResults[status].map((user) => (
<Link
to={userPage(user.discordId)}
className={clsx("plus-history__user-status", {
failed: status === "failed",
})}
key={user.id}
>
{user.wasSuggested ? (
<span className="plus-history__suggestion-s">S</span>
) : null}
{discordFullName(user)}
</Link>
))}
</div>
))}
</div>
))}
</div>
);
}

View File

@ -13,3 +13,59 @@
.plus-history__fail {
color: var(--theme-error);
}
.plus-history__tier-header {
display: flex;
flex-direction: row;
color: var(--theme);
}
.plus-history__tier-header::before,
.plus-history__tier-header::after {
flex: 1 1;
border-bottom: 3px solid var(--theme-transparent);
margin: auto;
content: "";
}
.plus-history__tier-header::before {
margin-right: 10px;
}
.plus-history__tier-header::after {
margin-left: 10px;
}
.plus-history__passed-info-container {
display: flex;
flex-wrap: wrap;
gap: var(--s-2);
}
.plus-history__passed-header {
color: var(--text-lighter);
font-size: var(--fonts-xs);
}
.plus-history__user-status {
background-color: var(--theme);
border-radius: var(--rounded);
color: var(--button-text);
font-size: var(--fonts-xs);
font-weight: var(--semi-bold);
padding-inline: var(--s-1-5);
}
.plus-history__user-status.failed {
background-color: var(--theme-error-transparent);
color: var(--text);
}
.plus-history__suggestion-s {
background-color: var(--bg-lighter);
border-radius: 50%;
color: var(--text);
font-weight: var(--bold);
margin-inline-end: var(--s-1);
padding-inline: var(--s-1);
}