Badge prize preview inside tags

This commit is contained in:
Kalle
2022-07-31 19:59:03 +03:00
parent 2477c5fb10
commit f8d97ff3c5
8 changed files with 54 additions and 64 deletions

View File

@@ -22,6 +22,7 @@ Calendar
## Other
- [x] badges inside tag?
- [ ] Move "BADGE" tag resolving to DB?
- [x] Tags selector can remove
- [x] Calendar new title

View File

@@ -136,7 +136,7 @@ const findAllBetweenTwoTimestampsStm = sql.prepare(`
"CalendarEvent"."discordUrl",
"CalendarEvent"."bracketUrl",
"CalendarEvent"."tags",
"CalendarEventDate"."id",
"CalendarEventDate"."id" as "eventDateId",
"CalendarEventDate"."eventId",
"CalendarEventDate"."startTime",
"User"."discordName",
@@ -184,8 +184,9 @@ export function findAllBetweenTwoTimestamps({
endTime: dateToDatabaseTimestamp(endTime),
}) as Array<
Pick<CalendarEvent, "name" | "discordUrl" | "bracketUrl" | "tags"> &
Pick<CalendarEventDate, "id" | "eventId" | "startTime"> &
Pick<User, "discordName" | "discordDiscriminator"> & {
Pick<CalendarEventDate, "eventId" | "startTime"> & {
eventDateId: CalendarEventDate["id"];
} & Pick<User, "discordName" | "discordDiscriminator"> & {
nthAppearance: number;
} & { hasBadge: number }
>;

View File

@@ -11,7 +11,6 @@ import * as React from "react";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { Avatar } from "~/components/Avatar";
import { Badge } from "~/components/Badge";
import { LinkButton } from "~/components/Button";
import { Main } from "~/components/Main";
import { db } from "~/db";
@@ -26,7 +25,6 @@ import { discordFullName, makeTitle } from "~/utils/strings";
import { calendarEditPage, resolveBaseUrl } from "~/utils/urls";
import { actualNumber, id } from "~/utils/zod";
import { Tags } from "./components/Tags";
import allTags from "./tags.json";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
@@ -63,12 +61,12 @@ export const loader = async ({ params, request }: LoaderArgs) => {
export default function CalendarEventPage() {
const user = useUser();
const { event } = useLoaderData<typeof loader>();
const { event, badgePrizes } = useLoaderData<typeof loader>();
const { i18n } = useTranslation();
const isMounted = useIsMounted();
return (
<Main className="stack md">
<Main className="stack lg">
<section className="stack sm">
<div className="event__times">
{event.startTimes.map((startTime, i) => (
@@ -100,7 +98,7 @@ export default function CalendarEventPage() {
<div className="stack md">
<div className="stack xs">
<h2>{event.name}</h2>
<Tags tags={event.tags} />
<Tags tags={event.tags} badges={badgePrizes} />
</div>
<div className="stack horizontal sm flex-wrap">
{event.discordUrl ? (
@@ -130,39 +128,16 @@ export default function CalendarEventPage() {
</div>
</section>
<div className="stack sm">
<div className="event__author-badges-container">
<div className="event__author">
<Avatar
discordAvatar={event.discordAvatar}
discordId={event.discordId}
size="xs"
/>
{discordFullName(event)}
</div>
<PrizeBadges />
<div className="event__author">
<Avatar
discordAvatar={event.discordAvatar}
discordId={event.discordId}
size="xs"
/>
{discordFullName(event)}
</div>
<div>{event.description}</div>
</div>
</Main>
);
}
function PrizeBadges() {
const { badgePrizes } = useLoaderData<typeof loader>();
if (badgePrizes.length === 0) return null;
return (
<div
className="event__badges__container"
style={{ color: allTags["BADGE"].color }}
>
Win!
<div className="event__badges__gifs">
{badgePrizes.map((badge) => (
<Badge key={badge.code} badge={badge} size={26} isAnimated />
))}
</div>
</div>
);
}

View File

@@ -1,15 +1,19 @@
import clsx from "clsx";
import React from "react";
import { useTranslation } from "react-i18next";
import { Badge } from "~/components/Badge";
import { Button } from "~/components/Button";
import { CrossIcon } from "~/components/icons/Cross";
import type { CalendarEventTag } from "~/db/types";
import type { Badge as BadgeType, CalendarEventTag } from "~/db/types";
import allTags from "../tags.json";
export function Tags({
tags,
badges,
onDelete,
}: {
tags: Array<CalendarEventTag>;
badges?: Array<BadgeType>;
/** Called when tag delete button clicked. If undefined delete buttons won't be shown. */
onDelete?: (tag: CalendarEventTag) => void;
}) {
@@ -21,7 +25,10 @@ export function Tags({
<ul className="calendar__event__tags">
{tags.map((tag) => (
<React.Fragment key={tag}>
<li style={{ backgroundColor: allTags[tag].color }}>
<li
style={{ backgroundColor: allTags[tag].color }}
className={clsx({ "calendar__event__badge-tag": tag === "BADGE" })}
>
{t(`tag.name.${tag}`)}
{onDelete && (
<Button
@@ -34,6 +41,13 @@ export function Tags({
data-cy="tag-delete-button"
/>
)}
{tag === "BADGE" && badges && (
<div className="calendar__event__tag-badges">
{badges.map((badge) => (
<Badge key={badge.id} badge={badge} size={20} isAnimated />
))}
</div>
)}
</li>
</React.Fragment>
))}

View File

@@ -115,7 +115,14 @@ function fetchEventsOfWeek(args: { week: number; year: number }) {
// so we get all events of sunday even from US west coast perspective
endTime.setHours(endTime.getHours() + 12);
return db.calendarEvents.findAllBetweenTwoTimestamps({ startTime, endTime });
return db.calendarEvents
.findAllBetweenTwoTimestamps({ startTime, endTime })
.map((event) => ({
...event,
badgePrizes: event.tags.includes("BADGE")
? db.calendarEvents.findBadgesById(event.eventId)
: [],
}));
}
export default function CalendarPage() {
@@ -290,7 +297,7 @@ function EventsList() {
<div className="stack md">
{events.map((calendarEvent, i) => {
return (
<React.Fragment key={calendarEvent.eventId}>
<React.Fragment key={calendarEvent.eventDateId}>
<section className="calendar__event main stack md">
<div className="stack sm">
<div
@@ -329,7 +336,10 @@ function EventsList() {
) : null}
</h2>
</Link>
<Tags tags={calendarEvent.tags} />
<Tags
tags={calendarEvent.tags}
badges={calendarEvent.badgePrizes}
/>
</div>
</div>
<div className="calendar__event__bottom-info-container">

View File

@@ -1,6 +1,6 @@
{
"BADGE": {
"color": "#FDFD96"
"color": "#000"
},
"SPECIAL": {
"color": "#CE93D8"

View File

@@ -17,26 +17,6 @@
height: 1.25rem;
}
.event__author-badges-container {
display: flex;
align-items: flex-end;
justify-content: space-between;
}
.event__badges__container {
font-size: var(--fonts-xs);
font-weight: var(--semi-bold);
text-align: center;
}
.event__badges__gifs {
display: flex;
flex-wrap: wrap;
padding: var(--s-2);
background-color: var(--bg-badge);
border-radius: var(--rounded);
}
.event__author {
display: flex;
align-items: center;

View File

@@ -551,10 +551,19 @@ dialog::backdrop {
padding-inline: var(--s-1-5);
}
.calendar__event__badge-tag {
color: var(--badge-text);
}
.calendar__event__tag-delete-button {
margin-left: auto;
}
.calendar__event__tag-badges {
display: flex;
margin-inline-start: var(--s-1);
}
.calendar__event__tag-delete-button > svg {
width: 0.85rem !important;
color: var(--black-text);