feat: export schedule button add to calendar (#594)
* feat: export schedule button add to calendar add to util too * docs: hypen bruh * chore: lowercase * style: filecode icon * chore: unused import * refactor: use export json deleted old function * chore: linting * chore: remove useless import --------- Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react';
|
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react';
|
||||||
import { CalendarDots, Export, FilePng, Sidebar } from '@phosphor-icons/react';
|
import { CalendarDots, Export, FileCode, FilePng, Sidebar } from '@phosphor-icons/react';
|
||||||
import styles from '@views/components/calendar/CalendarHeader/CalendarHeader.module.scss';
|
import styles from '@views/components/calendar/CalendarHeader/CalendarHeader.module.scss';
|
||||||
import { Button } from '@views/components/common/Button';
|
import { Button } from '@views/components/common/Button';
|
||||||
import DialogProvider from '@views/components/common/DialogProvider/DialogProvider';
|
import DialogProvider from '@views/components/common/DialogProvider/DialogProvider';
|
||||||
@@ -11,7 +11,7 @@ import useSchedules from '@views/hooks/useSchedules';
|
|||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { saveAsCal, saveCalAsPng } from '../utils';
|
import { handleExportJson, saveAsCal, saveCalAsPng } from '../utils';
|
||||||
|
|
||||||
interface CalendarHeaderProps {
|
interface CalendarHeaderProps {
|
||||||
sidebarOpen?: boolean;
|
sidebarOpen?: boolean;
|
||||||
@@ -98,6 +98,18 @@ export default function CalendarHeader({ sidebarOpen, onSidebarToggle }: Calenda
|
|||||||
Save as .cal
|
Save as .cal
|
||||||
</Button>
|
</Button>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem>
|
||||||
|
<Button
|
||||||
|
className='w-full flex justify-start'
|
||||||
|
onClick={() => handleExportJson(activeSchedule.id)}
|
||||||
|
color='ut-black'
|
||||||
|
size='small'
|
||||||
|
variant='minimal'
|
||||||
|
icon={FileCode}
|
||||||
|
>
|
||||||
|
Save as .json
|
||||||
|
</Button>
|
||||||
|
</MenuItem>
|
||||||
{/* <MenuItem>
|
{/* <MenuItem>
|
||||||
<Button color='ut-black' size='small' variant='minimal' icon={FileTxt}>
|
<Button color='ut-black' size='small' variant='minimal' icon={FileTxt}>
|
||||||
Export Unique IDs
|
Export Unique IDs
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { tz, TZDate } from '@date-fns/tz';
|
import { tz, TZDate } from '@date-fns/tz';
|
||||||
|
import exportSchedule from '@pages/background/lib/exportSchedule';
|
||||||
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
|
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
|
||||||
import type { Course } from '@shared/types/Course';
|
import type { Course } from '@shared/types/Course';
|
||||||
import type { CourseMeeting } from '@shared/types/CourseMeeting';
|
import type { CourseMeeting } from '@shared/types/CourseMeeting';
|
||||||
@@ -261,6 +262,22 @@ export const saveAsCal = async () => {
|
|||||||
downloadBlob(icsString, 'CALENDAR', 'schedule.ics');
|
downloadBlob(icsString, 'CALENDAR', 'schedule.ics');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves current schedule to JSON that can be imported on other devices.
|
||||||
|
* @param id - Provided schedule ID to download
|
||||||
|
*/
|
||||||
|
export const handleExportJson = async (id: string) => {
|
||||||
|
const jsonString = await exportSchedule(id);
|
||||||
|
if (jsonString) {
|
||||||
|
const schedules = await UserScheduleStore.get('schedules');
|
||||||
|
const schedule = schedules.find(s => s.id === id);
|
||||||
|
const fileName = `${schedule?.name ?? `schedule_${id}`}_${new Date().toISOString().replace(/[:.]/g, '-')}.json`;
|
||||||
|
await downloadBlob(jsonString, 'JSON', fileName);
|
||||||
|
} else {
|
||||||
|
console.error('Error exporting schedule: jsonString is undefined');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the calendar as a PNG image.
|
* Saves the calendar as a PNG image.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|||||||
|
|
||||||
import IconoirGitFork from '~icons/iconoir/git-fork';
|
import IconoirGitFork from '~icons/iconoir/git-fork';
|
||||||
|
|
||||||
|
import { handleExportJson } from '../calendar/utils';
|
||||||
// import { ExampleCourse } from 'src/stories/components/ConflictsWithWarning.stories';;
|
// import { ExampleCourse } from 'src/stories/components/ConflictsWithWarning.stories';;
|
||||||
import FileUpload from '../common/FileUpload';
|
import FileUpload from '../common/FileUpload';
|
||||||
import { useMigrationDialog } from '../common/MigrationDialog';
|
import { useMigrationDialog } from '../common/MigrationDialog';
|
||||||
@@ -232,18 +233,6 @@ export default function Settings(): JSX.Element {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleExportClick = async (id: string) => {
|
|
||||||
const jsonString = await exportSchedule(id);
|
|
||||||
if (jsonString) {
|
|
||||||
const schedules = await UserScheduleStore.get('schedules');
|
|
||||||
const schedule = schedules.find(s => s.id === id);
|
|
||||||
const fileName = `${schedule?.name ?? `schedule_${id}`}_${new Date().toISOString().replace(/[:.]/g, '-')}.json`;
|
|
||||||
await downloadBlob(jsonString, 'JSON', fileName);
|
|
||||||
} else {
|
|
||||||
console.error('Error exporting schedule: jsonString is undefined');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleImportClick = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleImportClick = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -400,7 +389,7 @@ export default function Settings(): JSX.Element {
|
|||||||
<Button
|
<Button
|
||||||
variant='outline'
|
variant='outline'
|
||||||
color='ut-burntorange'
|
color='ut-burntorange'
|
||||||
onClick={() => handleExportClick(activeSchedule.id)}
|
onClick={() => handleExportJson(activeSchedule.id)}
|
||||||
>
|
>
|
||||||
Export
|
Export
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user