Skip to content

Commit

Permalink
feat: use tabs on event detail page; fix TypeScript issues with Disco…
Browse files Browse the repository at this point in the history
…rd; move event components
  • Loading branch information
simonknittel committed Dec 23, 2024
1 parent d0aed46 commit 302fd2f
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 71 deletions.
43 changes: 35 additions & 8 deletions app/src/app/app/events/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { authenticatePage } from "@/auth/server";
import Tab from "@/common/components/tabs/Tab";
import TabList from "@/common/components/tabs/TabList";
import TabPanel from "@/common/components/tabs/TabPanel";
import { TabsProvider } from "@/common/components/tabs/TabsContext";
import type { NextjsSearchParams } from "@/common/utils/searchParamsNextjsToURLSearchParams";
import searchParamsNextjsToURLSearchParams from "@/common/utils/searchParamsNextjsToURLSearchParams";
import { getEvent } from "@/discord/getEvent";
import { FleetTile } from "@/events/components/FleetTile";
import { OverviewTile } from "@/events/components/OverviewTile";
import { ParticipantsTile } from "@/events/components/ParticipantsTile";
import { log } from "@/logging";
import { type Metadata } from "next";
import { FaUsers } from "react-icons/fa";
import { MdWorkspaces } from "react-icons/md";
import { serializeError } from "serialize-error";
import { FleetTile } from "./_components/FleetTile";
import { OverviewTile } from "./_components/OverviewTile";
import { ParticipantsTile } from "./_components/ParticipantsTile";

