Skip to content

Commit

Permalink
Move attendees and registration out of EventDetail page file
Browse files Browse the repository at this point in the history
  • Loading branch information
eikhr committed Sep 22, 2024
1 parent b2f4762 commit e5bc9d3
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 92 deletions.
8 changes: 3 additions & 5 deletions app/components/UserAttendance/Attendance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import AttendanceStatus from 'app/components/UserAttendance/AttendanceStatus';
import UserGrid from 'app/components/UserGrid';
import { useIsLoggedIn } from 'app/reducers/auth';
import RegisteredSummary from 'app/routes/events/components/RegisteredSummary';
import type {
Pool,
Registration,
} from 'app/components/UserAttendance/AttendanceModalContent';
import type { Pool } from 'app/components/UserAttendance/AttendanceModalContent';
import type { SummaryRegistration } from 'app/routes/events/components/RegisteredSummary';
import type { PaymentRegistration } from 'app/store/models/Registration';

type Props = {
pools: Pool[];
registrations?: SummaryRegistration[];
currentRegistration?: Registration;
currentRegistration?: PaymentRegistration;
minUserGridRows?: number;
maxUserGridRows?: number;
isMeeting?: boolean;
Expand Down
82 changes: 82 additions & 0 deletions app/routes/events/components/EventDetail/AttendeeSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Flex } from '@webkom/lego-bricks';
import moment from 'moment-timezone';
import Attendance from 'app/components/UserAttendance/Attendance';
import { useIsLoggedIn } from 'app/reducers/auth';
import { selectRegistrationsFromPools } from 'app/reducers/events';
import RegistrationMeta from 'app/routes/events/components/RegistrationMeta';
import { getEventSemesterFromStartTime } from 'app/routes/events/utils';
import { useAppSelector } from 'app/store/hooks';
import type { UserDetailedEvent } from 'app/store/models/Event';
import type {
PaymentRegistration,
ReadRegistration,
} from 'app/store/models/Registration';

const MIN_USER_GRID_ROWS = 2;
const MAX_USER_GRID_ROWS = 2;

interface Props {
showSkeleton: boolean;
event: UserDetailedEvent;
currentRegistration?: PaymentRegistration;
pools: any;
currentPool: any;
}

export const AttendeeSection = ({
showSkeleton,
event,
currentRegistration,
pools,
currentPool,
}: Props) => {
const loggedIn = useIsLoggedIn();
const fetching = useAppSelector((state) => state.events.fetching);
const registrations: ReadRegistration[] | undefined = useAppSelector(
(state) => selectRegistrationsFromPools(state, { eventId: event.id }),
);

const currentMoment = moment();
const hasSimpleWaitingList =
pools.filter((p) => p.name != 'Venteliste').length <= 1;
const waitingListIndex =
currentPool?.registrations.indexOf(currentRegistration);

// The UserGrid is expanded when there's less than 5 minutes till activation
const minUserGridRows = currentMoment.isAfter(
moment(event.activationTime).subtract(5, 'minutes'),
)
? MIN_USER_GRID_ROWS
: 0;

return (
<Flex column>
<h3>Påmeldte</h3>

<Attendance
pools={pools}
registrations={registrations}
currentRegistration={currentRegistration}
minUserGridRows={minUserGridRows}
maxUserGridRows={MAX_USER_GRID_ROWS}
legacyRegistrationCount={event.legacyRegistrationCount}
skeleton={fetching && !registrations}
/>

{loggedIn && (
<RegistrationMeta
useConsent={event.useConsent}
hasOpened={moment(event.activationTime).isBefore(currentMoment)}
photoConsents={event.photoConsents}
eventSemester={getEventSemesterFromStartTime(event.startTime)}
hasEnded={moment(event.endTime).isBefore(currentMoment)}
registration={currentRegistration}
isPriced={event.isPriced}
registrationIndex={waitingListIndex}
hasSimpleWaitingList={hasSimpleWaitingList}
skeleton={showSkeleton}
/>
)}
</Flex>
);
};
28 changes: 28 additions & 0 deletions app/routes/events/components/EventDetail/UnansweredSurveys.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Card } from '@webkom/lego-bricks';
import { Link } from 'react-router-dom';
import type { AuthUserDetailedEvent } from 'app/store/models/Event';
import type { ReadRegistration } from 'app/store/models/Registration';

