PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.14.1
Yatra – Travel Booking & Tour Operator Software v3.0.14.1
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / assets / dist / js / RecurringRuleForm-CZVn9vM6.js

RecurringRuleForm-CZVn9vM6.js in Yatra – Travel Booking & Tour Operator Software 3.0.14.1, at assets/dist/js/RecurringRuleForm-CZVn9vM6.js

2,149 lines 125.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { j as jsxRuntimeExports, t as useQueryClient, r as reactExports, u as useQuery, v as useMutation, z as ArrowLeft, J as RefreshCw, aw as Plus, ax as X, as as DollarSign, az as AlertCircle, ar as Clock, q as MapPin, aD as CheckCircle2, aQ as Eye, aV as Save } from "./react-vendor-xzSqHjRF.js";
2 import { u as useToast, g as todayYmd, _ as __, S as SearchableSelect, I as Input, t as toDateValue, a as apiClient } from "./index-CbMRo6lO.js";
3 import { C as Card, f as CardHeader, d as CardContent, P as PageHeader, B as Button, g as CardTitle, S as Select, D as DatePicker, e as Badge, h as CardDescription, T as TimePicker, L as LocationPicker, A as Alert, a2 as useNavigate } from "../../admin/dist/js/app.js";
4 const RecurringRuleFormSkeleton = () => {
5 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
6 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-pulse", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
7 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-8 bg-gray-200 dark:bg-gray-700 rounded w-64 mb-2" }),
9 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-96" })
10 ] }),
11 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded w-40" })
12 ] }) }),
13 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
14 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lg:col-span-2 space-y-6", children: [
15 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
16 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-40 animate-pulse" }) }),
17 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
18 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 animate-pulse", children: [
19 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
20 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-16" }),
21 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
22 ] }),
23 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
24 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" }),
25 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
26 ] })
27 ] }),
28 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 animate-pulse", children: [
29 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-20" }),
30 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
31 ] })
32 ] })
33 ] }),
34 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
35 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 animate-pulse", children: [
36 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-5 bg-gray-200 dark:bg-gray-700 rounded" }),
37 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-44" })
38 ] }) }),
39 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
40 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "animate-pulse", children: [
41 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-28 mb-3" }),
42 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-2", children: [...Array(7)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
43 "div",
44 {
45 className: "h-10 bg-gray-200 dark:bg-gray-700 rounded w-24"
46 },
47 i
48 )) })
49 ] }),
50 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t border-gray-200 dark:border-gray-700 animate-pulse", children: [
51 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
52 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" }),
53 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
54 ] }),
55 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
56 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-20" }),
57 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
58 ] })
59 ] }),
60 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700 animate-pulse", children: [
61 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-32 mb-2" }),
62 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 mb-2", children: [
63 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-10 bg-gray-200 dark:bg-gray-700 rounded" }),
64 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-10 bg-gray-200 dark:bg-gray-700 rounded" })
65 ] })
66 ] })
67 ] })
68 ] }),
69 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
70 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
71 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 animate-pulse", children: [
72 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-5 bg-gray-200 dark:bg-gray-700 rounded" }),
73 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-44" })
74 ] }),
75 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-80 mt-2 animate-pulse" })
76 ] }),
77 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
78 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 bg-gray-100 dark:bg-gray-800/50 rounded-lg animate-pulse", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
79 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-9 bg-gray-200 dark:bg-gray-700 rounded-full" }),
80 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
81 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-40 mb-2" }),
82 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-72" })
83 ] })
84 ] }) }),
85 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 animate-pulse", children: [
86 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
87 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-28" }),
88 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
89 ] }),
90 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
91 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" }),
92 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
93 ] })
94 ] }),
95 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700 animate-pulse", children: [
96 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 bg-gray-200 dark:bg-gray-700 rounded w-44 mb-4" }),
97 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
98 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
99 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-28" }),
100 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
101 ] }),
102 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
103 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-32" }),
104 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
105 ] })
106 ] })
107 ] })
108 ] })
109 ] }),
110 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
111 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
112 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 animate-pulse", children: [
113 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-5 bg-gray-200 dark:bg-gray-700 rounded" }),
114 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-36" })
115 ] }),
116 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2 mt-2 animate-pulse", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 bg-gray-200 dark:bg-gray-700 rounded w-28" }) })
117 ] }),
118 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
119 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between animate-pulse", children: [
120 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" }),
121 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-8 bg-gray-200 dark:bg-gray-700 rounded w-24" })
122 ] }),
123 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-6 bg-gray-50 dark:bg-gray-800 rounded-lg border-2 border-dashed border-gray-200 dark:border-gray-700 animate-pulse", children: [
124 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-8 w-8 bg-gray-200 dark:bg-gray-700 rounded mx-auto mb-2" }),
125 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-36 mx-auto mb-2" }),
126 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-64 mx-auto" })
127 ] }),
128 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t border-gray-200 dark:border-gray-700 animate-pulse", children: [
129 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
130 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-28" }),
131 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
132 ] }),
133 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
134 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24" }),
135 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
136 ] })
137 ] }),
138 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "animate-pulse", children: [
139 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-48 mb-2" }),
140 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
141 ] })
142 ] })
143 ] })
144 ] }),
145 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
146 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
147 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-16 animate-pulse" }) }),
148 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) })
149 ] }),
150 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
151 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
152 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 animate-pulse", children: [
153 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-5 bg-gray-200 dark:bg-gray-700 rounded" }),
154 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 bg-gray-200 dark:bg-gray-700 rounded w-20" })
155 ] }),
156 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-48 mt-2 animate-pulse" })
157 ] }),
158 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
159 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded w-full mb-4 animate-pulse" }),
160 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 animate-pulse", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
161 "div",
162 {
163 className: "h-6 bg-gray-200 dark:bg-gray-700 rounded"
164 },
165 i
166 )) })
167 ] })
168 ] }),
169 /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "pt-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 animate-pulse", children: [
170 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" }),
171 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
172 ] }) }) }),
173 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-gray-100 dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-gray-700 animate-pulse", children: [
174 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-24 mb-2" }),
175 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-12 bg-gray-200 dark:bg-gray-700 rounded" })
176 ] })
177 ] })
178 ] })
179 ] });
180 };
181 function coordFromApi(v) {
182 if (v == null || v === "") return "";
183 return String(v);
184 }
185 const dayOptions = [
186 { value: 0, label: "Sunday" },
187 { value: 1, label: "Monday" },
188 { value: 2, label: "Tuesday" },
189 { value: 3, label: "Wednesday" },
190 { value: 4, label: "Thursday" },
191 { value: 5, label: "Friday" },
192 { value: 6, label: "Saturday" }
193 ];
194 const weekOptions = [
195 { value: "first", label: "First" },
196 { value: "second", label: "Second" },
197 { value: "third", label: "Third" },
198 { value: "fourth", label: "Fourth" },
199 { value: "last", label: "Last" }
200 ];
201 const RecurringRuleForm = () => {
202 var _a, _b;
203 const { navigate } = useNavigate();
204 const queryClient = useQueryClient();
205 const { showToast } = useToast();
206 const params = new URLSearchParams(window.location.search);
207 const ruleId = params.get("id");
208 const tripIdFromUrl = params.get("trip_id");
209 const isEditing = !!ruleId;
210 const [formData, setFormData] = reactExports.useState({
211 trip_id: tripIdFromUrl ? parseInt(tripIdFromUrl) : 0,
212 name: "",
213 rule_type: "weekly",
214 days_of_week: [0],
215 // Sunday by default
216 week_of_month: "first",
217 day_of_week: 0,
218 interval_days: 7,
219 start_date: todayYmd(),
220 end_date: "",
221 excluded_dates: [],
222 months: [],
223 // Empty = all months, otherwise specific months (1-12)
224 time_slots: [],
225 // For single-day trips with multiple slots
226 pricing_type: "regular",
227 // Will be updated based on trip's pricing type
228 original_price: void 0,
229 sale_price: void 0,
230 traveler_pricing: [],
231 // For traveler-based pricing
232 seats_total: 20,
233 departure_time: "",
234 arrival_time: "",
235 from_location: "",
236 to_location: "",
237 from_latitude: "",
238 from_longitude: "",
239 to_latitude: "",
240 to_longitude: "",
241 cutoff_hours: 24,
242 alert_threshold: 5,
243 status: "active"
244 });
245 const [newExcludedDate, setNewExcludedDate] = reactExports.useState("");
246 const [previewData, setPreviewData] = reactExports.useState(null);
247 const [showCategorySelector, setShowCategorySelector] = reactExports.useState(false);
248 const { data: tripsData } = useQuery({
249 queryKey: ["trips", "all"],
250 queryFn: async () => {
251 const response = await apiClient.get("/trips", {
252 params: { per_page: 100, status: "publish" }
253 });
254 return {
255 trips: ((response == null ? void 0 : response.data) || []).map((trip) => {
256 const rawPriceTypes = trip.price_types;
257 const hasTravelerPricing = Array.isArray(rawPriceTypes) ? rawPriceTypes.length > 0 : false;
258 const effectivePricingType = hasTravelerPricing ? "traveler_based" : trip.pricing_type || "regular";
259 return {
260 id: Number(trip.id) || 0,
261 title: trip.title,
262 trip_type: trip.trip_type || (trip.duration_days <= 1 ? "single_day" : "multi_day"),
263 duration_days: trip.duration_days || 1,
264 starting_location: trip.starting_location,
265 ending_location: trip.ending_location,
266 pricing_type: effectivePricingType
267 };
268 })
269 };
270 }
271 });
272 const { data: travelerCategories = [] } = useQuery({
273 queryKey: ["traveler-categories"],
274 queryFn: async () => {
275 const response = await apiClient.get("/traveler-categories", {
276 params: { per_page: 100 }
277 });
278 return (response == null ? void 0 : response.data) || [];
279 }
280 });
281 const selectedTrip = tripsData == null ? void 0 : tripsData.trips.find((t) => t.id === formData.trip_id);
282 const { data: tripForLocations } = useQuery({
283 queryKey: ["trip", formData.trip_id, "recurring-rule-locations"],
284 queryFn: async () => {
285 const response = await apiClient.get(`/trips/${formData.trip_id}`);
286 return (response == null ? void 0 : response.data) || response || null;
287 },
288 enabled: formData.trip_id > 0,
289 staleTime: 5 * 60 * 1e3
290 });
291 const { data: fallbackTripData } = useQuery({
292 queryKey: ["trip", formData.trip_id, "recurring-rule-form"],
293 queryFn: async () => {
294 if (!formData.trip_id || selectedTrip) {
295 return null;
296 }
297 const response = await apiClient.get(`/trips/${formData.trip_id}`);
298 return (response == null ? void 0 : response.data) || response || null;
299 },
300 enabled: !!formData.trip_id && !selectedTrip,
301 staleTime: 5 * 60 * 1e3
302 });
303 const effectiveTrip = selectedTrip || (fallbackTripData ? {
304 id: Number(fallbackTripData.id) || formData.trip_id,
305 title: fallbackTripData.title
306 } : null);
307 const tripNameLabel = (effectiveTrip == null ? void 0 : effectiveTrip.title) || __("Unnamed Trip", "yatra");
308 let headerDescription = __(
309 "Set up automatic availability patterns for your trips",
310 "yatra"
311 );
312 if (effectiveTrip) {
313 headerDescription = `${isEditing ? __("Edit", "yatra") : __("Add", "yatra")} ${__("availability rule for", "yatra")} ${tripNameLabel} (Trip ID: ${effectiveTrip.id})`;
314 } else if (formData.trip_id) {
315 headerDescription = `${isEditing ? __("Edit", "yatra") : __("Add", "yatra")} ${__("availability rule for Trip ID:", "yatra")} ${formData.trip_id}`;
316 }
317 const isSingleDayTrip = (selectedTrip == null ? void 0 : selectedTrip.trip_type) === "single_day" || ((selectedTrip == null ? void 0 : selectedTrip.duration_days) || 1) <= 1;
318 const isTravelerBasedPricing = formData.pricing_type === "traveler_based";
319 const { data: existingRule, isLoading: isLoadingRule } = useQuery({
320 queryKey: ["recurring-availability", ruleId],
321 queryFn: async () => {
322 if (!ruleId) return null;
323 const response = await apiClient.get(`/recurring-availability/${ruleId}`);
324 return (response == null ? void 0 : response.data) || response;
325 },
326 enabled: !!ruleId
327 });
328 reactExports.useEffect(() => {
329 if (existingRule && tripsData) {
330 let daysOfWeek = [0];
331 if (existingRule.days_of_week_array && Array.isArray(existingRule.days_of_week_array)) {
332 daysOfWeek = existingRule.days_of_week_array;
333 } else if (existingRule.days_of_week) {
334 if (typeof existingRule.days_of_week === "string") {
335 daysOfWeek = existingRule.days_of_week.split(",").map(Number).filter((n) => !isNaN(n));
336 } else if (Array.isArray(existingRule.days_of_week)) {
337 daysOfWeek = existingRule.days_of_week.map(Number);
338 }
339 }
340 const ruleType = existingRule.rule_type || "weekly";
341 const tripRow = tripsData.trips.find(
342 (t) => t.id === Number(existingRule.trip_id)
343 );
344 const effectivePricingType = (tripRow == null ? void 0 : tripRow.pricing_type) || ((tripForLocations == null ? void 0 : tripForLocations.price_types) && Array.isArray(tripForLocations.price_types) && tripForLocations.price_types.length > 0 ? "traveler_based" : tripForLocations == null ? void 0 : tripForLocations.pricing_type) || "regular";
345 setFormData({
346 trip_id: existingRule.trip_id || 0,
347 name: existingRule.name || "",
348 rule_type: ruleType,
349 days_of_week: daysOfWeek.length > 0 ? daysOfWeek : [0],
350 week_of_month: existingRule.week_of_month || "first",
351 day_of_week: existingRule.day_of_week ?? 0,
352 interval_days: existingRule.interval_days || 7,
353 start_date: existingRule.start_date || todayYmd(),
354 end_date: existingRule.end_date || "",
355 excluded_dates: Array.isArray(existingRule.excluded_dates) ? existingRule.excluded_dates : [],
356 months: Array.isArray(existingRule.months) ? existingRule.months : [],
357 time_slots: Array.isArray(existingRule.time_slots) ? existingRule.time_slots : [],
358 pricing_type: effectivePricingType,
359 original_price: existingRule.original_price,
360 sale_price: existingRule.sale_price,
361 traveler_pricing: Array.isArray(existingRule.traveler_pricing) ? existingRule.traveler_pricing : [],
362 seats_total: existingRule.seats_total || 20,
363 departure_time: existingRule.departure_time || "",
364 arrival_time: existingRule.arrival_time || "",
365 from_location: existingRule.from_location || "",
366 to_location: existingRule.to_location || "",
367 from_latitude: coordFromApi(existingRule.from_latitude),
368 from_longitude: coordFromApi(existingRule.from_longitude),
369 to_latitude: coordFromApi(existingRule.to_latitude),
370 to_longitude: coordFromApi(existingRule.to_longitude),
371 cutoff_hours: existingRule.cutoff_hours || 24,
372 alert_threshold: existingRule.alert_threshold || 5,
373 status: existingRule.status || "active"
374 });
375 }
376 }, [existingRule, tripsData, tripForLocations]);
377 reactExports.useEffect(() => {
378 if (!isEditing && !existingRule) {
379 const inferred = (() => {
380 const priceTypes = tripForLocations == null ? void 0 : tripForLocations.price_types;
381 const hasTravelerPricing = Array.isArray(priceTypes) && priceTypes.length > 0;
382 return hasTravelerPricing ? "traveler_based" : (selectedTrip == null ? void 0 : selectedTrip.pricing_type) || (tripForLocations == null ? void 0 : tripForLocations.pricing_type) || "regular";
383 })();
384 setFormData((prev) => ({
385 ...prev,
386 ...selectedTrip || tripForLocations ? {
387 pricing_type: inferred
388 } : {},
389 ...tripForLocations ? {
390 from_location: prev.from_location || tripForLocations.starting_location || "",
391 to_location: prev.to_location || tripForLocations.ending_location || "",
392 from_latitude: prev.from_latitude || coordFromApi(tripForLocations.starting_latitude),
393 from_longitude: prev.from_longitude || coordFromApi(tripForLocations.starting_longitude),
394 to_latitude: prev.to_latitude || coordFromApi(tripForLocations.ending_latitude),
395 to_longitude: prev.to_longitude || coordFromApi(tripForLocations.ending_longitude)
396 } : {}
397 }));
398 }
399 }, [isEditing, selectedTrip, tripForLocations, existingRule]);
400 const createMutation = useMutation({
401 mutationFn: async (data) => {
402 return await apiClient.post("/recurring-availability", {
403 ...data,
404 days_of_week: Array.isArray(data.days_of_week) ? data.days_of_week : [],
405 // Normalize month-week selector to backend contract.
406 week_of_month: data.rule_type === "monthly" ? (data.week_of_month || "first").toLowerCase() : data.week_of_month,
407 // On create, omit empty arrays to keep payload small.
408 time_slots: data.time_slots.length > 0 ? data.time_slots : void 0,
409 traveler_pricing: data.traveler_pricing && data.traveler_pricing.length > 0 ? data.traveler_pricing : void 0
410 });
411 },
412 onSuccess: () => {
413 queryClient.invalidateQueries({ queryKey: ["recurring-availability"] });
414 showToast(__("Recurring rule created successfully", "yatra"), "success");
415 navigate({
416 subpage: "trips",
417 tab: "availability",
418 trip_id: formData.trip_id.toString()
419 });
420 },
421 onError: (error) => {
422 showToast(
423 (error == null ? void 0 : error.message) || __("Failed to create rule", "yatra"),
424 "error"
425 );
426 }
427 });
428 const updateMutation = useMutation({
429 mutationFn: async (data) => {
430 return await apiClient.put(`/recurring-availability/${ruleId}`, {
431 ...data,
432 days_of_week: Array.isArray(data.days_of_week) ? data.days_of_week : [],
433 week_of_month: data.rule_type === "monthly" ? (data.week_of_month || "first").toLowerCase() : data.week_of_month,
434 // IMPORTANT: on update, send empty arrays explicitly to clear persisted
435 // JSON columns; omitting the key leaves the old value in DB.
436 time_slots: Array.isArray(data.time_slots) ? data.time_slots : [],
437 traveler_pricing: Array.isArray(data.traveler_pricing) ? data.traveler_pricing : []
438 });
439 },
440 onSuccess: () => {
441 queryClient.invalidateQueries({ queryKey: ["recurring-availability"] });
442 showToast(__("Recurring rule updated successfully", "yatra"), "success");
443 navigate({
444 subpage: "trips",
445 tab: "availability",
446 trip_id: formData.trip_id.toString()
447 });
448 },
449 onError: (error) => {
450 showToast(
451 (error == null ? void 0 : error.message) || __("Failed to update rule", "yatra"),
452 "error"
453 );
454 }
455 });
456 const previewMutation = useMutation({
457 mutationFn: async (data) => {
458 return await apiClient.post("/recurring-availability/preview", {
459 ...data,
460 days_of_week: Array.isArray(data.days_of_week) ? data.days_of_week : [],
461 week_of_month: data.rule_type === "monthly" ? (data.week_of_month || "first").toLowerCase() : data.week_of_month,
462 time_slots: data.time_slots.length > 0 ? data.time_slots : void 0,
463 traveler_pricing: data.traveler_pricing && data.traveler_pricing.length > 0 ? data.traveler_pricing : void 0,
464 preview_limit: 20
465 });
466 },
467 onSuccess: (response) => {
468 const previewResult = (response == null ? void 0 : response.data) || response;
469 setPreviewData(previewResult);
470 },
471 onError: (error) => {
472 showToast(
473 (error == null ? void 0 : error.message) || __("Failed to generate preview", "yatra"),
474 "error"
475 );
476 }
477 });
478 const handleSubmit = (e) => {
479 e.preventDefault();
480 if (!formData.trip_id) {
481 showToast(__("Please select a trip", "yatra"), "error");
482 return;
483 }
484 if (formData.rule_type === "weekly" && formData.days_of_week.length === 0) {
485 showToast(
486 __("Please select at least one day of the week", "yatra"),
487 "error"
488 );
489 return;
490 }
491 if (isEditing) {
492 updateMutation.mutate(formData);
493 } else {
494 createMutation.mutate(formData);
495 }
496 };
497 const toggleDay = (day) => {
498 setFormData((prev) => ({
499 ...prev,
500 days_of_week: prev.days_of_week.includes(day) ? prev.days_of_week.filter((d) => d !== day) : [...prev.days_of_week, day].sort((a, b) => a - b)
501 }));
502 };
503 const addExcludedDate = () => {
504 if (newExcludedDate && !formData.excluded_dates.includes(newExcludedDate)) {
505 setFormData((prev) => ({
506 ...prev,
507 excluded_dates: [...prev.excluded_dates, newExcludedDate].sort()
508 }));
509 setNewExcludedDate("");
510 }
511 };
512 const removeExcludedDate = (date) => {
513 setFormData((prev) => ({
514 ...prev,
515 excluded_dates: prev.excluded_dates.filter((d) => d !== date)
516 }));
517 };
518 const isLoading = createMutation.isPending || updateMutation.isPending;
519 if (isEditing && isLoadingRule) {
520 return /* @__PURE__ */ jsxRuntimeExports.jsx(RecurringRuleFormSkeleton, {});
521 }
522 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
523 /* @__PURE__ */ jsxRuntimeExports.jsx(
524 PageHeader,
525 {
526 title: isEditing ? __("Edit Recurring Rule", "yatra") : __("Create Recurring Rule", "yatra"),
527 description: headerDescription,
528 actions: /* @__PURE__ */ jsxRuntimeExports.jsxs(
529 Button,
530 {
531 variant: "outline",
532 onClick: () => {
533 var _a2;
534 return navigate({
535 subpage: "trips",
536 tab: "availability",
537 trip_id: ((_a2 = formData.trip_id) == null ? void 0 : _a2.toString()) || tripIdFromUrl || ""
538 });
539 },
540 children: [
541 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "w-4 h-4 mr-2" }),
542 __("Back to Availability", "yatra")
543 ]
544 }
545 )
546 }
547 ),
548 /* @__PURE__ */ jsxRuntimeExports.jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
549 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lg:col-span-2 space-y-6", children: [
550 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
551 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Basic Information", "yatra") }) }),
552 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
553 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
554 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
555 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
556 __("Trip", "yatra"),
557 " ",
558 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
559 ] }),
560 /* @__PURE__ */ jsxRuntimeExports.jsx(
561 SearchableSelect,
562 {
563 value: ((_a = formData.trip_id) == null ? void 0 : _a.toString()) || "",
564 onChange: (value) => setFormData((prev) => {
565 var _a2;
566 return {
567 ...prev,
568 trip_id: parseInt(value) || 0,
569 // Reset pricing when trip changes and set pricing_type based on new trip
570 pricing_type: ((_a2 = tripsData == null ? void 0 : tripsData.trips.find(
571 (t) => t.id === parseInt(value)
572 )) == null ? void 0 : _a2.pricing_type) || "regular",
573 traveler_pricing: [],
574 original_price: void 0,
575 sale_price: void 0
576 };
577 }),
578 options: [
579 { value: "", label: __("-- Select Trip --", "yatra") },
580 ...(tripsData == null ? void 0 : tripsData.trips.map((trip) => ({
581 value: trip.id.toString(),
582 label: `${trip.title} (${trip.pricing_type === "traveler_based" ? "Traveler-Based" : "Regular"})`
583 }))) || []
584 ],
585 placeholder: __("Select a trip", "yatra"),
586 disabled: isEditing
587 }
588 )
589 ] }),
590 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
591 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Rule Name", "yatra") }),
592 /* @__PURE__ */ jsxRuntimeExports.jsx(
593 Input,
594 {
595 type: "text",
596 value: formData.name,
597 onChange: (e) => setFormData((prev) => ({
598 ...prev,
599 name: e.target.value
600 })),
601 placeholder: __("e.g., Weekend Departures", "yatra")
602 }
603 )
604 ] })
605 ] }),
606 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
607 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
608 __("Rule Type", "yatra"),
609 " ",
610 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
611 ] }),
612 /* @__PURE__ */ jsxRuntimeExports.jsxs(
613 Select,
614 {
615 value: formData.rule_type,
616 onChange: (e) => setFormData((prev) => ({
617 ...prev,
618 rule_type: e.target.value
619 })),
620 children: [
621 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "weekly", children: __("Weekly (specific days)", "yatra") }),
622 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "monthly", children: __("Monthly (e.g., first Sunday)", "yatra") }),
623 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "interval", children: __("Interval (every X days)", "yatra") })
624 ]
625 }
626 )
627 ] })
628 ] })
629 ] }),
630 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
631 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2", children: [
632 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-5 h-5" }),
633 __("Recurrence Pattern", "yatra")
634 ] }) }),
635 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
636 formData.rule_type === "weekly" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
637 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: [
638 __("Days of Week", "yatra"),
639 " ",
640 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
641 ] }),
642 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-2", children: dayOptions.map((day) => /* @__PURE__ */ jsxRuntimeExports.jsx(
643 "button",
644 {
645 type: "button",
646 onClick: () => toggleDay(day.value),
647 className: `px-4 py-2 rounded-lg text-sm font-medium transition-colors ${formData.days_of_week.includes(day.value) ? "bg-blue-600 text-white" : "bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700"}`,
648 children: day.label
649 },
650 day.value
651 )) })
652 ] }),
653 formData.rule_type === "monthly" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
654 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
655 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Week of Month", "yatra") }),
656 /* @__PURE__ */ jsxRuntimeExports.jsx(
657 Select,
658 {
659 value: formData.week_of_month || "first",
660 onChange: (e) => setFormData((prev) => ({
661 ...prev,
662 week_of_month: e.target.value
663 })),
664 children: weekOptions.map((week) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: week.value, children: week.label }, week.value))
665 }
666 )
667 ] }),
668 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
669 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Day of Week", "yatra") }),
670 /* @__PURE__ */ jsxRuntimeExports.jsx(
671 Select,
672 {
673 value: ((_b = formData.day_of_week) == null ? void 0 : _b.toString()) || "0",
674 onChange: (e) => setFormData((prev) => ({
675 ...prev,
676 day_of_week: parseInt(e.target.value)
677 })),
678 children: dayOptions.map((day) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: day.value, children: day.label }, day.value))
679 }
680 )
681 ] })
682 ] }),
683 formData.rule_type === "interval" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
684 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Every X Days", "yatra") }),
685 /* @__PURE__ */ jsxRuntimeExports.jsx(
686 Input,
687 {
688 type: "number",
689 min: 1,
690 max: 365,
691 value: formData.interval_days || 7,
692 onChange: (e) => setFormData((prev) => ({
693 ...prev,
694 interval_days: parseInt(e.target.value) || 7
695 }))
696 }
697 )
698 ] }),
699 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t border-gray-200 dark:border-gray-700", children: [
700 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
701 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
702 __("Start Date", "yatra"),
703 " ",
704 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
705 ] }),
706 /* @__PURE__ */ jsxRuntimeExports.jsx(
707 DatePicker,
708 {
709 value: formData.start_date,
710 onChange: (value) => setFormData((prev) => ({ ...prev, start_date: value })),
711 placeholder: __("Select start date", "yatra")
712 }
713 )
714 ] }),
715 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
716 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
717 __("End Date", "yatra"),
718 " ",
719 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400", children: [
720 "(",
721 __("optional", "yatra"),
722 ")"
723 ] })
724 ] }),
725 /* @__PURE__ */ jsxRuntimeExports.jsx(
726 DatePicker,
727 {
728 value: formData.end_date || "",
729 onChange: (value) => setFormData((prev) => ({ ...prev, end_date: value })),
730 minDate: formData.start_date ? toDateValue(formData.start_date) : void 0,
731 placeholder: __("Select end date (optional)", "yatra")
732 }
733 )
734 ] })
735 ] }),
736 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700", children: [
737 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
738 __("Specific Months", "yatra"),
739 " ",
740 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400", children: [
741 "(",
742 __("optional - leave empty for all months", "yatra"),
743 ")"
744 ] })
745 ] }),
746 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-2", children: [
747 { value: 1, label: __("January", "yatra") },
748 { value: 2, label: __("February", "yatra") },
749 { value: 3, label: __("March", "yatra") },
750 { value: 4, label: __("April", "yatra") },
751 { value: 5, label: __("May", "yatra") },
752 { value: 6, label: __("June", "yatra") },
753 { value: 7, label: __("July", "yatra") },
754 { value: 8, label: __("August", "yatra") },
755 { value: 9, label: __("September", "yatra") },
756 { value: 10, label: __("October", "yatra") },
757 { value: 11, label: __("November", "yatra") },
758 { value: 12, label: __("December", "yatra") }
759 ].map((month) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
760 "label",
761 {
762 className: `flex items-center justify-center px-3 py-2 rounded-md border cursor-pointer transition-colors ${formData.months.includes(month.value) ? "bg-blue-50 border-blue-500 text-blue-700 dark:bg-blue-900/20 dark:border-blue-600 dark:text-blue-300" : "border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800"}`,
763 children: [
764 /* @__PURE__ */ jsxRuntimeExports.jsx(
765 "input",
766 {
767 type: "checkbox",
768 checked: formData.months.includes(month.value),
769 onChange: (e) => {
770 const checked = e.target.checked;
771 setFormData((prev) => ({
772 ...prev,
773 months: checked ? [...prev.months, month.value].sort(
774 (a, b) => a - b
775 ) : prev.months.filter((m) => m !== month.value)
776 }));
777 },
778 className: "sr-only"
779 }
780 ),
781 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: month.label.slice(0, 3) })
782 ]
783 },
784 month.value
785 )) }),
786 formData.months.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-2", children: [
787 __("Selected:", "yatra"),
788 " ",
789 formData.months.length,
790 " ",
791 formData.months.length === 1 ? __("month", "yatra") : __("months", "yatra")
792 ] })
793 ] }),
794 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700", children: [
795 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
796 __("Excluded Dates", "yatra"),
797 " ",
798 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400", children: [
799 "(",
800 __("holidays, etc.", "yatra"),
801 ")"
802 ] })
803 ] }),
804 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 mb-2", children: [
805 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
806 DatePicker,
807 {
808 value: newExcludedDate,
809 onChange: (value) => setNewExcludedDate(value),
810 placeholder: __("Select date to exclude", "yatra")
811 }
812 ) }),
813 /* @__PURE__ */ jsxRuntimeExports.jsx(
814 Button,
815 {
816 type: "button",
817 variant: "outline",
818 onClick: addExcludedDate,
819 disabled: !newExcludedDate,
820 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" })
821 }
822 )
823 ] }),
824 formData.excluded_dates.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-2", children: formData.excluded_dates.map((date) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
825 Badge,
826 {
827 variant: "outline",
828 className: "flex items-center gap-1",
829 children: [
830 (/* @__PURE__ */ new Date(date + "T00:00:00")).toLocaleDateString(
831 "en-US",
832 {
833 weekday: "short",
834 month: "short",
835 day: "numeric",
836 year: "numeric"
837 }
838 ),
839 /* @__PURE__ */ jsxRuntimeExports.jsx(
840 "button",
841 {
842 type: "button",
843 onClick: () => removeExcludedDate(date),
844 className: "ml-1 hover:text-red-500",
845 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-3 h-3" })
846 }
847 )
848 ]
849 },
850 date
851 )) })
852 ] })
853 ] })
854 ] }),
855 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
856 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
857 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2", children: [
858 /* @__PURE__ */ jsxRuntimeExports.jsx(DollarSign, { className: "w-5 h-5" }),
859 __("Pricing & Availability", "yatra")
860 ] }),
861 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __(
862 "Set pricing for traveler categories and seat availability for this rule",
863 "yatra"
864 ) })
865 ] }),
866 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-6", children: [
867 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
868 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 rounded-full bg-amber-100 dark:bg-amber-900/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
869 "svg",
870 {
871 className: "w-5 h-5 text-amber-600 dark:text-amber-400",
872 fill: "none",
873 stroke: "currentColor",
874 viewBox: "0 0 24 24",
875 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
876 "path",
877 {
878 strokeLinecap: "round",
879 strokeLinejoin: "round",
880 strokeWidth: 2,
881 d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
882 }
883 )
884 }
885 ) }),
886 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
887 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-white mb-1", children: __("Pricing Override (Optional)", "yatra") }),
888 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: __(
889 "Leave pricing fields empty to use the trip's default pricing. Fill them in only if you want to override the default pricing for dates generated by this rule.",
890 "yatra"
891 ) })
892 ] })
893 ] }) }),
894 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
895 /* @__PURE__ */ jsxRuntimeExports.jsx(
896 "div",
897 {
898 className: `p-2 rounded-full ${isTravelerBasedPricing ? "bg-green-100 dark:bg-green-900/30" : "bg-blue-100 dark:bg-blue-900/30"}`,
899 children: isTravelerBasedPricing ? /* @__PURE__ */ jsxRuntimeExports.jsx(
900 "svg",
901 {
902 className: "w-5 h-5 text-green-600 dark:text-green-400",
903 fill: "none",
904 stroke: "currentColor",
905 viewBox: "0 0 24 24",
906 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
907 "path",
908 {
909 strokeLinecap: "round",
910 strokeLinejoin: "round",
911 strokeWidth: 2,
912 d: "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
913 }
914 )
915 }
916 ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
917 "svg",
918 {
919 className: "w-5 h-5 text-blue-600 dark:text-blue-400",
920 fill: "none",
921 stroke: "currentColor",
922 viewBox: "0 0 24 24",
923 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
924 "path",
925 {
926 strokeLinecap: "round",
927 strokeLinejoin: "round",
928 strokeWidth: 2,
929 d: "M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
930 }
931 )
932 }
933 )
934 }
935 ),
936 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
937 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-white", children: isTravelerBasedPricing ? __("Traveler-Based Pricing", "yatra") : __("Regular Pricing", "yatra") }),
938 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: isTravelerBasedPricing ? __(
939 "This trip uses traveler category pricing. Set prices for each category below.",
940 "yatra"
941 ) : __(
942 "This trip uses regular pricing. Set a single price for all travelers below.",
943 "yatra"
944 ) })
945 ] })
946 ] }) }),
947 !isTravelerBasedPricing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
948 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
949 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
950 __("Original Price", "yatra"),
951 " ",
952 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400 text-xs", children: [
953 "(",
954 __("Optional", "yatra"),
955 ")"
956 ] })
957 ] }),
958 /* @__PURE__ */ jsxRuntimeExports.jsx(
959 Input,
960 {
961 type: "number",
962 min: 0,
963 step: "0.01",
964 value: formData.original_price || "",
965 onChange: (e) => setFormData((prev) => ({
966 ...prev,
967 original_price: parseFloat(e.target.value) || void 0
968 })),
969 placeholder: "0.00"
970 }
971 )
972 ] }),
973 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
974 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Sale Price", "yatra") }),
975 /* @__PURE__ */ jsxRuntimeExports.jsx(
976 Input,
977 {
978 type: "number",
979 min: 0,
980 step: "0.01",
981 value: formData.sale_price || "",
982 onChange: (e) => setFormData((prev) => ({
983 ...prev,
984 sale_price: parseFloat(e.target.value) || void 0
985 })),
986 placeholder: "0.00"
987 }
988 ),
989 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: __("Leave empty if no discount", "yatra") })
990 ] })
991 ] }) }),
992 isTravelerBasedPricing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
993 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
994 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
995 __("Traveler Category Pricing", "yatra"),
996 " ",
997 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
998 ] }),
999 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-4", children: __(
1000 "Add pricing for traveler categories. Categories are managed in Traveler Categories page.",
1001 "yatra"
1002 ) })
1003 ] }),
1004 (() => {
1005 const activeCategories = travelerCategories.filter(
1006 (cat) => cat.status === "active" || cat.status === "publish"
1007 );
1008 if (activeCategories.length === 0) {
1009 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border border-gray-200 dark:border-gray-700 rounded-lg text-center", children: [
1010 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __(
1011 "No active traveler categories found.",
1012 "yatra"
1013 ) }),
1014 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1015 Button,
1016 {
1017 type: "button",
1018 variant: "outline",
1019 onClick: () => window.location.href = "?page=yatra&subpage=traveler-categories&action=create",
1020 className: "flex items-center gap-2 mx-auto",
1021 children: [
1022 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }),
1023 __("Create Category", "yatra")
1024 ]
1025 }
1026 )
1027 ] });
1028 }
1029 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1030 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
1031 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1032 Button,
1033 {
1034 type: "button",
1035 variant: "outline",
1036 onClick: () => setShowCategorySelector(!showCategorySelector),
1037 className: "flex items-center gap-2",
1038 disabled: activeCategories.filter(
1039 (cat) => {
1040 var _a2;
1041 return !((_a2 = formData.traveler_pricing) == null ? void 0 : _a2.some(
1042 (tp) => tp.category_id === cat.id
1043 ));
1044 }
1045 ).length === 0,
1046 children: [
1047 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }),
1048 __("Add Pricing", "yatra")
1049 ]
1050 }
1051 ),
1052 showCategorySelector && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1053 /* @__PURE__ */ jsxRuntimeExports.jsx(
1054 "div",
1055 {
1056 className: "fixed inset-0 z-10",
1057 onClick: () => setShowCategorySelector(false)
1058 }
1059 ),
1060 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-full left-0 mt-2 w-full max-w-md bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg z-20 max-h-96 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2", children: [
1061 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300 px-3 py-2 mb-1", children: __(
1062 "Select a category to add pricing",
1063 "yatra"
1064 ) }),
1065 activeCategories.filter(
1066 (cat) => {
1067 var _a2;
1068 return !((_a2 = formData.traveler_pricing) == null ? void 0 : _a2.some(
1069 (tp) => tp.category_id === cat.id
1070 ));
1071 }
1072 ).length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-4 text-sm text-gray-500 dark:text-gray-400 text-center", children: __(
1073 "All categories have pricing added",
1074 "yatra"
1075 ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: activeCategories.filter(
1076 (cat) => {
1077 var _a2;
1078 return !((_a2 = formData.traveler_pricing) == null ? void 0 : _a2.some(
1079 (tp) => tp.category_id === cat.id
1080 ));
1081 }
1082 ).map((category) => {
1083 const minAge = category.age_min ?? category.min_age;
1084 const maxAge = category.age_max ?? category.max_age;
1085 const ageRange = minAge !== void 0 || maxAge !== void 0 ? minAge !== void 0 && maxAge !== void 0 ? `${minAge}-${maxAge} ${__("years", "yatra")}` : minAge !== void 0 ? `${minAge}+ ${__("years", "yatra")}` : maxAge !== void 0 ? `${__("Under", "yatra")} ${maxAge} ${__("years", "yatra")}` : "" : null;
1086 const categoryName = category.label || category.name || `Category ${category.id}`;
1087 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1088 "button",
1089 {
1090 type: "button",
1091 onClick: () => {
1092 setFormData((prev) => ({
1093 ...prev,
1094 traveler_pricing: [
1095 ...prev.traveler_pricing || [],
1096 {
1097 category_id: category.id,
1098 original_price: 0,
1099 sale_price: void 0
1100 }
1101 ]
1102 }));
1103 setShowCategorySelector(
1104 false
1105 );
1106 },
1107 className: "w-full text-left px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
1108 children: [
1109 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-medium text-sm text-gray-900 dark:text-white", children: [
1110 categoryName,
1111 ageRange && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [
1112 "(",
1113 ageRange,
1114 ")"
1115 ] })
1116 ] }),
1117 category.description && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5", children: category.description })
1118 ]
1119 },
1120 category.id
1121 );
1122 }) })
1123 ] }) })
1124 ] })
1125 ] }),
1126 formData.traveler_pricing && formData.traveler_pricing.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.traveler_pricing.map(
1127 (pricing, index) => {
1128 const category = activeCategories.find(
1129 (cat) => cat.id === pricing.category_id
1130 );
1131 if (!category) return null;
1132 const minAge = category.age_min ?? category.min_age;
1133 const maxAge = category.age_max ?? category.max_age;
1134 const categoryName = category.label || category.name || `Category ${pricing.category_id}`;
1135 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1136 "div",
1137 {
1138 className: "p-4 border border-blue-300 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/20 rounded-lg",
1139 children: [
1140 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-3", children: [
1141 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
1142 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 mb-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-semibold text-gray-900 dark:text-white", children: [
1143 categoryName,
1144 (minAge !== void 0 || maxAge !== void 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [
1145 "(",
1146 minAge !== void 0 && maxAge !== void 0 ? `${minAge}-${maxAge} ${__("years", "yatra")}` : minAge !== void 0 ? `${minAge}+ ${__("years", "yatra")}` : maxAge !== void 0 ? `${__("Under", "yatra")} ${maxAge} ${__("years", "yatra")}` : "",
1147 ")"
1148 ] })
1149 ] }) }),
1150 category.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: category.description })
1151 ] }),
1152 /* @__PURE__ */ jsxRuntimeExports.jsx(
1153 "button",
1154 {
1155 type: "button",
1156 onClick: () => {
1157 const categoryIdToRemove = pricing.category_id;
1158 setFormData((prev) => ({
1159 ...prev,
1160 traveler_pricing: (prev.traveler_pricing || []).filter(
1161 (tp) => tp.category_id !== categoryIdToRemove
1162 )
1163 }));
1164 },
1165 className: "p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors",
1166 title: __(
1167 "Remove Pricing",
1168 "yatra"
1169 ),
1170 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
1171 }
1172 )
1173 ] }),
1174 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [
1175 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1176 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [
1177 __("Original Price", "yatra"),
1178 " ",
1179 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
1180 ] }),
1181 /* @__PURE__ */ jsxRuntimeExports.jsx(
1182 Input,
1183 {
1184 type: "number",
1185 min: 0,
1186 step: "0.01",
1187 value: pricing.original_price || "",
1188 onChange: (e) => {
1189 const newPricing = [
1190 ...formData.traveler_pricing || []
1191 ];
1192 newPricing[index].original_price = parseFloat(e.target.value) || 0;
1193 setFormData((prev) => ({
1194 ...prev,
1195 traveler_pricing: newPricing
1196 }));
1197 },
1198 placeholder: "0.00"
1199 }
1200 )
1201 ] }),
1202 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1203 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [
1204 __("Sale Price", "yatra"),
1205 " (",
1206 __("Optional", "Optional"),
1207 ")"
1208 ] }),
1209 /* @__PURE__ */ jsxRuntimeExports.jsx(
1210 Input,
1211 {
1212 type: "number",
1213 min: 0,
1214 step: "0.01",
1215 value: pricing.sale_price || "",
1216 onChange: (e) => {
1217 const newPricing = [
1218 ...formData.traveler_pricing || []
1219 ];
1220 newPricing[index].sale_price = parseFloat(e.target.value) || void 0;
1221 setFormData((prev) => ({
1222 ...prev,
1223 traveler_pricing: newPricing
1224 }));
1225 },
1226 className: "text-sm",
1227 placeholder: "0.00"
1228 }
1229 )
1230 ] })
1231 ] })
1232 ]
1233 },
1234 pricing.category_id
1235 );
1236 }
1237 ) })
1238 ] });
1239 })()
1240 ] }),
1241 selectedTrip && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700", children: [
1242 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4", children: __("Inventory Management", "yatra") }),
1243 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1244 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1245 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
1246 __("Total Capacity", "yatra"),
1247 " ",
1248 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
1249 ] }),
1250 /* @__PURE__ */ jsxRuntimeExports.jsx(
1251 Input,
1252 {
1253 type: "number",
1254 min: 1,
1255 value: formData.seats_total,
1256 onChange: (e) => setFormData((prev) => ({
1257 ...prev,
1258 seats_total: parseInt(e.target.value) || 1
1259 }))
1260 }
1261 ),
1262 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: __(
1263 "Maximum number of seats available for this rule",
1264 "yatra"
1265 ) })
1266 ] }),
1267 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1268 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Alert Threshold", "yatra") }),
1269 /* @__PURE__ */ jsxRuntimeExports.jsx(
1270 Input,
1271 {
1272 type: "number",
1273 min: 0,
1274 value: formData.alert_threshold,
1275 onChange: (e) => setFormData((prev) => ({
1276 ...prev,
1277 alert_threshold: parseInt(e.target.value) || 0
1278 }))
1279 }
1280 ),
1281 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: __(
1282 "Alert when available seats drop below this number",
1283 "yatra"
1284 ) })
1285 ] })
1286 ] })
1287 ] }),
1288 !selectedTrip && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-6 bg-gray-50 dark:bg-gray-800 rounded-lg", children: [
1289 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-8 h-8 text-gray-400 mx-auto mb-2" }),
1290 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: __("Select a trip above to configure pricing", "yatra") })
1291 ] })
1292 ] })
1293 ] }),
1294 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1295 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
1296 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2", children: [
1297 /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-5 h-5" }),
1298 __("Time & Location", "yatra")
1299 ] }),
1300 selectedTrip && /* @__PURE__ */ jsxRuntimeExports.jsxs(CardDescription, { children: [
1301 /* @__PURE__ */ jsxRuntimeExports.jsx(
1302 Badge,
1303 {
1304 variant: isSingleDayTrip ? "default" : "outline",
1305 className: "mr-2",
1306 children: isSingleDayTrip ? __("Single-Day Trip", "yatra") : __("Multi-Day Trip", "yatra")
1307 }
1308 ),
1309 !isSingleDayTrip && selectedTrip.duration_days && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-500", children: [
1310 "(",
1311 selectedTrip.duration_days,
1312 " ",
1313 __("days", "yatra"),
1314 ")"
1315 ] })
1316 ] })
1317 ] }),
1318 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
1319 isSingleDayTrip && formData.trip_id > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1320 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
1321 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
1322 __("Time Slots", "yatra"),
1323 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400 ml-1", children: [
1324 "(",
1325 __("for each recurring day", "yatra"),
1326 ")"
1327 ] })
1328 ] }),
1329 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1330 Button,
1331 {
1332 type: "button",
1333 variant: "outline",
1334 size: "sm",
1335 onClick: () => setFormData((prev) => ({
1336 ...prev,
1337 time_slots: [
1338 ...prev.time_slots,
1339 {
1340 departure_time: "09:00",
1341 arrival_time: "17:00",
1342 seats: 20,
1343 price: 0,
1344 traveler_pricing: isTravelerBasedPricing ? [] : void 0
1345 }
1346 ]
1347 })),
1348 children: [
1349 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-1" }),
1350 __("Add Slot", "yatra")
1351 ]
1352 }
1353 )
1354 ] }),
1355 formData.time_slots.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-6 bg-gray-50 dark:bg-gray-800 rounded-lg border-2 border-dashed border-gray-200 dark:border-gray-700", children: [
1356 /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-8 h-8 text-gray-400 mx-auto mb-2" }),
1357 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-2", children: __("No time slots added yet", "yatra") }),
1358 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: __(
1359 "Add multiple time slots for tours throughout the day (e.g., morning, afternoon, evening)",
1360 "yatra"
1361 ) })
1362 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.time_slots.map((slot, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1363 "div",
1364 {
1365 className: "p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700",
1366 children: [
1367 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
1368 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
1369 __("Slot", "yatra"),
1370 " ",
1371 index + 1
1372 ] }),
1373 /* @__PURE__ */ jsxRuntimeExports.jsx(
1374 Button,
1375 {
1376 type: "button",
1377 variant: "ghost",
1378 size: "sm",
1379 onClick: () => setFormData((prev) => ({
1380 ...prev,
1381 time_slots: prev.time_slots.filter(
1382 (_, i) => i !== index
1383 )
1384 })),
1385 className: "text-red-500 hover:text-red-600 h-8 w-8 p-0",
1386 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
1387 }
1388 )
1389 ] }),
1390 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
1391 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
1392 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1393 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Departure Time", "yatra") }),
1394 /* @__PURE__ */ jsxRuntimeExports.jsx(
1395 TimePicker,
1396 {
1397 value: slot.departure_time || "",
1398 onChange: (value) => {
1399 const newSlots = [...formData.time_slots];
1400 newSlots[index].departure_time = value;
1401 setFormData((prev) => ({
1402 ...prev,
1403 time_slots: newSlots
1404 }));
1405 },
1406 placeholder: "09:00"
1407 }
1408 )
1409 ] }),
1410 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1411 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Arrival Time", "yatra") }),
1412 /* @__PURE__ */ jsxRuntimeExports.jsx(
1413 TimePicker,
1414 {
1415 value: slot.arrival_time || "",
1416 onChange: (value) => {
1417 const newSlots = [...formData.time_slots];
1418 newSlots[index].arrival_time = value;
1419 setFormData((prev) => ({
1420 ...prev,
1421 time_slots: newSlots
1422 }));
1423 },
1424 placeholder: "17:00"
1425 }
1426 )
1427 ] })
1428 ] }),
1429 !isTravelerBasedPricing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3", children: [
1430 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1431 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Seats", "yatra") }),
1432 /* @__PURE__ */ jsxRuntimeExports.jsx(
1433 Input,
1434 {
1435 type: "number",
1436 min: 1,
1437 value: slot.seats,
1438 onChange: (e) => {
1439 const newSlots = [
1440 ...formData.time_slots
1441 ];
1442 newSlots[index].seats = parseInt(e.target.value) || 1;
1443 setFormData((prev) => ({
1444 ...prev,
1445 time_slots: newSlots
1446 }));
1447 },
1448 className: "text-sm"
1449 }
1450 )
1451 ] }),
1452 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1453 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Price", "yatra") }),
1454 /* @__PURE__ */ jsxRuntimeExports.jsx(
1455 Input,
1456 {
1457 type: "number",
1458 min: 0,
1459 step: "0.01",
1460 value: slot.price || "",
1461 onChange: (e) => {
1462 const newSlots = [
1463 ...formData.time_slots
1464 ];
1465 newSlots[index].price = parseFloat(e.target.value) || 0;
1466 setFormData((prev) => ({
1467 ...prev,
1468 time_slots: newSlots
1469 }));
1470 },
1471 className: "text-sm",
1472 placeholder: "0.00"
1473 }
1474 )
1475 ] }),
1476 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1477 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Sale Price", "yatra") }),
1478 /* @__PURE__ */ jsxRuntimeExports.jsx(
1479 Input,
1480 {
1481 type: "number",
1482 min: 0,
1483 step: "0.01",
1484 value: slot.sale_price || "",
1485 onChange: (e) => {
1486 const newSlots = [
1487 ...formData.time_slots
1488 ];
1489 newSlots[index].sale_price = parseFloat(e.target.value) || void 0;
1490 setFormData((prev) => ({
1491 ...prev,
1492 time_slots: newSlots
1493 }));
1494 },
1495 className: "text-sm",
1496 placeholder: "0.00"
1497 }
1498 )
1499 ] })
1500 ] }),
1501 isTravelerBasedPricing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1502 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-500 dark:text-gray-400 mb-1", children: __("Seats", "yatra") }),
1503 /* @__PURE__ */ jsxRuntimeExports.jsx(
1504 Input,
1505 {
1506 type: "number",
1507 min: 1,
1508 value: slot.seats,
1509 onChange: (e) => {
1510 const newSlots = [...formData.time_slots];
1511 newSlots[index].seats = parseInt(e.target.value) || 1;
1512 setFormData((prev) => ({
1513 ...prev,
1514 time_slots: newSlots
1515 }));
1516 },
1517 className: "text-sm"
1518 }
1519 )
1520 ] })
1521 ] }),
1522 isTravelerBasedPricing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 pt-3 border-t border-gray-200 dark:border-gray-700", children: [
1523 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1524 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-gray-700 dark:text-gray-300", children: __("Traveler Category Pricing", "yatra") }),
1525 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5", children: __(
1526 "Set pricing for each traveler category for this time slot",
1527 "yatra"
1528 ) })
1529 ] }) }),
1530 (() => {
1531 const activeCategories = travelerCategories.filter(
1532 (cat) => cat.status === "active" || cat.status === "publish"
1533 );
1534 const slotTravelerPricing = slot.traveler_pricing || [];
1535 const availableCategories = activeCategories.filter(
1536 (cat) => !slotTravelerPricing.some(
1537 (tp) => tp.category_id === cat.id
1538 )
1539 );
1540 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
1541 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
1542 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1543 Button,
1544 {
1545 type: "button",
1546 variant: "outline",
1547 size: "sm",
1548 onClick: () => {
1549 const dropdownId = `slot-${index}-category-dropdown`;
1550 const dropdown = document.getElementById(
1551 dropdownId
1552 );
1553 if (dropdown) {
1554 dropdown.classList.toggle(
1555 "hidden"
1556 );
1557 }
1558 },
1559 disabled: availableCategories.length === 0,
1560 children: [
1561 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-3 h-3 mr-1" }),
1562 __("Add Pricing", "yatra")
1563 ]
1564 }
1565 ),
1566 /* @__PURE__ */ jsxRuntimeExports.jsx(
1567 "div",
1568 {
1569 id: `slot-${index}-category-dropdown`,
1570 className: "hidden absolute top-full left-0 mt-2 w-full max-w-sm bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg z-20 max-h-64 overflow-y-auto",
1571 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2", children: [
1572 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300 px-3 py-2 mb-1", children: __(
1573 "Select a category to add pricing",
1574 "yatra"
1575 ) }),
1576 availableCategories.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-3 text-xs text-gray-500 dark:text-gray-400 text-center", children: __(
1577 "All categories have pricing added",
1578 "yatra"
1579 ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: availableCategories.map(
1580 (category) => {
1581 const minAge = category.age_min ?? category.min_age;
1582 const maxAge = category.age_max ?? category.max_age;
1583 const ageRange = minAge !== void 0 || maxAge !== void 0 ? minAge !== void 0 && maxAge !== void 0 ? `${minAge}-${maxAge} ${__("years", "yatra")}` : minAge !== void 0 ? `${minAge}+ ${__("years", "yatra")}` : `${__("Under", "yatra")} ${maxAge} ${__("years", "yatra")}` : null;
1584 const categoryName = category.label || category.name || `Category ${category.id}`;
1585 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1586 "button",
1587 {
1588 type: "button",
1589 onClick: () => {
1590 const newSlots = [
1591 ...formData.time_slots
1592 ];
1593 if (!newSlots[index].traveler_pricing) {
1594 newSlots[index].traveler_pricing = [];
1595 }
1596 newSlots[index].traveler_pricing = [
1597 ...newSlots[index].traveler_pricing,
1598 {
1599 category_id: category.id,
1600 original_price: 0,
1601 sale_price: void 0
1602 }
1603 ];
1604 setFormData(
1605 (prev) => ({
1606 ...prev,
1607 time_slots: newSlots
1608 })
1609 );
1610 const dropdown = document.getElementById(
1611 `slot-${index}-category-dropdown`
1612 );
1613 if (dropdown)
1614 dropdown.classList.add(
1615 "hidden"
1616 );
1617 },
1618 className: "w-full text-left px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
1619 children: [
1620 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-medium text-xs text-gray-900 dark:text-white", children: [
1621 categoryName,
1622 ageRange && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [
1623 "(",
1624 ageRange,
1625 ")"
1626 ] })
1627 ] }),
1628 category.description && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate", children: category.description })
1629 ]
1630 },
1631 category.id
1632 );
1633 }
1634 ) })
1635 ] })
1636 }
1637 )
1638 ] }),
1639 slotTravelerPricing.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: slotTravelerPricing.map(
1640 (tp, tpIndex) => {
1641 const category = activeCategories.find(
1642 (cat) => cat.id === tp.category_id
1643 );
1644 if (!category) return null;
1645 const minAge = category.age_min ?? category.min_age;
1646 const maxAge = category.age_max ?? category.max_age;
1647 const categoryName = category.label || category.name || `Category ${tp.category_id}`;
1648 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1649 "div",
1650 {
1651 className: "p-3 border border-blue-300 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/20 rounded-lg",
1652 children: [
1653 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-2", children: [
1654 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold text-gray-900 dark:text-white", children: [
1655 categoryName,
1656 (minAge !== void 0 || maxAge !== void 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-1 text-xs font-normal text-gray-500 dark:text-gray-400", children: [
1657 "(",
1658 minAge !== void 0 && maxAge !== void 0 ? `${minAge}-${maxAge}` : minAge !== void 0 ? `${minAge}+` : `<${maxAge}`,
1659 " ",
1660 __(
1661 "years",
1662 "yatra"
1663 ),
1664 ")"
1665 ] })
1666 ] }) }),
1667 /* @__PURE__ */ jsxRuntimeExports.jsx(
1668 "button",
1669 {
1670 type: "button",
1671 onClick: () => {
1672 const categoryIdToRemove = tp.category_id;
1673 setFormData((prev) => {
1674 const newSlots = [
1675 ...prev.time_slots
1676 ];
1677 if (!newSlots[index]) {
1678 return prev;
1679 }
1680 newSlots[index] = {
1681 ...newSlots[index],
1682 traveler_pricing: (newSlots[index].traveler_pricing || []).filter(
1683 (p) => p.category_id !== categoryIdToRemove
1684 )
1685 };
1686 return {
1687 ...prev,
1688 time_slots: newSlots
1689 };
1690 });
1691 },
1692 className: "p-0.5 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors",
1693 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-3 h-3" })
1694 }
1695 )
1696 ] }),
1697 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1698 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1699 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1", children: [
1700 __("Price", "yatra"),
1701 " ",
1702 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
1703 ] }),
1704 /* @__PURE__ */ jsxRuntimeExports.jsx(
1705 Input,
1706 {
1707 type: "number",
1708 min: 0,
1709 step: "0.01",
1710 value: tp.original_price || "",
1711 onChange: (e) => {
1712 const newSlots = [
1713 ...formData.time_slots
1714 ];
1715 if (newSlots[index] && newSlots[index].traveler_pricing) {
1716 newSlots[index].traveler_pricing[tpIndex].original_price = parseFloat(
1717 e.target.value
1718 ) || 0;
1719 setFormData(
1720 (prev) => ({
1721 ...prev,
1722 time_slots: newSlots
1723 })
1724 );
1725 }
1726 },
1727 className: "text-xs",
1728 placeholder: "0.00"
1729 }
1730 )
1731 ] }),
1732 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1733 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1", children: __("Sale", "yatra") }),
1734 /* @__PURE__ */ jsxRuntimeExports.jsx(
1735 Input,
1736 {
1737 type: "number",
1738 min: 0,
1739 step: "0.01",
1740 value: tp.sale_price || "",
1741 onChange: (e) => {
1742 const newSlots = [
1743 ...formData.time_slots
1744 ];
1745 if (newSlots[index] && newSlots[index].traveler_pricing) {
1746 newSlots[index].traveler_pricing[tpIndex].sale_price = parseFloat(
1747 e.target.value
1748 ) || void 0;
1749 setFormData(
1750 (prev) => ({
1751 ...prev,
1752 time_slots: newSlots
1753 })
1754 );
1755 }
1756 },
1757 className: "text-xs",
1758 placeholder: "0.00"
1759 }
1760 )
1761 ] })
1762 ] })
1763 ]
1764 },
1765 tp.category_id
1766 );
1767 }
1768 ) }),
1769 slotTravelerPricing.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center py-3 bg-gray-100 dark:bg-gray-800 rounded border border-dashed border-gray-300 dark:border-gray-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: __(
1770 'Click "Add Pricing" to set prices for traveler categories',
1771 "yatra"
1772 ) }) })
1773 ] });
1774 })()
1775 ] })
1776 ]
1777 },
1778 index
1779 )) }),
1780 formData.time_slots.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-gray-700", children: [
1781 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-3", children: __(
1782 "Or use default time (applies to all generated dates):",
1783 "yatra"
1784 ) }),
1785 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
1786 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1787 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Default Start Time", "yatra") }),
1788 /* @__PURE__ */ jsxRuntimeExports.jsx(
1789 TimePicker,
1790 {
1791 value: formData.departure_time || "",
1792 onChange: (value) => setFormData((prev) => ({
1793 ...prev,
1794 departure_time: value
1795 })),
1796 placeholder: "09:00"
1797 }
1798 )
1799 ] }),
1800 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1801 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Default End Time", "yatra") }),
1802 /* @__PURE__ */ jsxRuntimeExports.jsx(
1803 TimePicker,
1804 {
1805 value: formData.arrival_time || "",
1806 onChange: (value) => setFormData((prev) => ({
1807 ...prev,
1808 arrival_time: value
1809 })),
1810 placeholder: "17:00"
1811 }
1812 )
1813 ] })
1814 ] })
1815 ] })
1816 ] }),
1817 !isSingleDayTrip && formData.trip_id > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1818 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1819 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Departure Time", "yatra") }),
1820 /* @__PURE__ */ jsxRuntimeExports.jsx(
1821 TimePicker,
1822 {
1823 value: formData.departure_time || "",
1824 onChange: (value) => setFormData((prev) => ({
1825 ...prev,
1826 departure_time: value
1827 })),
1828 placeholder: "08:00"
1829 }
1830 )
1831 ] }),
1832 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1833 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
1834 __("Return Time", "yatra"),
1835 " ",
1836 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400", children: [
1837 "(",
1838 __("on final day", "yatra"),
1839 ")"
1840 ] })
1841 ] }),
1842 /* @__PURE__ */ jsxRuntimeExports.jsx(
1843 TimePicker,
1844 {
1845 value: formData.arrival_time || "",
1846 onChange: (value) => setFormData((prev) => ({
1847 ...prev,
1848 arrival_time: value
1849 })),
1850 placeholder: "18:00"
1851 }
1852 )
1853 ] })
1854 ] }),
1855 !formData.trip_id && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-6 bg-gray-50 dark:bg-gray-800 rounded-lg", children: [
1856 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-8 h-8 text-gray-400 mx-auto mb-2" }),
1857 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: __(
1858 "Select a trip above to configure time settings",
1859 "yatra"
1860 ) })
1861 ] }),
1862 formData.trip_id > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1863 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8 pt-4 border-t border-gray-200 dark:border-gray-700", children: [
1864 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1865 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 p-4 bg-gradient-to-r from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 rounded-xl border border-blue-200 dark:border-blue-800", children: [
1866 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center shadow-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-5 h-5 text-white" }) }),
1867 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
1868 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-blue-900 dark:text-blue-100", children: __("Starting Point", "yatra") }),
1869 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-700 dark:text-blue-300", children: __("Where the journey begins", "yatra") })
1870 ] }),
1871 formData.from_latitude && formData.from_longitude && /* @__PURE__ */ jsxRuntimeExports.jsx(
1872 "div",
1873 {
1874 className: "w-2 h-2 bg-blue-500 rounded-full",
1875 title: __("Coordinates set", "yatra")
1876 }
1877 )
1878 ] }),
1879 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1880 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: __("From location (departure)", "yatra") }),
1881 /* @__PURE__ */ jsxRuntimeExports.jsx(
1882 LocationPicker,
1883 {
1884 value: {
1885 name: formData.from_location || "",
1886 latitude: formData.from_latitude || "",
1887 longitude: formData.from_longitude || ""
1888 },
1889 onChange: (loc) => setFormData((prev) => ({
1890 ...prev,
1891 from_location: loc.name,
1892 from_latitude: loc.latitude,
1893 from_longitude: loc.longitude
1894 })),
1895 label: "",
1896 placeholder: __(
1897 "Search for starting location...",
1898 "yatra"
1899 ),
1900 helpText: "",
1901 required: false,
1902 defaultMapCenter: formData.from_latitude && formData.from_longitude ? [
1903 parseFloat(formData.from_latitude),
1904 parseFloat(formData.from_longitude)
1905 ] : (tripForLocations == null ? void 0 : tripForLocations.starting_latitude) && (tripForLocations == null ? void 0 : tripForLocations.starting_longitude) ? [
1906 parseFloat(
1907 String(
1908 tripForLocations.starting_latitude
1909 )
1910 ),
1911 parseFloat(
1912 String(
1913 tripForLocations.starting_longitude
1914 )
1915 )
1916 ] : [20, 0],
1917 defaultZoom: formData.from_latitude && formData.from_longitude ? 13 : (tripForLocations == null ? void 0 : tripForLocations.starting_latitude) && (tripForLocations == null ? void 0 : tripForLocations.starting_longitude) ? 13 : 2,
1918 mapHeight: "300px",
1919 showMapButton: false,
1920 searchLimit: 8,
1921 __,
1922 className: "",
1923 mapClassName: "rounded-lg",
1924 showManualCoordinateFields: true
1925 }
1926 ),
1927 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __(
1928 "Default: trip starting location. Set per rule to override.",
1929 "yatra"
1930 ) })
1931 ] })
1932 ] }),
1933 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1934 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 p-4 bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 rounded-xl border border-green-200 dark:border-green-800", children: [
1935 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center shadow-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "w-5 h-5 text-white" }) }),
1936 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
1937 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-green-900 dark:text-green-100", children: __("Ending Point", "yatra") }),
1938 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-700 dark:text-green-300", children: __("Where the journey concludes", "yatra") })
1939 ] }),
1940 formData.to_latitude && formData.to_longitude && /* @__PURE__ */ jsxRuntimeExports.jsx(
1941 "div",
1942 {
1943 className: "w-2 h-2 bg-green-500 rounded-full",
1944 title: __("Coordinates set", "yatra")
1945 }
1946 )
1947 ] }),
1948 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
1949 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: __("To location (destination)", "yatra") }),
1950 /* @__PURE__ */ jsxRuntimeExports.jsx(
1951 LocationPicker,
1952 {
1953 value: {
1954 name: formData.to_location || "",
1955 latitude: formData.to_latitude || "",
1956 longitude: formData.to_longitude || ""
1957 },
1958 onChange: (loc) => setFormData((prev) => ({
1959 ...prev,
1960 to_location: loc.name,
1961 to_latitude: loc.latitude,
1962 to_longitude: loc.longitude
1963 })),
1964 label: "",
1965 placeholder: __(
1966 "Search for ending location...",
1967 "yatra"
1968 ),
1969 helpText: "",
1970 required: false,
1971 defaultMapCenter: formData.to_latitude && formData.to_longitude ? [
1972 parseFloat(formData.to_latitude),
1973 parseFloat(formData.to_longitude)
1974 ] : (tripForLocations == null ? void 0 : tripForLocations.ending_latitude) && (tripForLocations == null ? void 0 : tripForLocations.ending_longitude) ? [
1975 parseFloat(
1976 String(
1977 tripForLocations.ending_latitude
1978 )
1979 ),
1980 parseFloat(
1981 String(
1982 tripForLocations.ending_longitude
1983 )
1984 )
1985 ] : formData.from_latitude && formData.from_longitude ? [
1986 parseFloat(formData.from_latitude),
1987 parseFloat(formData.from_longitude)
1988 ] : (tripForLocations == null ? void 0 : tripForLocations.starting_latitude) && (tripForLocations == null ? void 0 : tripForLocations.starting_longitude) ? [
1989 parseFloat(
1990 String(
1991 tripForLocations.starting_latitude
1992 )
1993 ),
1994 parseFloat(
1995 String(
1996 tripForLocations.starting_longitude
1997 )
1998 )
1999 ] : [20, 0],
2000 defaultZoom: formData.to_latitude && formData.to_longitude ? 13 : (tripForLocations == null ? void 0 : tripForLocations.ending_latitude) && (tripForLocations == null ? void 0 : tripForLocations.ending_longitude) ? 13 : formData.from_latitude && formData.from_longitude ? 13 : (tripForLocations == null ? void 0 : tripForLocations.starting_latitude) && (tripForLocations == null ? void 0 : tripForLocations.starting_longitude) ? 13 : 2,
2001 mapHeight: "300px",
2002 showMapButton: false,
2003 searchLimit: 8,
2004 __,
2005 className: "",
2006 mapClassName: "rounded-lg",
2007 showManualCoordinateFields: true
2008 }
2009 ),
2010 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __(
2011 "Default: trip ending location. Set per rule to override.",
2012 "yatra"
2013 ) })
2014 ] })
2015 ] })
2016 ] }),
2017 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
2018 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Booking Cutoff (hours before)", "yatra") }),
2019 /* @__PURE__ */ jsxRuntimeExports.jsx(
2020 Input,
2021 {
2022 type: "number",
2023 min: 0,
2024 value: formData.cutoff_hours,
2025 onChange: (e) => setFormData((prev) => ({
2026 ...prev,
2027 cutoff_hours: parseInt(e.target.value) || 0
2028 }))
2029 }
2030 )
2031 ] })
2032 ] })
2033 ] })
2034 ] })
2035 ] }),
2036 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
2037 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
2038 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Status", "yatra") }) }),
2039 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2040 Select,
2041 {
2042 value: formData.status,
2043 onChange: (e) => setFormData((prev) => ({
2044 ...prev,
2045 status: e.target.value
2046 })),
2047 children: [
2048 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "active", children: __("Active", "yatra") }),
2049 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "inactive", children: __("Inactive", "yatra") })
2050 ]
2051 }
2052 ) })
2053 ] }),
2054 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
2055 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
2056 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2", children: [
2057 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-5 h-5" }),
2058 __("Preview", "yatra")
2059 ] }),
2060 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __("See which dates will be generated", "yatra") })
2061 ] }),
2062 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
2063 /* @__PURE__ */ jsxRuntimeExports.jsxs(
2064 Button,
2065 {
2066 type: "button",
2067 variant: "outline",
2068 className: "w-full mb-4",
2069 onClick: () => previewMutation.mutate(formData),
2070 disabled: previewMutation.isPending || !formData.trip_id,
2071 children: [
2072 previewMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-4 h-4 mr-2" }),
2073 __("Generate Preview", "yatra")
2074 ]
2075 }
2076 ),
2077 previewData && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
2078 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-sm", children: [
2079 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 dark:text-gray-400", children: __("Total dates:", "yatra") }),
2080 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "success", children: previewData.total })
2081 ] }),
2082 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-h-48 overflow-y-auto space-y-1", children: [
2083 previewData.dates && Array.isArray(previewData.dates) && previewData.dates.map((date, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
2084 "div",
2085 {
2086 className: "text-xs px-2 py-1 bg-gray-50 dark:bg-gray-800 rounded flex justify-between",
2087 children: [
2088 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: toDateValue(
2089 date.departure_date
2090 ).toLocaleDateString("en-US", {
2091 weekday: "short",
2092 month: "short",
2093 day: "numeric",
2094 year: "numeric"
2095 }) }),
2096 date.departure_time && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: date.departure_time })
2097 ]
2098 },
2099 index
2100 )),
2101 previewData.total > 20 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 text-center py-1", children: [
2102 "+",
2103 previewData.total - 20,
2104 " ",
2105 __("more dates", "yatra")
2106 ] })
2107 ] })
2108 ] })
2109 ] })
2110 ] }),
2111 /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "pt-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
2112 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { type: "submit", className: "w-full", disabled: isLoading, children: [
2113 isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "w-4 h-4 mr-2" }),
2114 isEditing ? __("Update Rule", "yatra") : __("Create Rule", "yatra")
2115 ] }),
2116 /* @__PURE__ */ jsxRuntimeExports.jsx(
2117 Button,
2118 {
2119 type: "button",
2120 variant: "outline",
2121 className: "w-full",
2122 onClick: () => {
2123 var _a2;
2124 return navigate({
2125 subpage: "trips",
2126 tab: "availability",
2127 trip_id: ((_a2 = formData.trip_id) == null ? void 0 : _a2.toString()) || tripIdFromUrl || ""
2128 });
2129 },
2130 children: __("Cancel", "yatra")
2131 }
2132 )
2133 ] }) }) }),
2134 /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-2", children: [
2135 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-medium", children: __("How it works", "yatra") }),
2136 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400 mt-1", children: __(
2137 "Dates are generated automatically based on your pattern. Manually added specific dates will take priority over generated dates.",
2138 "yatra"
2139 ) })
2140 ] }) })
2141 ] })
2142 ] }) })
2143 ] });
2144 };
2145 export {
2146 RecurringRuleForm as default
2147 };
2148 //# sourceMappingURL=RecurringRuleForm-CZVn9vM6.js.map
2149