From 3c14645fb5cc8247231c9bf8c5365fe810f1b701 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 16 Nov 2025 10:06:19 +0330 Subject: [PATCH] create schedule --- src/components/TimePicker.tsx | 97 +++++++++++++++++++ src/config/Pages.ts | 1 + src/index.css | 16 +++ src/pages/schedule/Create.tsx | 74 ++++++++++++++ src/pages/schedule/List.tsx | 16 +-- .../components/ScheduleFormFields.tsx | 65 +++++++++++++ src/pages/schedule/hooks/useScheduleData.ts | 10 ++ src/pages/schedule/service/ScheduleService.ts | 10 +- src/pages/schedule/types/Types.ts | 7 ++ src/router/Main.tsx | 2 + 10 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 src/components/TimePicker.tsx create mode 100644 src/pages/schedule/Create.tsx create mode 100644 src/pages/schedule/components/ScheduleFormFields.tsx diff --git a/src/components/TimePicker.tsx b/src/components/TimePicker.tsx new file mode 100644 index 0000000..5ecce44 --- /dev/null +++ b/src/components/TimePicker.tsx @@ -0,0 +1,97 @@ +import { useState, useEffect, useRef, type FC } from 'react'; +import { clx } from '../helpers/utils'; +import { Clock } from 'iconsax-react'; +import Error from './Error'; + +type Props = { + onChange: (time: string) => void; + defaultValue?: string; + error_text?: string; + placeholder?: string; + className?: string; + label?: string; +}; + +const TimePickerComponent: FC = (props: Props) => { + const [inputValue, setInputValue] = useState(''); + const inputRef = useRef(null); + + useEffect(() => { + if (props.defaultValue) { + // تبدیل فرمت HH.mm به HH:mm برای input type="time" + const timeStr = props.defaultValue.replace('.', ':'); + setInputValue(timeStr); + } + }, [props.defaultValue]); + + const handleChange = (e: React.ChangeEvent) => { + const timeValue = e.target.value; // فرمت: HH:mm + setInputValue(timeValue); + + if (timeValue) { + // تبدیل فرمت HH:mm به HH.mm برای ارسال به سرور + const formattedTime = timeValue.replace(':', '.'); + props.onChange(formattedTime); + } else { + props.onChange(''); + } + }; + + const handleWrapperClick = () => { + inputRef.current?.showPicker?.(); + inputRef.current?.focus(); + inputRef.current?.click(); + }; + + return ( +
+ {props.label && ( +
+ {props.label} +
+ )} +
+
+ + {!inputValue && ( + + {props.placeholder || 'انتخاب زمان'} + + )} + {inputValue && ( + + {inputValue.replace(':', '.')} + + )} + +
+ {props.error_text && props.error_text !== '' && ( + + )} +
+
+ ); +}; + +export default TimePickerComponent; + diff --git a/src/config/Pages.ts b/src/config/Pages.ts index db3298b..96b4785 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -8,6 +8,7 @@ export const Pages = { schedule: { list: "/schedule/list", update: "/schedule/update/", + create: "/schedule/create", }, foods: { list: "/foods/list", diff --git a/src/index.css b/src/index.css index ed8915b..ca0b1a5 100644 --- a/src/index.css +++ b/src/index.css @@ -79,3 +79,19 @@ tbody tr:nth-child(odd) { .rowTwoInput { @apply flex flex-col sm:flex-row sm:gap-5 gap-5; } + +.time-picker-input::-webkit-calendar-picker-indicator { + display: none !important; + -webkit-appearance: none; +} + +.time-picker-input::-webkit-inner-spin-button, +.time-picker-input::-webkit-outer-spin-button { + display: none !important; + -webkit-appearance: none; +} + +.time-picker-input { + -webkit-appearance: none; + -moz-appearance: textfield; +} diff --git a/src/pages/schedule/Create.tsx b/src/pages/schedule/Create.tsx new file mode 100644 index 0000000..93bd0e5 --- /dev/null +++ b/src/pages/schedule/Create.tsx @@ -0,0 +1,74 @@ +import { type FC } from 'react'; +import { useFormik } from 'formik'; +import * as Yup from 'yup'; +import { TickCircle } from 'iconsax-react'; +import { toast } from 'react-toastify'; +import Button from '@/components/Button'; +import ScheduleFormFields from './components/ScheduleFormFields'; +import { useCreateSchedule } from './hooks/useScheduleData'; +import type { CreateScheduleType } from './types/Types'; +import { Pages } from '@/config/Pages'; +import type { ErrorType } from '@/helpers/types'; +import { extractErrorMessage } from '@/config/func'; +import { useNavigate } from 'react-router-dom'; + +const CreateSchedule: FC = () => { + const { mutate: createSchedule, isPending } = useCreateSchedule(); + const navigate = useNavigate(); + const formik = useFormik({ + initialValues: { + weekDay: 1, + openTime: '', + closeTime: '', + isActive: true, + }, + validationSchema: Yup.object().shape({ + weekDay: Yup.number() + .required('روز هفته الزامی است') + .min(0, 'روز هفته باید بین 1 تا 7 باشد') + .max(6, 'روز هفته باید بین 1 تا 7 باشد'), + openTime: Yup.string().required('زمان شروع الزامی است'), + closeTime: Yup.string().required('زمان پایان الزامی است'), + isActive: Yup.boolean(), + }), + onSubmit: (values) => { + createSchedule(values, { + onSuccess: () => { + toast.success('زمانبندی با موفقیت ایجاد شد'); + navigate(Pages.schedule.list); + }, + onError: (error: ErrorType) => { + toast.error(extractErrorMessage(error)); + }, + }); + }, + }); + + return ( +
+
+
+ زمانبندی جدید +
+
+ +
+
+ +
+ +
+
+ ); +}; + +export default CreateSchedule; \ No newline at end of file diff --git a/src/pages/schedule/List.tsx b/src/pages/schedule/List.tsx index fcba159..3b5d4c1 100644 --- a/src/pages/schedule/List.tsx +++ b/src/pages/schedule/List.tsx @@ -7,6 +7,8 @@ import { useGetSchedules, useDeleteSchedule } from './hooks/useScheduleData' import { useScheduleFilters } from './hooks/useScheduleFilters' import { getScheduleTableColumns } from './components/ScheduleTableColumns' import { useScheduleFiltersFields } from './components/ScheduleFiltersFields' +import { Link } from 'react-router-dom' +import { Pages } from '@/config/Pages' const ScheduleList: FC = () => { const { @@ -34,12 +36,14 @@ const ScheduleList: FC = () => {

لیست زمانبندی

- + + +
diff --git a/src/pages/schedule/components/ScheduleFormFields.tsx b/src/pages/schedule/components/ScheduleFormFields.tsx new file mode 100644 index 0000000..d175c43 --- /dev/null +++ b/src/pages/schedule/components/ScheduleFormFields.tsx @@ -0,0 +1,65 @@ +import { type FC } from 'react'; +import type { FormikProps } from 'formik'; +import Select from '@/components/Select'; +import TimePicker from '@/components/TimePicker'; +import Switch from '@/components/Switch'; +import type { CreateScheduleType } from '../types/Types'; + +type ScheduleFormFieldsProps = { + formik: FormikProps; +}; + +const weekDayOptions = [ + { value: '0', label: 'شنبه' }, + { value: '1', label: 'یکشنبه' }, + { value: '2', label: 'دوشنبه' }, + { value: '3', label: 'سه‌شنبه' }, + { value: '4', label: 'چهارشنبه' }, + { value: '5', label: 'پنج‌شنبه' }, + { value: '6', label: 'جمعه' }, +]; + +const ScheduleFormFields: FC = ({ formik }) => { + return ( +
+