Skip to content

Commit

Permalink
feat(schedules): weekend meeting pdf export
Browse files Browse the repository at this point in the history
  • Loading branch information
rhahao committed Aug 4, 2024
1 parent 9a847ae commit 4b204de
Show file tree
Hide file tree
Showing 26 changed files with 838 additions and 427 deletions.
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export const ASSIGNMENT_PATH = {
WM_WTStudy_Reader: 'weekend_meeting.wt_study.reader',
WM_ClosingPrayer: 'weekend_meeting.closing_prayer',
WM_CircuitOverseer: 'weekend_meeting.circuit_overseer',
WM_SubstituteSpeaker: 'weekend_meeting.speaker.substitute',
};

export const BROTHER_ASSIGNMENT = [
Expand Down
3 changes: 2 additions & 1 deletion src/definition/assignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,5 @@ export type AssignmentFieldType =
| 'WM_WTStudy_Conductor'
| 'WM_WTStudy_Reader'
| 'WM_ClosingPrayer'
| 'WM_CircuitOverseer';
| 'WM_CircuitOverseer'
| 'WM_SubstituteSpeaker';
22 changes: 22 additions & 0 deletions src/definition/schedules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,25 @@ export type MidweekMeetingDataType = {
lc_concluding_prayer: string;
co_name?: string;
};

export type WeekendMeetingDataType = {
date_formatted: string;
weekOf: string;
no_meeting: boolean;
week_type: Week;
week_type_name: string;
event_name: string;
chairman_name: string;
opening_prayer_name: string;
public_talk_title?: string;
public_talk_number: string;
wtstudy_conductor_name: string;
wtstudy_reader_name: string;
speaker_1_name: string;
speaker_2_name: string;
speaker_cong_name: string;
substitute_speaker_name: string;
co_name?: string;
concluding_prayer_name?: string;
service_talk_title?: string;
};
4 changes: 2 additions & 2 deletions src/features/meetings/midweek_export/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box } from '@mui/material';
import { IconLoading } from '@components/icons';
import { useAppTranslation } from '@hooks/index';
import { MidweekExportType } from './index.types';
import useAssignmentsDelete from './useMidweekExport';
import useMidweekExport from './useMidweekExport';
import Button from '@components/button';
import Checkbox from '@components/checkbox';
import Dialog from '@components/dialog';
Expand All @@ -28,7 +28,7 @@ const MidweekExport = ({ open, onClose }: MidweekExportType) => {
S140Template,
handleSelectS140Template,
handleSelectS89Template,
} = useAssignmentsDelete(onClose);
} = useMidweekExport(onClose);

