PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.13
Yatra – Travel Booking & Tour Operator Software v3.0.13
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 / resources / js / components / itinerary / DayFormFields.tsx

DayFormFields.tsx in Yatra – Travel Booking & Tour Operator Software 3.0.13, at resources/js/components/itinerary/DayFormFields.tsx

237 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Day Form Fields Component
3 * Displays the form fields for creating/editing a day
4 */
5
6 import React from "react";
7 import { Info, Lock } from "lucide-react";
8 import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
9 import { Input } from "../ui/input";
10 import { SearchableSelect } from "../ui/searchable-select";
11 import { HelpText } from "../ui/help-text";
12 import { __ } from "../../lib/i18n";
13
14 interface DayFormFieldsProps {
15 formData: {
16 trip_id: string;
17 day: string;
18 day_title: string;
19 day_description: string;
20 };
21 errors: Record<string, string>;
22 tripsData: any[];
23 isLoadingTrips: boolean;
24 isEditMode?: boolean; // If true, disable trip field
25 isSingleDayTrip?: boolean; // If true, hide/disable day number field
26 onFieldChange: (
27 field: keyof DayFormFieldsProps["formData"],
28 value: any,
29 ) => void;
30 }
31 export const DayFormFields: React.FC<DayFormFieldsProps> = ({
32 formData,
33 errors,
34 tripsData,
35 isLoadingTrips,
36 isEditMode = false,
37 isSingleDayTrip = false,
38 onFieldChange,
39 }) => {
40 return (
41 <Card>
42 <CardHeader className="pb-2">
43 <CardTitle className="text-base">
44 {__("Day Information", "yatra")}
45 </CardTitle>
46 </CardHeader>
47 <CardContent className="space-y-3">
48 <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
49 <div>
50 <label
51 htmlFor="trip_id"
52 className="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5"
53 >
54 {__("Trip", "yatra")} <span className="text-red-500">*</span>
55 {isEditMode && (
56 <span
57 title={__(
58 "This field cannot be changed in edit mode",
59 "yatra",
60 )}
61 >
62 <Lock className="w-4 h-4 text-gray-400" />
63 </span>
64 )}
65 </label>
66 <HelpText
67 text={
68 isEditMode
69 ? __(
70 "The trip cannot be changed when editing a day.",
71 "yatra",
72 )
73 : __("Select the trip this day belongs to.", "yatra")
74 }
75 className="mb-2"
76 />
77 <div className="relative">
78 <SearchableSelect
79 value={formData.trip_id}
80 onChange={(value) => onFieldChange("trip_id", value)}
81 options={[
82 { value: "", label: __("-- Select a Trip --", "yatra") },
83 ...((Array.isArray(tripsData) ? tripsData : []).map(
84 (trip: any) => ({
85 value: trip.id.toString(),
86 label: `${trip.title || trip.name || ""}${trip.trip_type === "single_day" ? " (Single Day)" : trip.trip_type === "multi_day" ? " (Multi-Day)" : ""}`,
87 }),
88 ) || []),
89 ]}
90 placeholder={__("Search or select a trip...", "yatra")}
91 searchPlaceholder={__("Search by trip name or ID...", "yatra")}
92 className={errors.trip_id ? "border-red-500" : ""}
93 error={!!errors.trip_id}
94 required
95 disabled={isLoadingTrips || isEditMode}
96 />
97 {isEditMode && (
98 <div className="absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none">
99 <Lock className="w-4 h-4 text-gray-400" />
100 </div>
101 )}
102 </div>
103 {errors.trip_id && (
104 <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1">
105 <Info className="w-4 h-4" />
106 {errors.trip_id}
107 </p>
108 )}
109 </div>
110
111 {!isSingleDayTrip && (
112 <div>
113 <label
114 htmlFor="day"
115 className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5"
116 >
117 {__("Day Number", "yatra")}{" "}
118 <span className="text-red-500">*</span>
119 </label>
120 <HelpText
121 text={__("Which day number is this in the itinerary?", "yatra")}
122 className="mb-2"
123 />
124 <Input
125 id="day"
126 type="number"
127 min="1"
128 value={formData.day}
129 onChange={(e) => onFieldChange("day", e.target.value)}
130 className={errors.day ? "border-red-500" : ""}
131 required
132 />
133 {errors.day && (
134 <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1">
135 <Info className="w-4 h-4" />
136 {errors.day}
137 </p>
138 )}
139 </div>
140 )}
141 {isSingleDayTrip && (
142 <div>
143 <label
144 htmlFor="day"
145 className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5"
146 >
147 {__("Entry Number", "yatra")}{" "}
148 <span className="text-red-500">*</span>
149 </label>
150 <HelpText
151 text={__(
152 "Entry number for ordering entries in this single-day trip.",
153 "yatra",
154 )}
155 className="mb-2"
156 />
157 <Input
158 id="day"
159 type="number"
160 min="1"
161 value={formData.day}
162 onChange={(e) => onFieldChange("day", e.target.value)}
163 className={errors.day ? "border-red-500" : ""}
164 required
165 />
166 {errors.day && (
167 <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1">
168 <Info className="w-4 h-4" />
169 {errors.day}
170 </p>
171 )}
172 </div>
173 )}
174 </div>
175
176 <div>
177 <label
178 htmlFor="day_title"
179 className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5"
180 >
181 {__("Day Title (Optional)", "yatra")}
182 </label>
183 <HelpText
184 text={__(
185 'A descriptive title for this day (e.g., "Arrival & Welcome to Paradise").',
186 "yatra",
187 )}
188 className="mb-2"
189 />
190 <Input
191 id="day_title"
192 type="text"
193 value={formData.day_title}
194 onChange={(e) => onFieldChange("day_title", e.target.value)}
195 placeholder={__("e.g., Arrival & Welcome to Paradise", "yatra")}
196 />
197 </div>
198
199 <div>
200 <label
201 htmlFor="day_description"
202 className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5"
203 >
204 {__("Day Description (Optional)", "yatra")}
205 </label>
206 <HelpText
207 text={__(
208 "A detailed description of what happens on this day, activities, highlights, etc.",
209 "yatra",
210 )}
211 className="mb-2"
212 />
213 <textarea
214 id="day_description"
215 value={formData.day_description}
216 onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
217 onFieldChange("day_description", e.target.value)
218 }
219 placeholder={__(
220 "Describe the activities, highlights, and details for this day...",
221 "yatra",
222 )}
223 rows={4}
224 className={`w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent ${errors.day_description ? "border-red-500" : ""}`}
225 />
226 {errors.day_description && (
227 <p className="mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1">
228 <Info className="w-4 h-4" />
229 {errors.day_description}
230 </p>
231 )}
232 </div>
233 </CardContent>
234 </Card>
235 );
236 };
237