diff --git a/src/pages/finance/ui/Finance.tsx b/src/pages/finance/ui/Finance.tsx index a5dc7aa..9a59605 100644 --- a/src/pages/finance/ui/Finance.tsx +++ b/src/pages/finance/ui/Finance.tsx @@ -242,7 +242,7 @@ export default function FinancePage({ user }: { user: Role }) { {t("Bandlovlar va to‘lovlar")} - {user === "tour_admin" || + {user === "moderator" || user === "buxgalter" || user === "admin" || (user === "superuser" && ( @@ -443,7 +443,7 @@ export default function FinancePage({ user }: { user: Role }) { )} - {user === "tour_admin" || + {user === "moderator" || user === "buxgalter" || user === "admin" || (user === "superuser" && ( diff --git a/src/pages/tours/lib/form.ts b/src/pages/tours/lib/form.ts index 7d298af..b9c9a22 100644 --- a/src/pages/tours/lib/form.ts +++ b/src/pages/tours/lib/form.ts @@ -57,10 +57,8 @@ export const TourformSchema = z.object({ .min(1, { message: "Jo‘nash vaqti majburiy" }) .refine( (val) => { - // HH:MM:SS formatini tekshirish const parts = val.split(":"); if (parts.length !== 3) return false; - const [hour, minute, second] = parts.map(Number); return ( !isNaN(hour) && @@ -84,10 +82,8 @@ export const TourformSchema = z.object({ .min(1, { message: "Jo‘nash vaqti majburiy" }) .refine( (val) => { - // HH:MM:SS formatini tekshirish const parts = val.split(":"); if (parts.length !== 3) return false; - const [hour, minute, second] = parts.map(Number); return ( !isNaN(hour) && @@ -105,7 +101,7 @@ export const TourformSchema = z.object({ ), }), languages: z.string().min(1, { message: "Majburiy maydon" }), - duration: z.number().min(1, { message: "Kamida 1kun bo'lishi kerak" }), + duration: z.number().min(1, { message: "Kamida 1 kun bo'lishi kerak" }), badges: z.array(z.number()).optional(), tarif: z .array( @@ -113,18 +109,17 @@ export const TourformSchema = z.object({ tariff: z.number().min(1, { message: "Transport ID majburiy" }), price: z .number() - .min(0, { message: "Narx 0 dan kichik bo‘lishi mumkin emas" }), // 0 ham ruxsat + .min(0, { message: "Narx 0 dan kichik bo‘lishi mumkin emas" }), }), ) .min(1, { message: "Kamida bitta transport tanlang." }), - transport: z .array( z.object({ transport: z.number().min(1, { message: "Transport ID majburiy" }), price: z .number() - .min(0, { message: "Narx 0 dan kichik bo‘lishi mumkin emas" }), // 0 ham ruxsat + .min(0, { message: "Narx 0 dan kichik bo‘lishi mumkin emas" }), }), ) .min(1, { message: "Kamida bitta transport tanlang." }), @@ -135,23 +130,26 @@ export const TourformSchema = z.object({ amenities: z .array( z.object({ - name: z.string().min(1, { message: "Majburoy maydon" }), - name_ru: z.string().min(1, { message: "Majburoy maydon" }), - icon_name: z.string().min(1, { message: "Majburoy maydon" }), + name: z.string().min(1, { message: "Majburiy maydon" }), + name_ru: z.string().min(1, { message: "Majburiy maydon" }), + icon_name: z.string().min(1, { message: "Majburiy maydon" }), }), ) .min(1, { message: "Kamida bitta qulaylik kiriting." }), + + // 🔹 Quyidagilar endi ixtiyoriy (required emas) hotel_services: z .array( z.object({ image: z.any().nullable(), title: z.string().min(1, "Xizmat nomi majburiy"), - title_ru: z.string().min(1, { message: "Majburoy maydon" }), + title_ru: z.string().min(1, { message: "Majburiy maydon" }), description: z.string().min(1, "Tavsif majburiy"), - desc_ru: z.string().min(1, { message: "Majburoy maydon" }), + desc_ru: z.string().min(1, { message: "Majburiy maydon" }), }), ) - .min(1, { message: "Kamida bitta xizmat kiriting." }), + .optional(), + hotel_meals: z .array( z.object({ @@ -184,6 +182,7 @@ export const TourformSchema = z.object({ }), ) .min(1, { message: "Kamida bitta xizmat kiriting." }), + extra_service: z .array( z.object({ @@ -191,7 +190,7 @@ export const TourformSchema = z.object({ name_ru: z.string().min(1, { message: "Xizmat nomi (RU) majburiy" }), }), ) - .min(1, { message: "Kamida bitta bepul xizmat kiriting." }), + .optional(), paid_extra_service: z .array( @@ -203,5 +202,5 @@ export const TourformSchema = z.object({ .min(0, { message: "Narx manfiy bo‘lishi mumkin emas." }), }), ) - .min(1, { message: "Kamida bitta pullik xizmat kiriting." }), + .optional(), }); diff --git a/src/pages/tours/ui/StepOne.tsx b/src/pages/tours/ui/StepOne.tsx index 646be78..1b02370 100644 --- a/src/pages/tours/ui/StepOne.tsx +++ b/src/pages/tours/ui/StepOne.tsx @@ -356,15 +356,16 @@ const StepOne = ({ name_ru: e.name_ru, }); }); - value.hotel_services.forEach((e, i) => { - if (e instanceof File) { - formData.append(`ticket_included_services[${i}]image`, e.image); - formData.append(`ticket_included_services[${i}]title`, e.title); - formData.append(`ticket_included_services[${i}]title_ru`, e.title_ru); - formData.append(`ticket_included_services[${i}]desc_ru`, e.desc_ru); - formData.append(`ticket_included_services[${i}]desc`, e.description); - } - }); + value.hotel_services && + value.hotel_services.forEach((e, i) => { + if (e instanceof File) { + formData.append(`ticket_included_services[${i}]image`, e.image); + formData.append(`ticket_included_services[${i}]title`, e.title); + formData.append(`ticket_included_services[${i}]title_ru`, e.title_ru); + formData.append(`ticket_included_services[${i}]desc_ru`, e.desc_ru); + formData.append(`ticket_included_services[${i}]desc`, e.description); + } + }); value.ticket_itinerary.forEach((e, i) => { e.ticket_itinerary_image.forEach((l, f) => { if (e instanceof File) { @@ -397,15 +398,17 @@ const StepOne = ({ formData.append(`ticket_hotel_meals[${i}]desc_ru`, e.desc_ru); } }); - value.extra_service.forEach((e, i) => { - formData.append(`extra_service[${i}]name`, e.name); - formData.append(`extra_service[${i}]name_ru`, e.name_ru); - }); - value.paid_extra_service.forEach((e, i) => { - formData.append(`paid_extra_service[${i}]name`, e.name); - formData.append(`paid_extra_service[${i}]name_ru`, e.name_ru); - formData.append(`paid_extra_service[${i}]price`, String(e.price)); - }); + value.extra_service && + value.extra_service.forEach((e, i) => { + formData.append(`extra_service[${i}]name`, e.name); + formData.append(`extra_service[${i}]name_ru`, e.name_ru); + }); + value.paid_extra_service && + value.paid_extra_service.forEach((e, i) => { + formData.append(`paid_extra_service[${i}]name`, e.name); + formData.append(`paid_extra_service[${i}]name_ru`, e.name_ru); + formData.append(`paid_extra_service[${i}]price`, String(e.price)); + }); if (isEditMode && id) { update({ body: formData, @@ -1383,7 +1386,7 @@ const StepOne = ({
{/* Ko'rsatilayotgan xizmatlar */}
- {form.watch("extra_service").map((item, idx) => ( + {(form.watch("extra_service") ?? []).map((item, idx) => ( { - const current = form.getValues("extra_service"); + const current = form.getValues("extra_service") ?? []; form.setValue( "extra_service", current.filter((_, i) => i !== idx), @@ -1432,7 +1435,7 @@ const StepOne = ({ ) as HTMLInputElement; if (nameInput.value && nameRuInput.value) { - const current = form.getValues("extra_service"); + const current = form.getValues("extra_service") ?? []; form.setValue("extra_service", [ ...current, { @@ -1479,7 +1482,8 @@ const StepOne = ({