return (
<Dialog
Expand Down
2 changes: 1 addition & 1 deletion src/features/meetings/midweek_export/useMidweekExport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const useMidweekExport = (onClose: MidweekExportType['onClose']) => {
}

setIsProcessing(false);
// onClose?.();
onClose?.();
} catch (error) {
console.error(error);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ const usePersonSelector = ({
useEffect(() => {
if (circuitOverseer) {
setOptions([]);
setFreeSoloText('');
}
}, [circuitOverseer]);

Expand Down
79 changes: 79 additions & 0 deletions src/features/meetings/weekend_export/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Box } from '@mui/material';
import { IconLoading } from '@components/icons';
import { useAppTranslation } from '@hooks/index';
import { WeekendExportType } from './index.types';
import useWeekendExport from './useWeekendExport';
import Button from '@components/button';
import Dialog from '@components/dialog';
import Typography from '@components/typography';
import WeekRangeSelector from '../week_range_selector';

const WeekendExport = ({ open, onClose }: WeekendExportType) => {
const { t } = useAppTranslation();

const {
handleSetEndWeek,
handleSetStartWeek,
isProcessing,
handleExportSchedule,
} = useWeekendExport(onClose);

return (
<Dialog
onClose={onClose}
open={open}
sx={{ padding: '24px', position: 'relative' }}
>
<Box
sx={{
display: 'flex',
gap: '24px',
flexDirection: 'column',
width: '100%',
marginBottom: '110px',
overflow: 'auto',
}}
>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<Typography className="h2">{t('tr_exportWM')}</Typography>
<Typography color="var(--grey-400)">
{t('tr_exportWMDesc')}
</Typography>
</Box>

<WeekRangeSelector
meeting="weekend"
onStartChange={handleSetStartWeek}
onEndChange={handleSetEndWeek}
/>
</Box>

<Box
sx={{
display: 'flex',
flexDirection: 'column',
gap: '8px',
width: '100%',
position: 'absolute',
bottom: 0,
right: 0,
padding: '24px',
}}
>
<Button
variant="main"
disabled={isProcessing}
endIcon={isProcessing && <IconLoading />}
onClick={handleExportSchedule}
>
{t('tr_export')}
</Button>
<Button variant="secondary" onClick={onClose}>
{t('tr_cancel')}
</Button>
</Box>
</Dialog>
);
};

export default WeekendExport;
4 changes: 4 additions & 0 deletions src/features/meetings/weekend_export/index.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type WeekendExportType = {
open: boolean;
onClose: VoidFunction;
};
91 changes: 91 additions & 0 deletions src/features/meetings/weekend_export/useWeekendExport.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { pdf } from '@react-pdf/renderer';
import { saveAs } from 'file-saver';
import { useAppTranslation } from '@hooks/index';
import { WeekendExportType } from './index.types';
import { displaySnackNotification } from '@services/recoil/app';
import { getMessageByCode } from '@services/i18n/translation';
import { schedulesState } from '@states/schedules';
import { WeekendMeetingDataType } from '@definition/schedules';
import { schedulesWeekendData } from '@services/app/schedules';
import {
congNameState,
congNumberState,
userDataViewState,
} from '@states/settings';
import { TemplateWeekendMeeting } from '@views/index';

const useWeekendExport = (onClose: WeekendExportType['onClose']) => {
const { t } = useAppTranslation();

const schedules = useRecoilValue(schedulesState);
const dataView = useRecoilValue(userDataViewState);
const congName = useRecoilValue(congNameState);
const congNumber = useRecoilValue(congNumberState);

const [startWeek, setStartWeek] = useState('');
const [endWeek, setEndWeek] = useState('');
const [isProcessing, setIsProcessing] = useState(false);

const handleSetStartWeek = (value: string) => setStartWeek(value);

const handleSetEndWeek = (value: string) => setEndWeek(value);

const handleExportSchedule = async () => {
if (startWeek.length === 0 || endWeek.length === 0) return;

try {
setIsProcessing(true);

const weeksList = schedules.filter(
(record) => record.weekOf >= startWeek && record.weekOf <= endWeek
);

const meetingData: WeekendMeetingDataType[] = [];

for await (const schedule of weeksList) {
const data = await schedulesWeekendData(schedule, dataView);
meetingData.push(data);
}

const firstWeek = meetingData.at(0).weekOf.replaceAll('/', '');
const lastWeek = meetingData.at(-1).weekOf.replaceAll('/', '');

const blob = await pdf(
<TemplateWeekendMeeting
data={meetingData}
cong_name={congName}
cong_number={congNumber}
/>
).toBlob();

const filename = `WM_${firstWeek}-${lastWeek}.pdf`;

saveAs(blob, filename);

setIsProcessing(false);
onClose?.();
} catch (error) {
console.error(error);

setIsProcessing(false);
onClose?.();

await displaySnackNotification({
header: t('tr_errorTitle'),
message: getMessageByCode(error.message),
severity: 'error',
});
}
};

return {
isProcessing,
handleSetStartWeek,
handleSetEndWeek,
handleExportSchedule,
};
};

export default useWeekendExport;
6 changes: 4 additions & 2 deletions src/locales/en/forms-templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"tr_lcContentElderVariations": "To be handled by an elder",
"tr_speaker": "Speaker",
"tr_speakerSymposium": "Speaker (Symposium, part 1)",
"tr_wtStudyReader": "Watchtower Study Reader",
"tr_wtStudyReader": "Study Reader",
"tr_weekendMeetingPrint": "Weekend Meeting Schedule",
"tr_publicTalk": "Public talk",
"tr_openingPrayerWeekendMeeting": "Opening Prayer",
Expand All @@ -70,5 +70,7 @@
"tr_partDuration": "({{ time }} min.)",
"tr_memorialWeek": "Memorial",
"tr_exportMidweekMeetinDesc": "Choose the schedules and forms you'd like to export and pick your preferred template. Organized saves your template choice for next time to make the export easier.",
"tr_specialTalkWeek": "Special Talk"
"tr_specialTalkWeek": "Special Talk",
"tr_wtStudyConductor": "Study conductor",
"tr_closingPrayerWeekendMeeting": "Closing Prayer"
}
2 changes: 1 addition & 1 deletion src/pages/dashboard/persons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const PersonsCard = () => {
<ListItem disablePadding>
<DashboardMenu
icon={<IconVisitingSpeaker color="var(--black)" />}
primaryText={t('tr_visitingSpeakers')}
primaryText={t('tr_speakersCatalog')}
path="/visiting-speakers"
/>
</ListItem>
Expand Down
22 changes: 19 additions & 3 deletions src/pages/meetings/weekend/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ import useWeekend from './useWeekend';
import Button from '@components/button';
import PageTitle from '@components/page_title';
import WeekendEditor from '@features/meetings/weekend_editor';
import WeekendExport from '@features/meetings/weekend_export';

const WeekendMeeting = () => {
const { t } = useAppTranslation();

const { desktopUp } = useBreakpoints();

const { hasWeeks, openAutofill, handleCloseAutofill, handleOpenAutofill } =
useWeekend();
const {
hasWeeks,
openAutofill,
handleCloseAutofill,
handleOpenAutofill,
openExport,
handleCloseExport,
handleOpenExport,
} = useWeekend();

return (
<Box
Expand All @@ -23,6 +31,10 @@ const WeekendMeeting = () => {
flexDirection: 'column',
}}
>
{openExport && (
<WeekendExport open={openExport} onClose={handleCloseExport} />
)}

{openAutofill && (
<ScheduleAutofillDialog
meeting="weekend"
Expand All @@ -36,7 +48,11 @@ const WeekendMeeting = () => {
buttons={
hasWeeks && (
<>
<Button variant="secondary" startIcon={<IconPrint />}>
<Button
variant="secondary"
startIcon={<IconPrint />}
onClick={handleOpenExport}
>
{t('tr_export')}
</Button>
<Button
Expand Down
Loading

0 comments on commit 4b204de

Please sign in to comment.