interface Props {
event: AuthUserDetailedEvent;
currentRegistration: ReadRegistration | null;
}

export const UnansweredSurveys = ({ event, currentRegistration }: Props) => {
return (
<Card severity="danger">
<p>
Du kan ikke melde deg {currentRegistration ? 'av' : 'på'} dette
arrangementet fordi du har ubesvarte spørreundersøkelser. Gå til lenkene
under for å svare:
</p>
<ul>
{event.unansweredSurveys.map((surveyId, i) => (
<li key={surveyId}>
<Link to={`/surveys/${surveyId}`}>Undersøkelse {i + 1}</Link>
</li>
))}
</ul>
</Card>
);
};
96 changes: 18 additions & 78 deletions app/routes/events/components/EventDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, Flex, Page, Skeleton } from '@webkom/lego-bricks';
import { Flex, Page, Skeleton } from '@webkom/lego-bricks';
import { usePreparedEffect } from '@webkom/react-prepare';
import { isEmpty } from 'lodash';
import { CircleHelp, FilePenLine } from 'lucide-react';
Expand All @@ -19,7 +19,6 @@ import Tag from 'app/components/Tags/Tag';
import TextWithIcon from 'app/components/TextWithIcon';
import { FormatTime } from 'app/components/Time';
import Tooltip from 'app/components/Tooltip';
import Attendance from 'app/components/UserAttendance/Attendance';
import config from 'app/config';
import { useCurrentUser, useIsLoggedIn } from 'app/reducers/auth';
import {
Expand All @@ -30,36 +29,31 @@ import {
selectPoolsForEvent,
selectPoolsWithRegistrationsForEvent,
selectRegistrationForEventByUserId,
selectRegistrationsFromPools,
selectWaitingRegistrationsForEvent,
} from 'app/reducers/events';
import { resolveGroupLink } from 'app/reducers/groups';
import { selectPenaltyByUserId } from 'app/reducers/penalties';
import { selectUserWithGroups } from 'app/reducers/users';
import { AttendeeSection } from 'app/routes/events/components/EventDetail/AttendeeSection';
import { InterestedButton } from 'app/routes/events/components/EventDetail/InterestedButton';
import { SidebarInfo } from 'app/routes/events/components/EventDetail/SidebarInfo';
import { UnansweredSurveys } from 'app/routes/events/components/EventDetail/UnansweredSurveys';
import {
colorForEventType,
penaltyHours,
getEventSemesterFromStartTime,
registrationCloseTime,
displayNameForEventType,
} from 'app/routes/events/utils';
import YoutubeCover from 'app/routes/pages/components/YoutubeCover';
import { useAppDispatch, useAppSelector } from 'app/store/hooks';
import Admin from '../Admin';
import JoinEventForm from '../JoinEventForm';
import RegistrationMeta from '../RegistrationMeta';
import styles from './EventDetail.css';
import type { PropertyGenerator } from 'app/components/PropertyHelmet';
import type {
AuthUserDetailedEvent,
UserDetailedEvent,
} from 'app/store/models/Event';
import type { ReadRegistration } from 'app/store/models/Registration';

const MIN_USER_GRID_ROWS = 2;
const MAX_USER_GRID_ROWS = 2;

const Line = () => <div className={styles.line} />;

Expand Down Expand Up @@ -115,7 +109,7 @@ const EventDetail = () => {
const fetching = useAppSelector((state) => state.events.fetching);
const showSkeleton = fetching && isEmpty(event);
const actionGrant = event?.actionGrant || [];
const hasFullAccess = Boolean(event?.waitingRegistrations);
const hasFullAccess = Boolean('waitingRegistrations' in event);

const loggedIn = useIsLoggedIn();
const currentUser = useCurrentUser();
Expand All @@ -136,9 +130,6 @@ const EventDetail = () => {
? selectMergedPoolWithRegistrations(state, { eventId })
: selectPoolsWithRegistrationsForEvent(state, { eventId }),
);
const registrations: ReadRegistration[] | undefined = useAppSelector(
(state) => selectRegistrationsFromPools(state, { eventId }),
);
const waitingRegistrations = useAppSelector((state) =>
selectWaitingRegistrationsForEvent(state, { eventId }),
);
Expand Down Expand Up @@ -175,17 +166,10 @@ const EventDetail = () => {
),
);

let currentRegistration;
let currentRegistrationIndex;

if (currentPool) {
currentRegistrationIndex = currentPool.registrations.findIndex(
(registration) => registration.user?.id === currentUser?.id,
);
currentRegistration = currentPool.registrations[currentRegistrationIndex];
}
const currentRegistration = currentPool?.registrations.find(
(registration) => registration.user?.id === currentUser?.id,
);

const hasSimpleWaitingList = poolsWithRegistrations.length <= 1;
const pendingRegistration = useAppSelector(
(state) =>
currentUser &&
Expand Down Expand Up @@ -225,13 +209,6 @@ const EventDetail = () => {

const registrationCloseTimeMoment = registrationCloseTime(event);

// The UserGrid is expanded when there's less than 5 minutes till activation
const minUserGridRows = currentMoment.isAfter(
moment(activationTimeMoment).subtract(5, 'minutes'),
)
? MIN_USER_GRID_ROWS
: 0;

const deadlines = [
event.activationTime && currentMoment.isBefore(activationTimeMoment)
? {
Expand Down Expand Up @@ -436,58 +413,21 @@ const EventDetail = () => {
<JoinEventForm event={event} />
) : (
<>
<Flex column>
<h3>Påmeldte</h3>

<Attendance
pools={pools}
registrations={registrations}
currentRegistration={currentRegistration}
minUserGridRows={minUserGridRows}
maxUserGridRows={MAX_USER_GRID_ROWS}
legacyRegistrationCount={event.legacyRegistrationCount}
skeleton={fetching && !registrations}
/>

{loggedIn && (
<RegistrationMeta
useConsent={event.useConsent}
hasOpened={moment(event.activationTime).isBefore(
currentMoment,
)}
photoConsents={event.photoConsents}
eventSemester={getEventSemesterFromStartTime(
event.startTime,
)}
hasEnded={moment(event.endTime).isBefore(currentMoment)}
registration={currentRegistration}
isPriced={event.isPriced}
registrationIndex={currentRegistrationIndex}
hasSimpleWaitingList={hasSimpleWaitingList}
skeleton={showSkeleton}
/>
)}
</Flex>
<AttendeeSection
showSkeleton={showSkeleton}
event={event}
currentRegistration={currentRegistration}
pools={pools}
currentPool={currentPool}
/>

{'unansweredSurveys' in event &&
event.unansweredSurveys?.length > 0 &&
!event.isAdmitted ? (
<Card severity="danger">
<p>
Du kan ikke melde deg {currentRegistration ? 'av' : 'på'}{' '}
dette arrangementet fordi du har ubesvarte
spørreundersøkelser. Gå til lenkene under for å svare:
</p>
<ul>
{event.unansweredSurveys.map((surveyId, i) => (
<li key={surveyId}>
<Link to={`/surveys/${surveyId}`}>
Undersøkelse {i + 1}
</Link>
</li>
))}
</ul>
</Card>
<UnansweredSurveys
event={event}
currentRegistration={currentRegistration}
/>
) : (
!showSkeleton && (
<JoinEventForm
Expand Down
11 changes: 7 additions & 4 deletions app/routes/events/components/RegistrationMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ import type {
PhotoConsent,
EventSemester,
} from 'app/models';
import type { Presence } from 'app/store/models/Registration';
import type {
PaymentRegistration,
Presence,
} from 'app/store/models/Registration';

type Props = {
registration: Record<string, any>;
registration?: PaymentRegistration;
isPriced: boolean;
registrationIndex: number;
hasSimpleWaitingList: boolean;
Expand All @@ -47,7 +50,7 @@ const ConsentStatus = ({
eventSemester,
}: {
useConsent: boolean;
LEGACY_photoConsent: LEGACY_EventRegistrationPhotoConsent;
LEGACY_photoConsent?: LEGACY_EventRegistrationPhotoConsent;
hasEnded: boolean;
photoConsents?: Array<PhotoConsent>;
eventSemester: EventSemester;
Expand Down Expand Up @@ -184,7 +187,7 @@ const PaymentStatus = ({
paymentStatus,
isPriced,
}: {
paymentStatus: EventRegistrationPaymentStatus;
paymentStatus?: EventRegistrationPaymentStatus | null;
isPriced: boolean;
}) => {
if (!isPriced) return null;
Expand Down
Loading

0 comments on commit e5bc9d3

Please sign in to comment.