Skip to content

Commit

Permalink
feat: show all events on 1 page and improve query time ⚡️ (#680)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramiAbdou authored Dec 13, 2024
1 parent f80fd35 commit ce0b8ef
Show file tree
Hide file tree
Showing 44 changed files with 1,055 additions and 1,151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { Form, useActionData, useLoaderData } from '@remix-run/react';

import {
addEventRecordingLink,
AddEventRecordingLinkInput,
getEvent,
} from '@oyster/core/admin-dashboard/server';
import { AddEventRecordingLinkInput } from '@oyster/core/admin-dashboard/ui';
} from '@oyster/core/events';
import {
Button,
ErrorMessage,
Expand Down Expand Up @@ -83,8 +83,6 @@ export default function AddEventRecordingModal() {
);
}

const keys = AddEventRecordingLinkInput.keyof().enum;

function AddEventRecordingForm() {
const { event } = useLoaderData<typeof loader>();
const { error, errors } = getErrors(useActionData<typeof action>());
Expand All @@ -95,13 +93,13 @@ function AddEventRecordingForm() {
description="Please add the full URL of the event recording."
error={errors.recordingLink}
label="Recording Link"
labelFor={keys.recordingLink}
labelFor="recordingLink"
required
>
<Input
defaultValue={event.recordingLink || undefined}
id={keys.recordingLink}
name={keys.recordingLink}
id="recordingLink"
name="recordingLink"
placeholder="https://www.youtube.com/watch?v=..."
required
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { json, type LoaderFunctionArgs } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import QRCode from 'qrcode';

import { getEvent } from '@oyster/core/admin-dashboard/server';
import { getEvent } from '@oyster/core/events';
import { Modal } from '@oyster/ui';

import { Route } from '@/shared/constants';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '@remix-run/node';
import { Form, useActionData, useLoaderData } from '@remix-run/react';

import { getEvent } from '@oyster/core/admin-dashboard/server';
import { getEvent } from '@oyster/core/events';
import { deleteEvent } from '@oyster/core/events';
import { Button, ErrorMessage, getErrors, Modal } from '@oyster/ui';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import {
import { Form, useActionData, useLoaderData } from '@remix-run/react';
import { z } from 'zod';

import { getEvent, parseCsv } from '@oyster/core/admin-dashboard/server';
import { parseCsv } from '@oyster/core/admin-dashboard/server';
import { job } from '@oyster/core/bull';
import { getEvent } from '@oyster/core/events';
import { db } from '@oyster/db';
import { Email, EventAttendee } from '@oyster/types';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { Form, useActionData } from '@remix-run/react';
import { z } from 'zod';

import { createEvent } from '@oyster/core/admin-dashboard/server';
import { createEvent } from '@oyster/core/events';
import { Event, EventType } from '@oyster/types';
import {
Button,
Expand Down
2 changes: 1 addition & 1 deletion apps/admin-dashboard/app/routes/_dashboard.events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { useState } from 'react';
import { Camera, Menu, Plus, RefreshCw, Trash2, Upload } from 'react-feather';
import { generatePath } from 'react-router';

import { listEvents } from '@oyster/core/admin-dashboard/server';
import { ListSearchParams } from '@oyster/core/admin-dashboard/ui';
import { listEvents } from '@oyster/core/events';
import { type Event, EventType } from '@oyster/types';
import {
Dashboard,
Expand Down
6 changes: 2 additions & 4 deletions apps/member-profile/app/routes/_profile.directory_.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import React, { type PropsWithChildren } from 'react';
import { BookOpen, Calendar, Globe, Home, Link, MapPin } from 'react-feather';

import { job } from '@oyster/core/bull';
import { countEventAttendees } from '@oyster/core/events/attendees';
import { getTotalPoints } from '@oyster/core/gamification';
import {
countEventAttendees,
countMessagesSent,
getActiveStreak,
getIcebreakerResponses,
Expand Down Expand Up @@ -48,9 +48,7 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
] = await Promise.all([
getActiveStreak(memberId),
getEducationExperiences(memberId),
countEventAttendees({
where: { studentId: memberId },
}),
countEventAttendees({ studentId: memberId }),
getIcebreakerResponses(memberId, [
'icebreakerResponses.promptId',
'icebreakerResponses.text',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { generatePath, Link, useLoaderData } from '@remix-run/react';
import {
countEventAttendees,
listEventAttendees,
} from '@oyster/core/member-profile/server';
} from '@oyster/core/events/attendees';
import { type Student } from '@oyster/types';
import { Modal, ProfilePicture } from '@oyster/ui';

Expand All @@ -14,19 +14,8 @@ export async function loader({ params }: LoaderFunctionArgs) {
const eventId = params.id as string;

const [attendees, attendeesCount] = await Promise.all([
listEventAttendees({
select: [
'students.firstName',
'students.id',
'students.lastName',
'students.preferredName',
'students.profilePicture',
],
where: { eventId },
}),
countEventAttendees({
where: { eventId },
}),
listEventAttendees({ eventId }),
countEventAttendees({ eventId }),
]);

return json({
Expand All @@ -39,7 +28,7 @@ export default function EventAttendeesPage() {
const { attendees, attendeesCount } = useLoaderData<typeof loader>();

return (
<Modal onCloseTo={Route['/events/past']}>
<Modal onCloseTo={Route['/events']}>
<Modal.Header>
<Modal.Title>Attendees List ({attendeesCount})</Modal.Title>
<Modal.CloseButton />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
import { Form, useActionData, useLoaderData } from '@remix-run/react';
import { Check } from 'react-feather';

import { checkIntoEvent } from '@oyster/core/events';
import { getEvent } from '@oyster/core/member-profile/server';
import { getEvent } from '@oyster/core/events';
import { checkIntoEvent } from '@oyster/core/events/attendees';
import { Button, Modal } from '@oyster/ui';

import { Route } from '@/shared/constants';
Expand Down Expand Up @@ -72,7 +72,7 @@ export default function EventCheckIn() {
const isCheckedIn = event.isCheckedIn || actionData?.checkedIn;

return (
<Modal onCloseTo={Route['/events/upcoming']} size="400">
<Modal onCloseTo={Route['/events']} size="400">
<Modal.Header>
<Modal.Title>{event.name}: Check In! 👋</Modal.Title>
<Modal.CloseButton />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import {
import { Form, useLoaderData } from '@remix-run/react';
import { Calendar, Check, ExternalLink } from 'react-feather';

import { job } from '@oyster/core/bull';
import { getEvent } from '@oyster/core/member-profile/server';
import { db } from '@oyster/db';
import { formatEventDate, getEvent } from '@oyster/core/events';
import { registerForEvent } from '@oyster/core/events/registrations';
import { Button, Modal, Text } from '@oyster/ui';

import { formatEventDate } from '@/shared/components/event';
import { Route } from '@/shared/constants';
import { getTimezone } from '@/shared/cookies.server';
import {
Expand Down Expand Up @@ -65,11 +63,15 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
export async function action({ params, request }: ActionFunctionArgs) {
const session = await ensureUserAuthenticated(request);

await registerForEvent({
const result = await registerForEvent({
eventId: params.id as string,
studentId: user(session),
});

if (!result.ok) {
return json({ error: result.error }, { status: result.code });
}

toast(session, {
message: 'Registered!',
});
Expand All @@ -81,41 +83,11 @@ export async function action({ params, request }: ActionFunctionArgs) {
});
}

async function registerForEvent({
eventId,
studentId,
}: {
eventId: string;
studentId: string;
}) {
const student = await db
.selectFrom('students')
.select(['email'])
.where('id', '=', studentId)
.executeTakeFirstOrThrow();

await db
.insertInto('eventRegistrations')
.values({
email: student.email,
eventId,
registeredAt: new Date(),
studentId,
})
.onConflict((oc) => oc.doNothing())
.execute();

job('event.register', {
eventId,
studentId,
});
}

export default function EventRegisterPage() {
const { event } = useLoaderData<typeof loader>();

return (
<Modal onCloseTo={Route['/events/upcoming']}>
<Modal onCloseTo={Route['/events']}>
<Modal.Header>
<Modal.Title>{event.name}</Modal.Title>
<Modal.CloseButton />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,25 @@
import { json, type LoaderFunctionArgs } from '@remix-run/node';
import { generatePath, Link, useLoaderData } from '@remix-run/react';

import { db } from '@oyster/db';
import { listEventRegistrations } from '@oyster/core/events/registrations';
import { type Student } from '@oyster/types';
import { Modal, ProfilePicture } from '@oyster/ui';

import { Route } from '@/shared/constants';

export async function loader({ params }: LoaderFunctionArgs) {
const registrations = await getEventRegistrations(params.id as string);
const registrations = await listEventRegistrations(params.id as string);

return json({
registrations,
});
}

async function getEventRegistrations(eventId: string) {
const registrations = await db
.selectFrom('eventRegistrations')
.leftJoin('students', 'students.id', 'eventRegistrations.studentId')
.select([
'students.firstName',
'students.id',
'students.lastName',
'students.preferredName',
'students.profilePicture',
])
.where('eventRegistrations.eventId', '=', eventId)
.orderBy('eventRegistrations.registeredAt', 'desc')
.execute();

return registrations;
}

export default function EventRegistrationsPage() {
const { registrations } = useLoaderData<typeof loader>();

return (
<Modal onCloseTo={Route['/events/upcoming']}>
<Modal onCloseTo={Route['/events']}>
<Modal.Header>
<Modal.Title>Guest List ({registrations.length})</Modal.Title>
<Modal.CloseButton />
Expand Down
10 changes: 0 additions & 10 deletions apps/member-profile/app/routes/_profile.events._index.tsx

This file was deleted.

Loading

0 comments on commit ce0b8ef

Please sign in to comment.