interface Params {
id: string;
Expand Down Expand Up @@ -60,11 +66,32 @@ export default async function Page({ params, searchParams }: Props) {
</div>

<div className="flex gap-8 flex-col-reverse 2xl:flex-row 2xl:items-start">
<div className="flex flex-col gap-4 2xl:flex-1">
<ParticipantsTile event={event} />
{showFleetTile && (
<FleetTile event={event} urlSearchParams={urlSearchParams} />
)}
<div className="2xl:flex-1">
<TabsProvider initialActiveTab="participants">
<TabList>
<Tab id="participants">
<FaUsers />
Teilnehmer ({event.user_count})
</Tab>

{showFleetTile && (
<Tab id="fleet">
<MdWorkspaces />
Flotte
</Tab>
)}
</TabList>

<TabPanel id="participants">
<ParticipantsTile event={event} />
</TabPanel>

{showFleetTile && (
<TabPanel id="fleet">
<FleetTile event={event} urlSearchParams={urlSearchParams} />
</TabPanel>
)}
</TabsProvider>
</div>

<OverviewTile
Expand Down
2 changes: 0 additions & 2 deletions app/src/app/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ export default async function Page({ searchParams }: Props) {
const authentication = await authenticatePage("/app");

const showCalendar = authentication.authorize("event", "read");

const showSpynetSearchTile =
!(await dedupedGetUnleashFlag("DisableAlgolia")) &&
(authentication.authorize("citizen", "read") ||
authentication.authorize("organization", "read"));

const showUwuHero = Object.hasOwn(searchParams, "uwu");

return (
Expand Down
35 changes: 19 additions & 16 deletions app/src/discord/getEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,25 @@ export const getEvent = cache(async (id: string) => {

checkResponseForError(data);

return { date: response.headers.get("Date"), data };
return {
date: response.headers.get("Date"),
data: data as z.infer<typeof successSchema>,
};
});

const responseSchema = z.union([
z.object({
id: z.string(),
guild_id: z.string(),
name: z.string(),
image: z.string().optional().nullable(),
scheduled_start_time: z.coerce.date(),
scheduled_end_time: z.coerce.date(),
user_count: z.number(),
description: z.string().optional(),
}),
const successSchema = z.object({
id: z.string(),
guild_id: z.string(),
name: z.string(),
image: z.string().optional().nullable(),
scheduled_start_time: z.coerce.date(),
scheduled_end_time: z.coerce.date(),
user_count: z.number(),
description: z.string().optional(),
});

const errorSchema = z.object({
message: z.string(),
});

z.object({
message: z.string(),
}),
]);
const responseSchema = z.union([successSchema, errorSchema]);
38 changes: 19 additions & 19 deletions app/src/discord/getEventUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ export const getEventUsersDeduped = cache(async (id: string) => {

checkResponseForError(data);

return data;
return data as z.infer<typeof successSchema>;
});

const schema = z.union([
z.array(
z.object({
user: z.object({
id: z.string(),
username: z.string(),
global_name: z.string().optional().nullable(),
avatar: z.string().optional().nullable(),
}),
member: z.object({
nick: z.string().optional().nullable(),
avatar: z.string().optional().nullable(),
}),
}),
),

const successSchema = z.array(
z.object({
message: z.string(),
user: z.object({
id: z.string(),
username: z.string(),
global_name: z.string().optional().nullable(),
avatar: z.string().optional().nullable(),
}),
member: z.object({
nick: z.string().optional().nullable(),
avatar: z.string().optional().nullable(),
}),
}),
]);
);

const errorSchema = z.object({
message: z.string(),
});

const schema = z.union([successSchema, errorSchema]);
35 changes: 19 additions & 16 deletions app/src/discord/getEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,26 @@ export const getEvents = cache(async () => {

checkResponseForError(data);

return { date: response.headers.get("Date"), data };
return {
date: response.headers.get("Date"),
data: data as z.infer<typeof successSchema>,
};
});

const responseSchema = z.union([
z.array(
z.object({
id: z.string(),
guild_id: z.string(),
name: z.string(),
image: z.string().optional().nullable(),
scheduled_start_time: z.coerce.date(),
scheduled_end_time: z.coerce.date(),
user_count: z.number(),
}),
),

const successSchema = z.array(
z.object({
message: z.string(),
id: z.string(),
guild_id: z.string(),
name: z.string(),
image: z.string().optional().nullable(),
scheduled_start_time: z.coerce.date(),
scheduled_end_time: z.coerce.date(),
user_count: z.number(),
}),
]);
);

const errorSchema = z.object({
message: z.string(),
});

const responseSchema = z.union([successSchema, errorSchema]);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { FleetTable } from "@/fleet/components/FleetTable";
import { VariantStatus } from "@prisma/client";
import clsx from "clsx";
import { groupBy } from "lodash";
import { MdWorkspaces } from "react-icons/md";

type Props = Readonly<{
className?: string;
Expand Down Expand Up @@ -73,9 +72,7 @@ export const FleetTile = async ({
gridArea: "fleet",
}}
>
<h2 className="font-bold mb-4 flex gap-2 items-center">
<MdWorkspaces /> Flotte
</h2>
<h2 className="sr-only">Flotte</h2>

{countedOrgShips.length > 0 ? (
<>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getEventUsersDeduped } from "@/discord/getEventUsers";
import clsx from "clsx";
import Image from "next/image";
import Link from "next/link";
import { FaExternalLinkAlt, FaUsers } from "react-icons/fa";
import { FaExternalLinkAlt } from "react-icons/fa";

type Props = Readonly<{
className?: string;
Expand Down Expand Up @@ -54,13 +54,10 @@ export const ParticipantsTile = async ({ className, event }: Props) => {
"rounded-2xl bg-neutral-800/50 p-4 lg:p-8 overflow-auto",
)}
>
<h2 className="font-bold flex gap-2 items-center">
<FaUsers />
Teilnehmer ({event.user_count})
</h2>
<h2 className="sr-only">Teilnehmer ({event.user_count})</h2>

{resolvedUsers.length > 0 ? (
<div className="flex gap-2 flex-wrap mt-4">
<div className="flex gap-2 flex-wrap">
{resolvedUsers.map((resolvedUser) => (
<div
key={resolvedUser.discord.user.id}
Expand Down

0 comments on commit 302fd2f

Please sign in to comment.