mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-22 15:09:16 -05:00
Badge prize preview on calendar event page
This commit is contained in:
parent
5f196ac1d9
commit
efbcafaf82
|
|
@ -1,6 +1,6 @@
|
|||
import { dateToDatabaseTimestamp } from "~/utils/dates";
|
||||
import { sql } from "../sql";
|
||||
import type { CalendarEvent, CalendarEventDate, User } from "../types";
|
||||
import type { CalendarEvent, CalendarEventDate, User, Badge } from "../types";
|
||||
|
||||
const findAllBetweenTwoTimestampsStm = sql.prepare(`
|
||||
select
|
||||
|
|
@ -16,7 +16,7 @@ const findAllBetweenTwoTimestampsStm = sql.prepare(`
|
|||
"CalendarEventRanks"."nthAppearance",
|
||||
exists (select 1
|
||||
from "CalendarEventBadge"
|
||||
where "badgeId" = "CalendarEventDate"."eventId"
|
||||
where "CalendarEventBadge"."eventId" = "CalendarEventDate"."eventId"
|
||||
) as "hasBadge"
|
||||
from "CalendarEvent"
|
||||
join "CalendarEventDate" on "CalendarEvent"."id" = "CalendarEventDate"."eventId"
|
||||
|
|
@ -74,7 +74,7 @@ const findByIdStm = sql.prepare(`
|
|||
"CalendarEvent"."tags",
|
||||
exists (select 1
|
||||
from "CalendarEventBadge"
|
||||
where "badgeId" = "CalendarEventDate"."eventId"
|
||||
where "CalendarEventBadge"."eventId" = "CalendarEventDate"."eventId"
|
||||
) as "hasBadge",
|
||||
"CalendarEventDate"."startTime",
|
||||
"CalendarEventDate"."eventId",
|
||||
|
|
@ -132,3 +132,16 @@ export function startTimesOfRange({
|
|||
}) as Array<Pick<CalendarEventDate, "startTime">>
|
||||
).map(({ startTime }) => startTime);
|
||||
}
|
||||
|
||||
const findBadgesByIdStm = sql.prepare(`
|
||||
select "Badge"."id", "Badge"."code", "Badge"."hue", "Badge"."displayName"
|
||||
from "CalendarEventBadge"
|
||||
join "Badge" on "CalendarEventBadge"."badgeId" = "Badge"."id"
|
||||
where "CalendarEventBadge"."eventId" = $eventId
|
||||
`);
|
||||
|
||||
export function findBadgesById(eventId: CalendarEvent["id"]) {
|
||||
return findBadgesByIdStm.all({ eventId }) as Array<
|
||||
Pick<Badge, "id" | "code" | "hue" | "displayName">
|
||||
>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,17 @@ import { Avatar } from "~/components/Avatar";
|
|||
import { discordFullName } from "~/utils/strings";
|
||||
import * as React from "react";
|
||||
import { Tags } from "./components/Tags";
|
||||
import { Badge } from "~/components/Badge";
|
||||
import allTags from "./tags.json";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
|
||||
export const handle = {
|
||||
i18n: "calendar",
|
||||
};
|
||||
|
||||
export const loader = ({ params }: LoaderArgs) => {
|
||||
const parsedParams = z
|
||||
.object({ id: z.preprocess(actualNumber, id) })
|
||||
|
|
@ -28,6 +34,7 @@ export const loader = ({ params }: LoaderArgs) => {
|
|||
|
||||
return json({
|
||||
event,
|
||||
badgePrizes: db.calendar.findBadgesById(parsedParams.id),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -92,16 +99,39 @@ export default function CalendarEventPage() {
|
|||
</div>
|
||||
</section>
|
||||
<div className="stack sm">
|
||||
<div className="event__author">
|
||||
<Avatar
|
||||
discordAvatar={event.discordAvatar}
|
||||
discordId={event.discordId}
|
||||
size="xs"
|
||||
/>
|
||||
{discordFullName(event)}
|
||||
<div className="event__author-badges-container">
|
||||
<div className="event__author">
|
||||
<Avatar
|
||||
discordAvatar={event.discordAvatar}
|
||||
discordId={event.discordId}
|
||||
size="xs"
|
||||
/>
|
||||
{discordFullName(event)}
|
||||
</div>
|
||||
<PrizeBadges />
|
||||
</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_PRIZE"].color }}
|
||||
>
|
||||
Win!
|
||||
<div className="event__badges__gifs">
|
||||
{badgePrizes.map((badge) => (
|
||||
<Badge key={badge.code} badge={badge} size={26} isAnimated />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,7 +341,10 @@ function EventsList() {
|
|||
) : null}
|
||||
</section>,
|
||||
i < events.length - 1 ? (
|
||||
<hr className="calendar__event__divider" />
|
||||
<hr
|
||||
key={`${calendarEvent.eventId}-line`}
|
||||
className="calendar__event__divider"
|
||||
/>
|
||||
) : null,
|
||||
];
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,26 @@
|
|||
grid-template-columns: max-content 1fr;
|
||||
}
|
||||
|
||||
.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;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ export function weekNumberToDate({
|
|||
/** start = Date of Monday, end = Date of Sunday */
|
||||
position?: "start" | "end";
|
||||
}) {
|
||||
// xxx: possible problem of mismatch when server time and local time don't match
|
||||
// gotta make sure events which belong to monday are still shown for sunday
|
||||
const result = new Date(Date.UTC(year, 0, 4));
|
||||
|
||||
result.setDate(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user