fix(ui): duplicate schedule warning (#295)
* fix(ui): duplicate schedule warning * fix(ui): duplicate schedule warning * fix(ui): duplicate schedules * fix(ui): schedule limit loophole refactored * fix(ui): schedule bypass hooks * fix(ui): useEnforceScheduleLimit hook created * fix(ui): added useCallback to hook * fix(ui): updated jsdoc comment on hook * fix(ui): updated jsdoc comments on hook
This commit is contained in:
@@ -7,6 +7,7 @@ import { openReportWindow } from '@shared/util/openReportWindow';
|
||||
import Divider from '@views/components/common/Divider';
|
||||
import List from '@views/components/common/List';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import { useEnforceScheduleLimit } from '@views/hooks/useEnforceScheduleLimit';
|
||||
import useSchedules, { getActiveSchedule, replaceSchedule, switchSchedule } from '@views/hooks/useSchedules';
|
||||
import { getUpdatedAtDateTimeString } from '@views/lib/getUpdatedAtDateTimeString';
|
||||
import useKC_DABR_WASM from 'kc-dabr-wasm';
|
||||
@@ -62,6 +63,13 @@ export default function PopupMain(): JSX.Element {
|
||||
// const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [funny, setFunny] = useState<string>('');
|
||||
|
||||
const enforceScheduleLimit = useEnforceScheduleLimit();
|
||||
const handleAddSchedule = () => {
|
||||
if (enforceScheduleLimit()) {
|
||||
createSchedule('New Schedule');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const randomIndex = Math.floor(Math.random() * splashText.length);
|
||||
setFunny(
|
||||
@@ -128,7 +136,7 @@ export default function PopupMain(): JSX.Element {
|
||||
variant='filled'
|
||||
color='ut-burntorange'
|
||||
className='h-fit p-0 btn'
|
||||
onClick={() => createSchedule('New Schedule')}
|
||||
onClick={handleAddSchedule}
|
||||
>
|
||||
<AddSchedule className='h-6 w-6' />
|
||||
</Button>
|
||||
|
||||
@@ -4,13 +4,12 @@ import { Button } from '@views/components/common/Button';
|
||||
import List from '@views/components/common/List';
|
||||
import ScheduleListItem from '@views/components/common/ScheduleListItem';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import { useEnforceScheduleLimit } from '@views/hooks/useEnforceScheduleLimit';
|
||||
import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules';
|
||||
import React from 'react';
|
||||
|
||||
import AddSchedule from '~icons/material-symbols/add';
|
||||
|
||||
import { usePrompt } from '../common/DialogProvider/DialogProvider';
|
||||
|
||||
/**
|
||||
* Renders a component that displays a list of schedules.
|
||||
*
|
||||
@@ -19,32 +18,12 @@ import { usePrompt } from '../common/DialogProvider/DialogProvider';
|
||||
*/
|
||||
export function CalendarSchedules() {
|
||||
const [, schedules] = useSchedules();
|
||||
const showDialog = usePrompt();
|
||||
|
||||
const enforceScheduleLimit = useEnforceScheduleLimit();
|
||||
const handleAddSchedule = () => {
|
||||
if (schedules.length >= 10) {
|
||||
showDialog({
|
||||
title: `You have 10 active schedules!`,
|
||||
|
||||
description: (
|
||||
<>
|
||||
To encourage organization,{' '}
|
||||
<span className='text-ut-burntorange'>please consider removing some unused schedules</span> you
|
||||
may have.
|
||||
</>
|
||||
),
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
buttons: close => (
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
I Understand
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (enforceScheduleLimit()) {
|
||||
createSchedule('New Schedule');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,6 +4,7 @@ import duplicateSchedule from '@pages/background/lib/duplicateSchedule';
|
||||
import renameSchedule from '@pages/background/lib/renameSchedule';
|
||||
import type { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import { useEnforceScheduleLimit } from '@views/hooks/useEnforceScheduleLimit';
|
||||
import useSchedules from '@views/hooks/useSchedules';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
@@ -34,6 +35,12 @@ export default function ScheduleListItem({ schedule, dragHandleProps, onClick }:
|
||||
const [editorValue, setEditorValue] = useState(schedule.name);
|
||||
|
||||
const showDialog = usePrompt();
|
||||
const enforceScheduleLimit = useEnforceScheduleLimit();
|
||||
const handleDuplicateSchedule = (scheduleId: string) => {
|
||||
if (enforceScheduleLimit()) {
|
||||
duplicateSchedule(scheduleId);
|
||||
}
|
||||
};
|
||||
|
||||
const editorRef = React.useRef<HTMLInputElement>(null);
|
||||
useEffect(() => {
|
||||
@@ -180,7 +187,7 @@ export default function ScheduleListItem({ schedule, dragHandleProps, onClick }:
|
||||
<Text
|
||||
as='button'
|
||||
variant='small'
|
||||
onClick={() => duplicateSchedule(schedule.id)}
|
||||
onClick={() => handleDuplicateSchedule(schedule.id)}
|
||||
className='w-full rounded bg-transparent p-2 text-left data-[focus]:bg-gray-200/40'
|
||||
>
|
||||
Duplicate
|
||||
|
||||
45
src/views/hooks/useEnforceScheduleLimit.tsx
Normal file
45
src/views/hooks/useEnforceScheduleLimit.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import useSchedules from '@views/hooks/useSchedules';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { Button } from '../components/common/Button';
|
||||
import { usePrompt } from '../components/common/DialogProvider/DialogProvider';
|
||||
|
||||
const SCHEDULE_LIMIT = 10;
|
||||
|
||||
/**
|
||||
* Hook that creates a function that enforces a maximum amount of schedules
|
||||
*
|
||||
* If a new schedule can be created without exceeding the limit, the function returns true
|
||||
* Otherwise, display a prompt explaining the limit, and returns false
|
||||
*
|
||||
* @returns a function, () => boolean
|
||||
*/
|
||||
export function useEnforceScheduleLimit(): () => boolean {
|
||||
const [, schedules] = useSchedules();
|
||||
const showDialog = usePrompt();
|
||||
|
||||
return useCallback(() => {
|
||||
if (schedules.length >= SCHEDULE_LIMIT) {
|
||||
showDialog({
|
||||
title: `You have ${SCHEDULE_LIMIT} active schedules!`,
|
||||
|
||||
description: (
|
||||
<>
|
||||
To encourage organization,{' '}
|
||||
<span className='text-ut-burntorange'>please consider removing some unused schedules</span> you
|
||||
may have.
|
||||
</>
|
||||
),
|
||||
|
||||
buttons: close => (
|
||||
<Button variant='filled' color='ut-burntorange' onClick={close}>
|
||||
I Understand
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, [schedules, showDialog]);
|
||||
}
|
||||
Reference in New Issue
Block a user