Skip to content

Commit df7aadb

Browse files
committed
chore: move schedule modal to legacy
1 parent 8cb7c52 commit df7aadb

File tree

1 file changed

+314
-0
lines changed

1 file changed

+314
-0
lines changed

legacy/src/ScheduleSettings.tsx

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
import React, { useState, useEffect } from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import { GenericModal } from "../ui/GenericModal";
4+
import { MenuItem, TextField, Typography, Box } from "@mui/material";
5+
import { Dropdown } from "../ui/DropdownMui";
6+
import Button from "@mui/material/Button";
7+
import { validMomentTimezones } from '../../constants/const';
8+
import { useGlobalInfoStore } from '../../context/globalInfo';
9+
import { getSchedule, deleteSchedule } from '../../api/storage';
10+
11+
interface ScheduleSettingsProps {
12+
isOpen: boolean;
13+
handleStart: (settings: ScheduleSettings) => Promise<boolean>;
14+
handleClose: () => void;
15+
initialSettings?: ScheduleSettings | null;
16+
}
17+
18+
export interface ScheduleSettings {
19+
runEvery: number;
20+
runEveryUnit: string;
21+
startFrom: string;
22+
dayOfMonth?: string;
23+
atTimeStart?: string;
24+
atTimeEnd?: string;
25+
timezone: string;
26+
}
27+
28+
export const ScheduleSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: ScheduleSettingsProps) => {
29+
const { t } = useTranslation();
30+
const [schedule, setSchedule] = useState<ScheduleSettings | null>(null);
31+
const [settings, setSettings] = useState<ScheduleSettings>({
32+
runEvery: 1,
33+
runEveryUnit: 'HOURS',
34+
startFrom: 'MONDAY',
35+
dayOfMonth: '1',
36+
atTimeStart: '00:00',
37+
atTimeEnd: '01:00',
38+
timezone: 'UTC'
39+
});
40+
41+
useEffect(() => {
42+
if (initialSettings) {
43+
setSettings(initialSettings);
44+
}
45+
}, [initialSettings]);
46+
47+
const handleChange = (field: keyof ScheduleSettings, value: string | number | boolean) => {
48+
setSettings(prev => ({ ...prev, [field]: value }));
49+
};
50+
51+
const textStyle = {
52+
width: '150px',
53+
height: '52px',
54+
marginRight: '10px',
55+
};
56+
57+
const dropDownStyle = {
58+
marginTop: '2px',
59+
width: '150px',
60+
height: '59px',
61+
marginRight: '10px',
62+
};
63+
64+
const units = [
65+
'MINUTES',
66+
'HOURS',
67+
'DAYS',
68+
'WEEKS',
69+
'MONTHS'
70+
];
71+
72+
const days = [
73+
'MONDAY',
74+
'TUESDAY',
75+
'WEDNESDAY',
76+
'THURSDAY',
77+
'FRIDAY',
78+
'SATURDAY',
79+
'SUNDAY'
80+
];
81+
82+
const { recordingId, notify } = useGlobalInfoStore();
83+
84+
const deleteRobotSchedule = () => {
85+
if (recordingId) {
86+
deleteSchedule(recordingId);
87+
setSchedule(null);
88+
notify('success', t('Schedule deleted successfully'));
89+
} else {
90+
console.error('No recording id provided');
91+
}
92+
93+
setSettings({
94+
runEvery: 1,
95+
runEveryUnit: 'HOURS',
96+
startFrom: 'MONDAY',
97+
dayOfMonth: '',
98+
atTimeStart: '00:00',
99+
atTimeEnd: '01:00',
100+
timezone: 'UTC'
101+
});
102+
};
103+
104+
const getRobotSchedule = async () => {
105+
if (recordingId) {
106+
const scheduleData = await getSchedule(recordingId);
107+
setSchedule(scheduleData);
108+
} else {
109+
console.error('No recording id provided');
110+
}
111+
}
112+
113+
useEffect(() => {
114+
if (isOpen) {
115+
const fetchSchedule = async () => {
116+
await getRobotSchedule();
117+
};
118+
fetchSchedule();
119+
}
120+
}, [isOpen]);
121+
122+
const getDayOrdinal = (day: string | undefined) => {
123+
if (!day) return '';
124+
const lastDigit = day.slice(-1);
125+
const lastTwoDigits = day.slice(-2);
126+
127+
// Special cases for 11, 12, 13
128+
if (['11', '12', '13'].includes(lastTwoDigits)) {
129+
return t('schedule_settings.labels.on_day.th');
130+
}
131+
132+
// Other cases
133+
switch (lastDigit) {
134+
case '1': return t('schedule_settings.labels.on_day.st');
135+
case '2': return t('schedule_settings.labels.on_day.nd');
136+
case '3': return t('schedule_settings.labels.on_day.rd');
137+
default: return t('schedule_settings.labels.on_day.th');
138+
}
139+
};
140+
141+
return (
142+
<GenericModal
143+
isOpen={isOpen}
144+
onClose={handleClose}
145+
modalStyle={modalStyle}
146+
>
147+
<Box sx={{
148+
display: 'flex',
149+
flexDirection: 'column',
150+
alignItems: 'flex-start',
151+
padding: '20px',
152+
'& > *': { marginBottom: '20px' },
153+
}}>
154+
<Typography variant="h6" sx={{ marginBottom: '20px' }}>{t('schedule_settings.title')}</Typography>
155+
<>
156+
{schedule !== null ? (
157+
<>
158+
<Typography>{t('schedule_settings.run_every')}: {schedule.runEvery} {schedule.runEveryUnit.toLowerCase()}</Typography>
159+
<Typography>{['MONTHS', 'WEEKS'].includes(settings.runEveryUnit) ? t('schedule_settings.start_from') : t('schedule_settings.start_from')}: {schedule.startFrom.charAt(0).toUpperCase() + schedule.startFrom.slice(1).toLowerCase()}</Typography>
160+
{schedule.runEveryUnit === 'MONTHS' && (
161+
<Typography>{t('schedule_settings.on_day')}: {schedule.dayOfMonth}{getDayOrdinal(schedule.dayOfMonth)} of the month</Typography>
162+
)}
163+
<Typography>{t('schedule_settings.at_around')}: {schedule.atTimeStart}, {schedule.timezone} {t('schedule_settings.timezone')}</Typography>
164+
<Box mt={2} display="flex" justifyContent="space-between">
165+
<Button
166+
onClick={deleteRobotSchedule}
167+
variant="outlined"
168+
color="error"
169+
>
170+
{t('schedule_settings.buttons.delete_schedule')}
171+
</Button>
172+
</Box>
173+
</>
174+
) : (
175+
<>
176+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
177+
<Typography sx={{ marginRight: '10px' }}>{t('schedule_settings.labels.run_once_every')}</Typography>
178+
<TextField
179+
type="number"
180+
value={settings.runEvery}
181+
onChange={(e) => handleChange('runEvery', parseInt(e.target.value))}
182+
sx={textStyle}
183+
inputProps={{ min: 1 }}
184+
/>
185+
<Dropdown
186+
label=""
187+
id="runEveryUnit"
188+
value={settings.runEveryUnit}
189+
handleSelect={(e) => handleChange('runEveryUnit', e.target.value)}
190+
sx={dropDownStyle}
191+
>
192+
{units.map((unit) => (
193+
<MenuItem key={unit} value={unit}> {unit.charAt(0).toUpperCase() + unit.slice(1).toLowerCase()}</MenuItem>
194+
))}
195+
</Dropdown>
196+
</Box>
197+
198+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
199+
<Typography sx={{ marginBottom: '5px', marginRight: '25px' }}>
200+
{['MONTHS', 'WEEKS'].includes(settings.runEveryUnit) ? t('schedule_settings.labels.start_from_label') : t('schedule_settings.labels.start_from_label')}
201+
</Typography>
202+
<Dropdown
203+
label=""
204+
id="startFrom"
205+
value={settings.startFrom}
206+
handleSelect={(e) => handleChange('startFrom', e.target.value)}
207+
sx={dropDownStyle}
208+
>
209+
{days.map((day) => (
210+
<MenuItem key={day} value={day}>
211+
{day.charAt(0).toUpperCase() + day.slice(1).toLowerCase()}
212+
</MenuItem>
213+
))}
214+
</Dropdown>
215+
</Box>
216+
217+
{settings.runEveryUnit === 'MONTHS' && (
218+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
219+
<Typography sx={{ marginBottom: '5px', marginRight: '25px' }}>{t('schedule_settings.labels.on_day_of_month')}</Typography>
220+
<TextField
221+
type="number"
222+
value={settings.dayOfMonth}
223+
onChange={(e) => handleChange('dayOfMonth', e.target.value)}
224+
sx={textStyle}
225+
inputProps={{ min: 1, max: 31 }}
226+
/>
227+
</Box>
228+
)}
229+
230+
{['MINUTES', 'HOURS'].includes(settings.runEveryUnit) ? (
231+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
232+
<Box sx={{ marginRight: '20px' }}>
233+
<Typography sx={{ marginBottom: '5px' }}>{t('schedule_settings.labels.in_between')}</Typography>
234+
<TextField
235+
type="time"
236+
value={settings.atTimeStart}
237+
onChange={(e) => handleChange('atTimeStart', e.target.value)}
238+
sx={textStyle}
239+
/>
240+
<TextField
241+
type="time"
242+
value={settings.atTimeEnd}
243+
onChange={(e) => handleChange('atTimeEnd', e.target.value)}
244+
sx={textStyle}
245+
/>
246+
</Box>
247+
</Box>
248+
) : (
249+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
250+
<Typography sx={{ marginBottom: '5px', marginRight: '10px' }}>{t('schedule_settings.at_around')}</Typography>
251+
<TextField
252+
type="time"
253+
value={settings.atTimeStart}
254+
onChange={(e) => handleChange('atTimeStart', e.target.value)}
255+
sx={textStyle}
256+
/>
257+
</Box>
258+
)}
259+
260+
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%' }}>
261+
<Typography sx={{ marginRight: '10px' }}>{t('schedule_settings.timezone')}</Typography>
262+
<Dropdown
263+
label=""
264+
id="timezone"
265+
value={settings.timezone}
266+
handleSelect={(e) => handleChange('timezone', e.target.value)}
267+
sx={dropDownStyle}
268+
>
269+
{validMomentTimezones.map((tz) => (
270+
<MenuItem key={tz} value={tz}>{tz.charAt(0).toUpperCase() + tz.slice(1).toLowerCase()}</MenuItem>
271+
))}
272+
</Dropdown>
273+
</Box>
274+
<Box mt={2} display="flex" justifyContent="flex-end">
275+
<Button onClick={async () => {
276+
const success = await handleStart(settings);
277+
if (success) {
278+
await getRobotSchedule();
279+
}
280+
}} variant="contained" color="primary">
281+
{t('schedule_settings.buttons.save_schedule')}
282+
</Button>
283+
<Button
284+
onClick={handleClose}
285+
color="primary"
286+
variant="outlined"
287+
style={{ marginLeft: '10px' }}
288+
sx={{
289+
color: '#ff00c3 !important',
290+
borderColor: '#ff00c3 !important',
291+
backgroundColor: 'whitesmoke !important',
292+
}}>
293+
{t('schedule_settings.buttons.cancel')}
294+
</Button>
295+
</Box>
296+
</>
297+
)}
298+
</>
299+
</Box>
300+
</GenericModal>
301+
);
302+
};
303+
304+
const modalStyle = {
305+
top: '50%',
306+
left: '50%',
307+
transform: 'translate(-50%, -50%)',
308+
width: '40%',
309+
backgroundColor: 'background.paper',
310+
p: 4,
311+
height: 'fit-content',
312+
display: 'block',
313+
padding: '20px',
314+
};

0 commit comments

Comments
 (0)