Add pagination to events page (#1689)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Luke Vella 2025-04-24 15:30:30 +01:00 committed by GitHub
parent 9adebe496b
commit 8d2e5f8359
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 82 additions and 41 deletions

View file

@ -16,6 +16,7 @@ import {
EmptyStateIcon,
EmptyStateTitle,
} from "@/components/empty-state";
import { Pagination } from "@/components/pagination";
import { StackedList, StackedListItem } from "@/components/stacked-list";
import { Trans } from "@/components/trans";
import { getScheduledEvents } from "@/features/scheduled-event/api/get-scheduled-events";
@ -30,17 +31,22 @@ import { EventsTabbedView } from "./events-tabbed-view";
async function loadData({
status,
search,
page = 1,
pageSize = 10,
}: {
status: Status;
search?: string;
page?: number;
pageSize?: number;
}) {
const { userId } = await requireUser();
const scheduledEvents = await getScheduledEvents({
return getScheduledEvents({
userId,
status,
search,
page,
pageSize,
});
return scheduledEvents;
}
async function ScheduledEventEmptyState({ status }: { status: Status }) {
@ -98,11 +104,24 @@ export default async function Page({
searchParams,
}: {
params: Params;
searchParams?: { status: string; q?: string };
searchParams?: { status: string; q?: string; page?: string };
}) {
const { t } = await getTranslation(params.locale);
const status = statusSchema.catch("upcoming").parse(searchParams?.status);
const scheduledEvents = await loadData({ status, search: searchParams?.q });
const pageParam = searchParams?.page;
const page = pageParam ? Math.max(1, Number(pageParam) || 1) : 1;
const pageSize = 10;
const {
events: paginatedEvents,
totalCount,
totalPages,
} = await loadData({
status,
search: searchParams?.q,
page,
pageSize,
});
return (
<PageContainer>
@ -127,12 +146,12 @@ export default async function Page({
})}
/>
<div className="space-y-6">
{scheduledEvents.length === 0 && (
{paginatedEvents.length === 0 && (
<ScheduledEventEmptyState status={status} />
)}
{scheduledEvents.length > 0 && (
{paginatedEvents.length > 0 && (
<StackedList>
{scheduledEvents.map((event) => (
{paginatedEvents.map((event) => (
<StackedListItem key={event.id}>
<ScheduledEventListItem
eventId={event.id}
@ -149,6 +168,14 @@ export default async function Page({
))}
</StackedList>
)}
{totalPages > 1 && (
<Pagination
currentPage={page}
totalPages={totalPages}
totalItems={totalCount}
pageSize={pageSize}
/>
)}
</div>
</div>
</EventsTabbedView>

View file

@ -1,3 +1,4 @@
import type { Prisma } from "@rallly/database";
import { prisma } from "@rallly/database";
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
@ -19,22 +20,29 @@ export async function getScheduledEvents({
userId,
status,
search,
page = 1,
pageSize = 10,
}: {
userId: string;
status: Status;
search?: string;
page?: number;
pageSize?: number;
}) {
const now = new Date();
const rawEvents = await prisma.scheduledEvent.findMany({
where: {
const where: Prisma.ScheduledEventWhereInput = {
userId,
deletedAt: null,
...(status != "past" && { start: { gte: now } }),
...(status === "past" && { start: { lt: now } }),
...(search && { title: { contains: search, mode: "insensitive" } }),
status: mapStatus[status],
},
};
const [rawEvents, totalCount] = await Promise.all([
prisma.scheduledEvent.findMany({
where,
orderBy: {
start: status === "past" ? "desc" : "asc",
},
@ -60,14 +68,17 @@ export async function getScheduledEvents({
},
},
},
});
skip: (page - 1) * pageSize,
take: pageSize,
}),
prisma.scheduledEvent.count({ where }),
]);
const events = rawEvents.map((event) => ({
...event,
status:
event.status === "confirmed"
? // If the event is confirmed, it's either past or upcoming
((event.start < now ? "past" : "upcoming") as Status)
? ((event.start < now ? "past" : "upcoming") as Status)
: event.status,
invites: event.invites.map((invite) => ({
id: invite.id,
@ -76,5 +87,8 @@ export async function getScheduledEvents({
})),
}));
return events;
const totalPages = Math.ceil(totalCount / pageSize);
const hasNextPage = page * pageSize < totalCount;
return { events, totalCount, totalPages, hasNextPage };
}