PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.9
Yatra – Travel Booking & Tour Operator Software v3.0.2.9
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 / pages / account / Support.tsx

Support.tsx in Yatra – Travel Booking & Tour Operator Software 3.0.2.9, at resources/js/pages/account/Support.tsx

314 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useState } from "react";
2 import {
3 LifeBuoy,
4 AlertTriangle,
5 CheckCircle,
6 Clock as ClockIcon,
7 FileText as FileTextIcon,
8 Eye,
9 Phone as PhoneIcon,
10 Mail,
11 } from "lucide-react";
12 import { __ } from "../../lib/i18n";
13 import { formatDate, getBadge } from "./utils";
14 import type { SupportTicket } from "./types";
15
16 interface SupportProps {
17 tickets: SupportTicket[];
18 }
19
20 const Support: React.FC<SupportProps> = ({ tickets }) => {
21 const [ticketSubject, setTicketSubject] = useState("");
22 const [ticketMessage, setTicketMessage] = useState("");
23
24 const displayTickets = tickets;
25
26 const handleSubmitTicket = (e: React.FormEvent) => {
27 e.preventDefault();
28 // TODO: Implement ticket submission
29 setTicketSubject("");
30 setTicketMessage("");
31 };
32
33 const getStatusIcon = (status: string) => {
34 switch (status) {
35 case "resolved":
36 return (
37 <CheckCircle className="w-4 h-4 text-emerald-600 dark:text-emerald-400" />
38 );
39 case "awaiting_response":
40 return (
41 <ClockIcon className="w-4 h-4 text-amber-600 dark:text-amber-400" />
42 );
43 case "open":
44 return (
45 <AlertTriangle className="w-4 h-4 text-blue-600 dark:text-blue-400" />
46 );
47 default:
48 return (
49 <LifeBuoy className="w-4 h-4 text-gray-600 dark:text-gray-400" />
50 );
51 }
52 };
53
54 return (
55 <div className="yatra-support-page space-y-6">
56 {/* Header */}
57 <div className="yatra-support-header bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl shadow-sm p-6">
58 <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
59 <div>
60 <h2 className="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-3">
61 <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
62 <LifeBuoy className="w-6 h-6 text-blue-600 dark:text-blue-400" />
63 </div>
64 {__("Support & Help Center", "yatra")}
65 </h2>
66 <p className="text-sm text-gray-500 dark:text-gray-400 mt-2">
67 {__(
68 "Our team is available 24/7 for urgent requests. Submit a ticket or contact us directly.",
69 "yatra",
70 )}
71 </p>
72 </div>
73 </div>
74 </div>
75
76 {/* Support Statistics */}
77 <div className="yatra-support-stats flex flex-nowrap gap-6 overflow-x-auto">
78 <div className="flex-shrink-0 yatra-support-stat-card bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl p-6 min-w-0 flex-1">
79 <div className="flex items-center justify-between">
80 <div>
81 <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">
82 {__("Total Tickets", "yatra")}
83 </p>
84 <p className="text-xl font-bold text-gray-900 dark:text-white">
85 {displayTickets.length}
86 </p>
87 </div>
88 <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
89 <LifeBuoy className="w-5 h-5 text-blue-600 dark:text-blue-400" />
90 </div>
91 </div>
92 </div>
93 <div className="flex-shrink-0 yatra-support-stat-card bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl p-6 min-w-0 flex-1">
94 <div className="flex items-center justify-between">
95 <div>
96 <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">
97 {__("Open", "yatra")}
98 </p>
99 <p className="text-xl font-bold text-blue-600 dark:text-blue-400">
100 {
101 displayTickets.filter(
102 (t) =>
103 t.status === "open" || t.status === "awaiting_response",
104 ).length
105 }
106 </p>
107 </div>
108 <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
109 <AlertTriangle className="w-5 h-5 text-blue-600 dark:text-blue-400" />
110 </div>
111 </div>
112 </div>
113 <div className="flex-shrink-0 yatra-support-stat-card bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl p-6 min-w-0 flex-1">
114 <div className="flex items-center justify-between">
115 <div>
116 <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">
117 {__("Resolved", "yatra")}
118 </p>
119 <p className="text-xl font-bold text-emerald-600 dark:text-emerald-400">
120 {displayTickets.filter((t) => t.status === "resolved").length}
121 </p>
122 </div>
123 <div className="p-2 bg-emerald-50 dark:bg-emerald-900/20 rounded-lg">
124 <CheckCircle className="w-5 h-5 text-emerald-600 dark:text-emerald-400" />
125 </div>
126 </div>
127 </div>
128 </div>
129
130 {/* Create New Ticket */}
131 <div className="yatra-support-form-card bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl shadow-sm p-6">
132 <div className="yatra-support-form-header flex items-center gap-3 mb-6">
133 <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
134 <LifeBuoy className="w-6 h-6 text-blue-600 dark:text-blue-400" />
135 </div>
136 <div>
137 <h3 className="text-base font-semibold text-gray-900 dark:text-white">
138 {__("Create a new support ticket", "yatra")}
139 </h3>
140 <p className="text-sm text-gray-500 dark:text-gray-400">
141 {__(
142 "Please describe your issue and we will get back to you as soon as possible.",
143 "yatra",
144 )}
145 </p>
146 </div>
147 </div>
148 <form
149 onSubmit={handleSubmitTicket}
150 className="yatra-support-form space-y-4"
151 >
152 <div>
153 <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
154 {__("Subject", "yatra")} <span className="text-red-500">*</span>
155 </label>
156 <input
157 type="text"
158 value={ticketSubject}
159 onChange={(e) => setTicketSubject(e.target.value)}
160 placeholder={__("Enter ticket subject", "yatra")}
161 required
162 className="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
163 />
164 </div>
165 <div>
166 <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
167 {__("Message", "yatra")} <span className="text-red-500">*</span>
168 </label>
169 <textarea
170 value={ticketMessage}
171 onChange={(e) => setTicketMessage(e.target.value)}
172 placeholder={__("How can we help?", "yatra")}
173 required
174 rows={6}
175 className="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
176 />
177 </div>
178 <button
179 type="submit"
180 className="yatra-support-submit-btn inline-flex items-center gap-2 px-6 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition-colors text-sm font-medium"
181 >
182 <LifeBuoy className="w-4 h-4" /> {__("Submit Ticket", "yatra")}
183 </button>
184 </form>
185 </div>
186
187 {/* Support Tickets List */}
188 <div className="yatra-support-tickets bg-white dark:bg-gray-800 border border-gray-100 dark:border-gray-700 rounded-xl shadow-sm p-6">
189 <div className="flex items-center justify-between mb-6">
190 <h3 className="text-base font-semibold text-gray-900 dark:text-white flex items-center gap-2">
191 <FileTextIcon className="w-5 h-5 text-gray-600 dark:text-gray-400" />
192 {__("Your Support Tickets", "yatra")}
193 </h3>
194 </div>
195 {displayTickets.length === 0 ? (
196 <div className="text-center py-12">
197 <LifeBuoy className="w-16 h-16 text-gray-300 dark:text-gray-600 mx-auto mb-4" />
198 <p className="text-gray-500 dark:text-gray-400 font-medium mb-1">
199 {__("No support tickets yet", "yatra")}
200 </p>
201 <p className="text-sm text-gray-400 dark:text-gray-500">
202 {__("Create a ticket above to get started.", "yatra")}
203 </p>
204 </div>
205 ) : (
206 <div className="yatra-support-tickets-list space-y-4">
207 {displayTickets.map((ticket) => {
208 const isResolved = ticket.status === "resolved";
209 const isAwaiting = ticket.status === "awaiting_response";
210
211 return (
212 <div
213 key={ticket.id}
214 className="yatra-support-ticket-card group bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 hover:shadow-md transition-all"
215 >
216 <div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4">
217 <div className="flex-1">
218 <div className="flex items-start gap-3 mb-3">
219 <div
220 className={`p-2 rounded-lg ${
221 isResolved
222 ? "bg-emerald-50 dark:bg-emerald-900/20"
223 : isAwaiting
224 ? "bg-amber-50 dark:bg-amber-900/20"
225 : "bg-blue-50 dark:bg-blue-900/20"
226 }`}
227 >
228 {getStatusIcon(ticket.status)}
229 </div>
230 <div className="flex-1">
231 <h4 className="text-base font-semibold text-gray-900 dark:text-white mb-1">
232 {ticket.subject}
233 </h4>
234 <p className="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
235 <ClockIcon className="w-4 h-4" />
236 {__("Last updated", "yatra")}:{" "}
237 {formatDate(ticket.updated_at)}
238 </p>
239 </div>
240 </div>
241 </div>
242 <div className="flex items-center gap-3">
243 <span className={getBadge(ticket.status)}>
244 {__(ticket.status, ticket.status)}
245 </span>
246 <div
247 role="button"
248 tabIndex={0}
249 onClick={() => {}}
250 className="yatra-support-ticket-view inline-flex items-center gap-2 px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-sm font-medium cursor-pointer"
251 >
252 <Eye className="w-4 h-4" />
253 {__("View", "yatra")}
254 </div>
255 </div>
256 </div>
257 </div>
258 );
259 })}
260 </div>
261 )}
262 </div>
263
264 {/* Contact Information */}
265 <div
266 className="yatra-support-contact rounded-xl p-6 text-white shadow-xl"
267 style={{
268 backgroundColor: "#2563eb",
269 backgroundImage: "linear-gradient(to bottom right, #2563eb, #4f46e5)",
270 }}
271 >
272 <div className="flex items-start gap-4">
273 <div className="p-3 bg-white/20 rounded-lg flex-shrink-0">
274 <PhoneIcon className="w-6 h-6 text-white" />
275 </div>
276 <div className="flex-1">
277 <h3 className="text-base font-semibold text-white mb-2">
278 {__("Need Immediate Assistance?", "yatra")}
279 </h3>
280 <p className="text-sm text-white/90 mb-4">
281 {__(
282 "Call our 24/7 concierge desk for urgent travel support.",
283 "yatra",
284 )}
285 </p>
286 <div className="flex flex-wrap gap-4">
287 <div className="flex items-center gap-2">
288 <PhoneIcon className="w-4 h-4 text-white flex-shrink-0" />
289 <a
290 href="tel:+18005550199"
291 className="text-sm font-medium text-white hover:underline"
292 >
293 +1-800-555-0199
294 </a>
295 </div>
296 <div className="flex items-center gap-2">
297 <Mail className="w-4 h-4 text-white flex-shrink-0" />
298 <a
299 href="mailto:[email protected]"
300 className="text-sm font-medium text-white hover:underline"
301 >
302 [email protected]
303 </a>
304 </div>
305 </div>
306 </div>
307 </div>
308 </div>
309 </div>
310 );
311 };
312
313 export default Support;
314