Skip to content

Commit

Permalink
update prospect list to use tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
realmayus committed Oct 15, 2024
1 parent f12972a commit d1e7b7d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 67 deletions.
5 changes: 5 additions & 0 deletions src/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,11 @@
"cancel": "Abbrechen"
}
},
"prospectList": {
"toast": "Schüler wurde dem Kurs hinzugefügt.",
"error": "Schüler:in konnte nicht hinzugefügt werden.",
"noProspects": "Keine Interessent:innen."
},
"joinPupilModal": {
"header": "Schüler:innen nachrücken",
"add": "Hinzufügen",
Expand Down
15 changes: 11 additions & 4 deletions src/modals/AddPupilModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface AddPupilModalProps extends BaseModalProps {
subcourseId: number;
pupil?: PupilOnWaitinglist;
onPupilAdded: () => Promise<void>;
type: 'waitinglist' | 'prospectlist';
}
// type JoinPupilModalProps = {
// pupil: (SparseParticipant & { schooltype: string | undefined; gradeAsInt: number | undefined }) | undefined;
Expand All @@ -23,18 +24,24 @@ const ADD_PUPIL_FROM_WAITING_LIST_MUTATION = gql(`mutation JoinFromWaitinglist($
subcourseJoinFromWaitinglist(subcourseId: $subcourseId, pupilId: $pupilId)
}`);

const AddPupilModal = ({ isOpen, onOpenChange, subcourseId, pupil, onPupilAdded }: AddPupilModalProps) => {
const ADD_PUPIL_FROM_PROSPECT_LIST_MUTATION = gql(`mutation JoinFromProspectList($subcourseId: Float!, $pupilId: Float!) {
subcourseJoinFromProspects(subcourseId: $subcourseId, pupilId: $pupilId)
}`);

const AddPupilModal = ({ isOpen, onOpenChange, subcourseId, pupil, onPupilAdded, type }: AddPupilModalProps) => {
const { t } = useTranslation();
const [addPupil, { loading: isAdding }] = useMutation(ADD_PUPIL_FROM_WAITING_LIST_MUTATION);
const [addPupil, { loading: isAdding }] = useMutation(
type === 'waitinglist' ? ADD_PUPIL_FROM_WAITING_LIST_MUTATION : ADD_PUPIL_FROM_PROSPECT_LIST_MUTATION
);

const handleOnAddPupil = async () => {
if (!pupil) return;
try {
await addPupil({ variables: { subcourseId, pupilId: pupil.id } });
toast.success(t('single.waitinglist.toast'));
toast.success(t(type === 'waitinglist' ? 'single.waitinglist.toast' : 'single.prospectList.toast'));
if (onPupilAdded) await onPupilAdded();
} catch (error) {
toast.error(t('single.waitinglist.error'));
toast.error(t(type === 'waitinglist' ? 'single.waitinglist.error' : 'single.prospectList.error'));
} finally {
onOpenChange(false);
}
Expand Down
138 changes: 75 additions & 63 deletions src/pages/single-course/ProspectList.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,95 @@
import { Box, Button, Column, Heading, Modal, Row, Spacer, useBreakpointValue, useTheme, useToast } from 'native-base';
import AddCircleIcon from '../../assets/icons/ic_add_circle.svg';
import AddPupilModal from '../../modals/AddPupilModal';
import { ApolloQueryResult } from '@apollo/client';
import { useCallback, useState } from 'react';
import { SparseParticipant } from '../../gql/graphql';
import { ApolloQueryResult, useMutation } from '@apollo/client';
import { gql } from '../../gql';
import { LFPupilsOnWaitinglist, PupilOnWaitinglist, SparseParticipant } from '@/types/lernfair/Course';
import { useTranslation } from 'react-i18next';
import AddPupilModal from '@/modals/AddPupilModal';
import IncreaseMaxParticipantsModal from '@/modals/IncreaseMaxParticipantsModal';
import ParticipantRow from '../subcourse/ParticipantRow';
import { Button } from '@/components/Button';
import { Alert } from '@/components/Alert';
import { IconCircleCheckFilled } from '@tabler/icons-react';

type ProspectListProps = {
subcourseId: number;
prospects: SparseParticipant[];
maxParticipants: number;
refetch: () => Promise<ApolloQueryResult<any>>;
};
const ProspectList: React.FC<ProspectListProps> = ({ prospects, subcourseId, refetch }) => {
const { space } = useTheme();
const { t } = useTranslation();
const toast = useToast();
const [isFetching, setFetching] = useState(false);
const isMobile = useBreakpointValue({
base: true,
lg: false,
});

const ProspectList: React.FC<ProspectListProps> = ({ subcourseId, prospects, maxParticipants, refetch }) => {
const [isJoinPupilModalOpen, setIsJoinPupilModalOpen] = useState(false);
const [pupilToAdd, setPupilToAdd] = useState<undefined | SparseParticipant>();
const [isIncreaseMaxParticipantsModalOpen, setIsIncreaseMaxParticipantsModalOpen] = useState(false);
const [pupilToAdd, setPupilToAdd] = useState<PupilOnWaitinglist>();

const [addProspect] = useMutation(
gql(`mutation JoinProspect($subcourseId: Float!, $pupilId: Float!) {
subcourseJoinFromProspects(subcourseId: $subcourseId, pupilId: $pupilId)
}`)
);
const { t } = useTranslation();

const handleOpenModal = (prospect: SparseParticipant) => {
const handleOpenModal = (pupilOnWaitinglist: PupilOnWaitinglist) => {
setIsJoinPupilModalOpen(true);
setPupilToAdd(prospect);
setPupilToAdd(pupilOnWaitinglist);
};

const handleAddPupil = useCallback(
async (pupilId: number) => {
try {
setFetching(true);
await addProspect({ variables: { subcourseId: subcourseId, pupilId: pupilId } });
setIsJoinPupilModalOpen(false);
toast.show({ description: t('single.waitinglist.toast'), placement: 'top' });
await refetch();
} catch (error) {
toast.show({ description: t('single.waitinglist.error'), placement: 'top' });
} finally {
setFetching(false);
}
},
[addProspect, refetch, subcourseId]
);
const handleOnFinish = useCallback(async () => {
refetch();
}, [refetch]);

return (
<>
{prospects?.map((pupil) => {
return (
<>
<Box width={isMobile ? 'full' : '350'}>
<Row marginBottom={space['1.5']} alignItems="center">
<Column>
<Heading fontSize="md">
{pupil.firstname} {pupil.lastname}
</Heading>
</Column>
<Spacer />
<Column>
<Button variant="outline" onPress={() => handleOpenModal(pupil)} disabled={isFetching}>
<AddCircleIcon />
</Button>
</Column>
</Row>
<Modal isOpen={isJoinPupilModalOpen} onClose={() => setIsJoinPupilModalOpen(false)} w="full">
<AddPupilModal pupil={{ ...pupilToAdd!, schooltype: undefined, gradeAsInt: undefined }} addPupilToCourse={handleAddPupil} />
</Modal>
</Box>
</>
);
})}
<div className="w-full">
<div className="mb-2">
{pupilsOnWaitinglist && pupilsOnWaitinglist?.length > 0 ? (

Check failure on line 39 in src/pages/single-course/ProspectList.tsx

View workflow job for this annotation

GitHub Actions / verify-against-prod

Cannot find name 'pupilsOnWaitinglist'.

Check failure on line 39 in src/pages/single-course/ProspectList.tsx

View workflow job for this annotation

GitHub Actions / verify-against-prod

Cannot find name 'pupilsOnWaitinglist'.
<Button className="w-fit" onClick={() => setIsIncreaseMaxParticipantsModalOpen(true)}>
{t('single.joinPupilModal.header')}
</Button>
) : (
<Alert className="w-full lg:w-fit mt-4" icon={<IconCircleCheckFilled />}>
{t('single.waitinglist.noPupilsOnWaitinglist')}
</Alert>
)}
</div>
<div className="flex flex-col gap-y-6 max-w-[980px]">
{prospects.map((pupil) => {
return (
<ParticipantRow
key={pupil.id}
participant={{
firstname: pupil.firstname!,
lastname: pupil.lastname!,
grade: null,

Check failure on line 57 in src/pages/single-course/ProspectList.tsx

View workflow job for this annotation

GitHub Actions / verify-against-prod

Type 'null' is not assignable to type 'string'.
gradeAsInt: pupil.gradeAsInt,

Check failure on line 58 in src/pages/single-course/ProspectList.tsx

View workflow job for this annotation

GitHub Actions / verify-against-prod

Property 'gradeAsInt' does not exist on type 'SparseParticipant'.
id: pupil.id,
schooltype: pupil.schooltype!,

Check failure on line 60 in src/pages/single-course/ProspectList.tsx

View workflow job for this annotation

GitHub Actions / verify-against-prod

Property 'schooltype' does not exist on type 'SparseParticipant'.
}}
isInstructor
addParticipant={(participant) =>
handleOpenModal({
id: participant.id,
firstname: participant.firstname,
lastname: participant.lastname!,
gradeAsInt: participant.gradeAsInt,
grade: participant.grade,
schooltype: participant.schooltype!,
})
}
/>
);
})}
</div>
</div>
<AddPupilModal
pupil={pupilToAdd}
isOpen={isJoinPupilModalOpen}
onOpenChange={setIsJoinPupilModalOpen}
subcourseId={subcourseId}
onPupilAdded={handleOnFinish}
type="prospectlist"
/>
<IncreaseMaxParticipantsModal
isOpen={isIncreaseMaxParticipantsModalOpen}
onOpenChange={setIsIncreaseMaxParticipantsModalOpen}
onParticipantsIncreased={handleOnFinish}
maxParticipants={maxParticipants}
subcourseId={subcourseId}
/>
</>
);
};
Expand Down

0 comments on commit d1e7b7d

Please sign in to comment.