mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-28 14:18:04 -05:00
Scope my events hosting list to author and explicit organizers, organization events on the my events page
This commit is contained in:
@@ -7,14 +7,16 @@ import styles from "./SubNav.module.css";
|
||||
export function SubNav({
|
||||
children,
|
||||
secondary,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
secondary?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<nav
|
||||
className={clsx(styles.container, {
|
||||
className={clsx(styles.container, className, {
|
||||
[styles.secondary]: secondary,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -42,6 +42,8 @@ export interface CalendarEvent extends CommonEvent {
|
||||
export interface ShowcaseCalendarEvent extends CommonEvent {
|
||||
type: "showcase";
|
||||
startTime: number;
|
||||
/** Id of the organization the event belongs to, if any */
|
||||
organizationId: number | null;
|
||||
/** Tournament is hidden from the public (test tournament) */
|
||||
hidden: boolean;
|
||||
isFinalized: boolean;
|
||||
|
||||
@@ -6,16 +6,25 @@ import {
|
||||
tournamentToSidebarEvent,
|
||||
} from "~/features/sidebar/core/sidebar.server";
|
||||
import * as SavedCalendarEventRepository from "~/features/tournament/SavedCalendarEventRepository.server";
|
||||
import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server";
|
||||
|
||||
export type EventsLoaderData = typeof loader;
|
||||
|
||||
export const loader = async () => {
|
||||
const user = requireUser();
|
||||
|
||||
const [tournamentsData, scrimsData, savedTournaments] = await Promise.all([
|
||||
const [
|
||||
tournamentsData,
|
||||
scrimsData,
|
||||
savedTournaments,
|
||||
upcomingTournaments,
|
||||
userOrganizations,
|
||||
] = await Promise.all([
|
||||
ShowcaseTournaments.categorizedTournamentsByUserId(user.id),
|
||||
ScrimPostRepository.findUserScrims(user.id),
|
||||
SavedCalendarEventRepository.upcoming(user.id),
|
||||
ShowcaseTournaments.upcomingTournaments(),
|
||||
TournamentOrganizationRepository.findByUserId(user.id),
|
||||
]);
|
||||
|
||||
const registered = tournamentsData.participatingFor
|
||||
@@ -34,5 +43,16 @@ export const loader = async () => {
|
||||
.map(tournamentToSidebarEvent)
|
||||
.sort((a, b) => a.startTime - b.startTime);
|
||||
|
||||
return { registered, hosting, scrims, saved };
|
||||
const userOrganizationIds = new Set(userOrganizations.map((org) => org.id));
|
||||
const organization = upcomingTournaments
|
||||
.filter(
|
||||
(tournament) =>
|
||||
!tournament.hidden &&
|
||||
tournament.organizationId !== null &&
|
||||
userOrganizationIds.has(tournament.organizationId),
|
||||
)
|
||||
.map(tournamentToSidebarEvent)
|
||||
.sort((a, b) => a.startTime - b.startTime);
|
||||
|
||||
return { registered, hosting, scrims, saved, organization };
|
||||
};
|
||||
|
||||
@@ -6,3 +6,7 @@
|
||||
gap: var(--s-2);
|
||||
margin-block-end: var(--s-2);
|
||||
}
|
||||
|
||||
.subNav {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,13 @@ export const handle: SendouRouteHandle = {
|
||||
i18n: ["calendar"],
|
||||
};
|
||||
|
||||
const VIEW_FILTERS = ["registered", "hosting", "scrims", "saved"] as const;
|
||||
const VIEW_FILTERS = [
|
||||
"registered",
|
||||
"hosting",
|
||||
"scrims",
|
||||
"saved",
|
||||
"organization",
|
||||
] as const;
|
||||
type ViewFilter = (typeof VIEW_FILTERS)[number];
|
||||
|
||||
export default function EventsPage() {
|
||||
@@ -33,29 +39,19 @@ export default function EventsPage() {
|
||||
hosting: `${t("calendar:events.view.hosting")} (${data.hosting.length})`,
|
||||
scrims: `${t("calendar:events.view.scrims")} (${data.scrims.length})`,
|
||||
saved: `${t("calendar:events.view.saved")} (${data.saved.length})`,
|
||||
organization: `${t("calendar:events.view.organization")} (${data.organization.length})`,
|
||||
};
|
||||
|
||||
const shownEvents =
|
||||
filter === "registered"
|
||||
? data.registered
|
||||
: filter === "hosting"
|
||||
? data.hosting
|
||||
: filter === "saved"
|
||||
? data.saved
|
||||
: data.scrims;
|
||||
const shownEvents = data[filter];
|
||||
|
||||
const hasNoEventsAtAll =
|
||||
data.registered.length === 0 &&
|
||||
data.hosting.length === 0 &&
|
||||
data.scrims.length === 0 &&
|
||||
data.saved.length === 0;
|
||||
const hasNoEventsAtAll = VIEW_FILTERS.every((key) => data[key].length === 0);
|
||||
|
||||
return (
|
||||
<Main halfWidth>
|
||||
<div className={styles.eventsListHeader}>
|
||||
<h2 className="text-lg mx-2">{t("calendar:events.title")}</h2>
|
||||
{hasNoEventsAtAll ? null : (
|
||||
<SubNav secondary>
|
||||
<SubNav secondary className={styles.subNav}>
|
||||
{VIEW_FILTERS.map((value) => (
|
||||
<SubNavLink
|
||||
key={value}
|
||||
|
||||
@@ -275,10 +275,6 @@ async function tournamentsToParticipationInfoMap(
|
||||
addToMap(userId, tournament.id, "organizer");
|
||||
}
|
||||
|
||||
for (const { userId } of tournament.organizationMembers) {
|
||||
addToMap(userId, tournament.id, "organizer");
|
||||
}
|
||||
|
||||
addToMap(tournament.authorId, tournament.id, "organizer");
|
||||
}
|
||||
|
||||
@@ -304,6 +300,7 @@ function mapTournamentFromDB(
|
||||
url: tournamentPage(tournament.id),
|
||||
id: tournament.id,
|
||||
authorId: tournament.authorId,
|
||||
organizationId: tournament.organizationId,
|
||||
name: tournament.name,
|
||||
startTime: tournament.startTime,
|
||||
teamsCount: tournament.teamsCount,
|
||||
|
||||
@@ -465,25 +465,6 @@ export function relatedUsersByTournamentIds(tournamentIds: number[]) {
|
||||
.whereRef("TournamentStaff.tournamentId", "=", "Tournament.id")
|
||||
.where("TournamentStaff.role", "=", "ORGANIZER"),
|
||||
).as("staff"),
|
||||
jsonArrayFrom(
|
||||
eb
|
||||
.selectFrom("TournamentOrganization")
|
||||
.innerJoin(
|
||||
"TournamentOrganizationMember",
|
||||
"TournamentOrganization.id",
|
||||
"TournamentOrganizationMember.organizationId",
|
||||
)
|
||||
.select(["TournamentOrganizationMember.userId"])
|
||||
.whereRef(
|
||||
"TournamentOrganization.id",
|
||||
"=",
|
||||
"CalendarEvent.organizationId",
|
||||
)
|
||||
.where("TournamentOrganizationMember.role", "in", [
|
||||
"ADMIN",
|
||||
"ORGANIZER",
|
||||
]),
|
||||
).as("organizationMembers"),
|
||||
jsonArrayFrom(
|
||||
eb
|
||||
.selectFrom("TournamentTeam")
|
||||
@@ -499,7 +480,6 @@ export function relatedUsersByTournamentIds(tournamentIds: number[]) {
|
||||
.where("Tournament.id", "in", tournamentIds)
|
||||
.$narrowType<{
|
||||
staff: NotNull;
|
||||
organizationMembers: NotNull;
|
||||
teamMembers: NotNull;
|
||||
}>()
|
||||
.execute();
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"events.view.hosting": "Hosting",
|
||||
"events.view.scrims": "Scrims",
|
||||
"events.view.saved": "Saved",
|
||||
"events.view.organization": "Organization",
|
||||
"events.empty": "No events in this category",
|
||||
"events.emptyAll": "You have no upcoming events.",
|
||||
"events.findOnCalendar": "Find an event to join on the calendar!"
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
"events.view.hosting": "",
|
||||
"events.view.scrims": "",
|
||||
"events.view.saved": "",
|
||||
"events.view.organization": "",
|
||||
"events.empty": "",
|
||||
"events.emptyAll": "",
|
||||
"events.findOnCalendar": ""
|
||||
|
||||
Reference in New Issue
Block a user