import React, { useEffect, useState } from "react"; import { View, ScrollView, ActivityIndicator, Pressable, Modal, TextInput, KeyboardAvoidingView, Platform, } from "react-native"; import { ScreenWrapper } from "@/components/ScreenWrapper"; import { StandardHeader } from "@/components/StandardHeader"; import { Text } from "@/components/ui/text"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { supportApi } from "@/lib/api"; import { useAuthStore } from "@/lib/auth-store"; import { toast } from "@/lib/toast-store"; import { Plus, MessageSquare, AlertCircle, Clock, CheckCircle2, X, Calendar, User as UserIcon, Tag, } from "@/lib/icons"; import { useColorScheme } from "nativewind"; import { cn } from "@/lib/utils"; interface SupportTicket { id: string; ticketNumber: string; subject: string; message: string; status: "OPEN" | "PENDING" | "IN_PROGRESS" | "RESOLVED" | "CLOSED"; priority: "URGENT" | "HIGH" | "MEDIUM" | "LOW"; createdAt: string; updatedAt: string; resolution?: string; requesterName?: string; requesterEmail: string; } const PRIORITIES = [ { label: "Urgent", value: "URGENT", color: "text-red-500", bg: "bg-red-500/10", dot: "bg-red-500", }, { label: "High", value: "HIGH", color: "text-orange-500", bg: "bg-orange-500/10", dot: "bg-orange-500", }, { label: "Medium", value: "MEDIUM", color: "text-blue-500", bg: "bg-blue-500/10", dot: "bg-blue-500", }, { label: "Low", value: "LOW", color: "text-green-500", bg: "bg-green-500/10", dot: "bg-green-500", }, ] as const; export default function HelpScreen() { const [tickets, setTickets] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); const [selectedTicket, setSelectedTicket] = useState( null, ); const [isSubmitting, setIsSubmitting] = useState(false); // Form State const [subject, setSubject] = useState(""); const [message, setMessage] = useState(""); const [priority, setPriority] = useState< "URGENT" | "HIGH" | "MEDIUM" | "LOW" >("MEDIUM"); const { user } = useAuthStore(); const { colorScheme } = useColorScheme(); const isDark = colorScheme === "dark"; const iconColor = isDark ? "#f1f5f9" : "#0f172a"; const fetchTickets = async () => { try { const response = await supportApi.getAll(); const ticketData = (response as any)?.data || response; setTickets(Array.isArray(ticketData) ? ticketData : []); } catch (error) { console.error("[Support] Fetch failed:", error); setTickets([]); } finally { setLoading(false); } }; useEffect(() => { fetchTickets(); }, []); const handleSubmit = async () => { const cleanSubject = subject.trim(); const cleanMessage = message.trim(); console.log( "[Support] handleSubmit - subject length:", cleanSubject.length, ); console.log( "[Support] handleSubmit - message length:", cleanMessage.length, ); if (!cleanSubject || !cleanMessage) { console.log("[Support] Validation failed: Empty fields"); toast.error("Required Fields", "Please enter a subject and message."); return; } if (cleanSubject.length < 5) { console.log("[Support] Validation failed: Subject too short"); toast.error( "Subject too short", "The subject must be at least 5 characters.", ); return; } if (cleanMessage.length < 10) { console.log("[Support] Validation failed: Message too short"); toast.error( "Message too short", "Please describe your issue in more detail (min 10 chars).", ); return; } setIsSubmitting(true); try { console.log("[Support] Sending ticket data..."); const payload = { requesterEmail: user?.email && user.email.includes("@") ? user.email : "anonymous@yaltopia.com", requesterName: `${user?.firstName || ""} ${user?.lastName || ""}`.trim() || "Anonymous", subject: cleanSubject, message: cleanMessage, priority, }; console.log("[Support] Payload:", JSON.stringify(payload)); await supportApi.create({ body: payload, }); console.log("[Support] Ticket created successfully"); toast.success("Ticket Created", "We'll get back to you soon."); setIsModalVisible(false); setSubject(""); setMessage(""); setPriority("MEDIUM"); fetchTickets(); } catch (error: any) { console.error("[Support] Create failed:", error); const errorMsg = Array.isArray(error?.message) ? error.message.join(", ") : error?.message || "Could not create support ticket."; toast.error("Submission Failed", errorMsg); } finally { setIsSubmitting(false); } }; const getStatusInfo = (status: string) => { switch (status) { case "OPEN": case "PENDING": return { label: status, color: "text-blue-500", bg: "bg-blue-500/10", icon: , }; case "IN_PROGRESS": return { label: "In Progress", color: "text-orange-500", bg: "bg-orange-500/10", icon: , }; case "RESOLVED": case "CLOSED": return { label: status, color: "text-green-500", bg: "bg-green-500/10", icon: , }; default: return { label: status, color: "text-muted-foreground", bg: "bg-muted/10", icon: , }; } }; return ( setIsModalVisible(true)} className="h-10 w-10 rounded-[10px] bg-card items-center justify-center border border-border" > } /> {loading ? ( ) : ( {tickets.length === 0 ? ( All clear You don't have any active support tickets. Need assistance? Create one now. ) : ( {tickets.map((ticket: any) => { const pInfo = PRIORITIES.find((p) => p.value === ticket.priority) || PRIORITIES[2]; const sInfo = getStatusInfo(ticket.status); return ( setSelectedTicket(ticket)} > {ticket.ticketNumber} {new Date(ticket.createdAt).toLocaleDateString(undefined, { month: "short", day: "numeric", })} {ticket.subject} {pInfo.label} {sInfo.label} ); })} )} )} {/* Ticket Detail Modal */} setSelectedTicket(null)} > TICKET {selectedTicket?.ticketNumber} setSelectedTicket(null)} className="h-8 w-8 rounded-lg items-center justify-center" > {selectedTicket?.subject} {selectedTicket?.priority} {selectedTicket && getStatusInfo(selectedTicket.status).icon} {selectedTicket?.status} {selectedTicket?.message} {selectedTicket?.resolution && ( Resolution {selectedTicket.resolution} )} Created {selectedTicket && new Date(selectedTicket.createdAt).toLocaleDateString()} Requester {selectedTicket?.requesterName || selectedTicket?.requesterEmail} {/* New Ticket Modal */} setIsModalVisible(false)} > New Ticket setIsModalVisible(false)} className="h-8 w-8 rounded-lg items-center justify-center" > Subject Priority {PRIORITIES.map((p) => ( setPriority(p.value)} className={cn( "px-4 py-1.5 rounded-[4px] border", priority === p.value ? "border-primary bg-primary/10" : "border-border bg-card", )} > {p.label} ))} Message ); }