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 = ({