import { useState, useEffect } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Smartphone, Wallet, Calendar, MessageSquare, CreditCard, Star, Clock, CheckCircle, AlertCircle, User, Bell, Settings } from "lucide-react"; import { apiRequest } from "@/lib/queryClient";

const topupSchema = z.object({ amount: z.number().min(100, "Minimum top-up amount is 100 BDT"), method: z.string().min(1, "Payment method is required"), reference_id: z.string().optional() });

const complaintSchema = z.object({ service_id: z.number().optional(), subject: z.string().min(1, "Subject is required"), description: z.string().min(10, "Please provide a detailed description"), priority: z.enum(["low", "medium", "high"]) });

export default function CustomerPortal() { const queryClient = useQueryClient(); const [selectedTab, setSelectedTab] = useState("dashboard");

// Simplified dashboard data query with proper error handling const { data: dashboardData, isLoading, error } = useQuery({ queryKey: ["/api/customer/dashboard"], retry: 1, refetchOnWindowFocus: false, staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000 });

// Wallet top-up mutation const topupMutation = useMutation({ mutationFn: async (data: z.infer<typeof topupSchema>) => { const res = await apiRequest("POST", "/api/customer/wallet/topup", { amount: data.amount, method: data.method || "online", reference_id: Date.now().toString() }); return res.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/customer/dashboard"] }); } });

// Complaint submission mutation const complaintMutation = useMutation({ mutationFn: async (data: z.infer<typeof complaintSchema>) => { const res = await apiRequest("POST", "/api/customer/complaints", data); return res.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/customer/dashboard"] }); } });

const topupForm = useForm<z.infer<typeof topupSchema>>({ resolver: zodResolver(topupSchema), defaultValues: { amount: 100, method: "online" } });

const complaintForm = useForm<z.infer<typeof complaintSchema>>({ resolver: zodResolver(complaintSchema), defaultValues: { priority: "medium" } });

// Only show loading for initial load if (isLoading && !dashboardData) { return ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto"></div> <p className="mt-4 text-gray-600">Loading dashboard...</p> </div> </div> ); }

// Handle error gracefully without reload if (error && !dashboardData) { return ( <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center"> <Card className="w-full max-w-md"> <CardHeader className="text-center"> <AlertCircle className="h-12 w-12 text-red-500 mx-auto mb-4" /> <CardTitle>Connection Issue</CardTitle> <CardDescription> Unable to load dashboard data. Please check your connection and try again. </CardDescription> </CardHeader> <CardContent className="text-center"> <Button onClick={() => window.location.reload()} className="w-full"> Retry </Button> </CardContent> </Card> </div> ); }

// Use data with fallbacks const user = dashboardData?.user || {}; const services = dashboardData?.services || []; const reservations = dashboardData?.reservations || []; const complaints = dashboardData?.complaints || []; const walletTransactions = dashboardData?.walletTransactions || [];

const getStatusColor = (status: string) => { switch (status) { case 'completed': return 'bg-green-100 text-green-800'; case 'in_progress': return 'bg-blue-100 text-blue-800'; case 'pending': return 'bg-yellow-100 text-yellow-800'; case 'cancelled': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; } };

return ( <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100"> {/* Header */} <div className="bg-white border-b border-gray-200 shadow-sm"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="flex justify-between items-center py-4"> <div className="flex items-center space-x-4"> <h1 className="text-2xl font-bold text-gray-900">Customer Portal</h1> <Badge variant="outline" className="bg-blue-50 text-blue-700"> {user?.name || 'Customer'} </Badge> </div> <div className="flex items-center space-x-4"> <div className="flex items-center space-x-2"> <Wallet className="h-5 w-5 text-green-600" /> <span className="font-semibold text-green-600"> ৳{user?.wallet_balance || '0.00'} </span> </div> <Button variant="outline" size="sm"> <Bell className="h-4 w-4" /> </Button> <Button variant="outline" size="sm"> <Settings className="h-4 w-4" /> </Button> </div> </div> </div> </div>

  {/* Main Content */}
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
    <Tabs value={selectedTab} onValueChange={setSelectedTab}>
      <TabsList className="grid w-full grid-cols-5">
        <TabsTrigger value="dashboard">Dashboard</TabsTrigger>
        <TabsTrigger value="services">My Services</TabsTrigger>
        <TabsTrigger value="wallet">Wallet</TabsTrigger>
        <TabsTrigger value="reservations">Reservations</TabsTrigger>
        <TabsTrigger value="complaints">Complaints</TabsTrigger>
      </TabsList>

      {/* Dashboard Tab */}
      <TabsContent value="dashboard" className="space-y-6">
        {/* Stats Cards */}
        <div className="grid grid-cols-1 md:grid-cols-4 gap-6">
          <Card>
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
              <CardTitle className="text-sm font-medium">Active Services</CardTitle>
              <Smartphone className="h-4 w-4 text-muted-foreground" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">{services.filter((s: any) => s.status === 'in_progress').length}</div>
            </CardContent>
          </Card>
          
          <Card>
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
              <CardTitle className="text-sm font-medium">Completed Services</CardTitle>
              <CheckCircle className="h-4 w-4 text-muted-foreground" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">{services.filter((s: any) => s.status === 'completed').length}</div>
            </CardContent>
          </Card>
          
          <Card>
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
              <CardTitle className="text-sm font-medium">Total Spent</CardTitle>
              <CreditCard className="h-4 w-4 text-muted-foreground" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">৳{services.reduce((total: number, s: any) => total + parseFloat(s.total_cost || '0'), 0).toFixed(2)}</div>
            </CardContent>
          </Card>
          
          <Card>
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
              <CardTitle className="text-sm font-medium">Wallet Balance</CardTitle>
              <Wallet className="h-4 w-4 text-muted-foreground" />
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">৳{user?.wallet_balance || '0.00'}</div>
            </CardContent>
          </Card>
        </div>

        {/* Recent Services */}
        <Card>
          <CardHeader>
            <CardTitle>Recent Services</CardTitle>
            <CardDescription>Your latest device repair and service requests</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-4">
              {services.slice(0, 5).map((service: any) => (
                <div key={service.id} className="flex items-center justify-between p-4 border rounded-lg">
                  <div className="flex items-center space-x-4">
                    <Smartphone className="h-8 w-8 text-blue-600" />
                    <div>
                      <p className="font-medium">{service.device_info || 'Device Service'}</p>
                      <p className="text-sm text-gray-500">Service ID: {service.service_id}</p>
                    </div>
                  </div>
                  <div className="text-right">
                    <Badge className={getStatusColor(service.status)}>{service.status}</Badge>
                    <p className="text-sm text-gray-500 mt-1">৳{service.total_cost}</p>
                  </div>
                </div>
              ))}
              {services.length === 0 && (
                <div className="text-center py-8 text-gray-500">
                  <Smartphone className="h-12 w-12 mx-auto mb-4 text-gray-300" />
                  <p>No services found</p>
                </div>
              )}
            </div>
          </CardContent>
        </Card>
      </TabsContent>

      {/* Services Tab */}
      <TabsContent value="services" className="space-y-6">
        <Card>
          <CardHeader>
            <CardTitle>My Services</CardTitle>
            <CardDescription>Track all your device repair and service requests</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-4">
              {services.map((service: any) => (
                <div key={service.id} className="border rounded-lg p-6">
                  <div className="flex justify-between items-start mb-4">
                    <div>
                      <h3 className="font-semibold text-lg">{service.device_info || 'Device Service'}</h3>
                      <p className="text-gray-500">Service ID: {service.service_id}</p>
                    </div>
                    <Badge className={getStatusColor(service.status)}>{service.status}</Badge>
                  </div>
                  
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
                    <div>
                      <p className="text-sm text-gray-500">Total Cost</p>
                      <p className="font-medium">৳{service.total_cost}</p>
                    </div>
                    <div>
                      <p className="text-sm text-gray-500">Created</p>
                      <p className="font-medium">{new Date(service.created_at).toLocaleDateString()}</p>
                    </div>
                    <div>
                      <p className="text-sm text-gray-500">Updated</p>
                      <p className="font-medium">{new Date(service.updated_at).toLocaleDateString()}</p>
                    </div>
                    <div>
                      <p className="text-sm text-gray-500">Completion</p>
                      <p className="font-medium">{service.completion_date ? new Date(service.completion_date).toLocaleDateString() : 'Pending'}</p>
                    </div>
                  </div>
                  
                  {service.description && (
                    <div className="mb-4">
                      <p className="text-sm text-gray-500">Description</p>
                      <p className="text-sm">{service.description}</p>
                    </div>
                  )}
                </div>
              ))}
              {services.length === 0 && (
                <div className="text-center py-12">
                  <Smartphone className="h-16 w-16 mx-auto mb-4 text-gray-300" />
                  <h3 className="text-lg font-medium text-gray-900 mb-2">No Services Found</h3>
                  <p className="text-gray-500">You haven't requested any services yet.</p>
                </div>
              )}
            </div>
          </CardContent>
        </Card>
      </TabsContent>

      {/* Wallet Tab */}
      <TabsContent value="wallet" className="space-y-6">
        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <Card>
            <CardHeader>
              <CardTitle>Wallet Balance</CardTitle>
              <CardDescription>Your current wallet balance</CardDescription>
            </CardHeader>
            <CardContent>
              <div className="text-3xl font-bold text-green-600 mb-4">৳{user?.wallet_balance || '0.00'}</div>
              
              <Dialog>
                <DialogTrigger asChild>
                  <Button className="w-full">
                    <CreditCard className="mr-2 h-4 w-4" />
                    Top Up Wallet
                  </Button>
                </DialogTrigger>
                <DialogContent>
                  <DialogHeader>
                    <DialogTitle>Top Up Wallet</DialogTitle>
                  </DialogHeader>
                  <Form {...topupForm}>
                    <form onSubmit={topupForm.handleSubmit((data) => topupMutation.mutate(data))} className="space-y-4">
                      <FormField
                        control={topupForm.control}
                        name="amount"
                        render={({ field }) => (
                          <FormItem>
                            <FormLabel>Amount (BDT)</FormLabel>
                            <FormControl>
                              <Input type="number" min="100" {...field} onChange={(e) => field.onChange(Number(e.target.value))} />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                      <FormField
                        control={topupForm.control}
                        name="method"
                        render={({ field }) => (
                          <FormItem>
                            <FormLabel>Payment Method</FormLabel>
                            <Select onValueChange={field.onChange} defaultValue={field.value}>
                              <FormControl>
                                <SelectTrigger>
                                  <SelectValue placeholder="Select payment method" />
                                </SelectTrigger>
                              </FormControl>
                              <SelectContent>
                                <SelectItem value="online">Online Payment</SelectItem>
                                <SelectItem value="bkash">bKash</SelectItem>
                                <SelectItem value="nagad">Nagad</SelectItem>
                                <SelectItem value="rocket">Rocket</SelectItem>
                              </SelectContent>
                            </Select>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                      <Button type="submit" className="w-full" disabled={topupMutation.isPending}>
                        {topupMutation.isPending ? "Processing..." : "Top Up"}
                      </Button>
                    </form>
                  </Form>
                </DialogContent>
              </Dialog>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Recent Transactions</CardTitle>
              <CardDescription>Your latest wallet transactions</CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-4">
                {walletTransactions.slice(0, 5).map((transaction: any) => (
                  <div key={transaction.id} className="flex justify-between items-center">
                    <div>
                      <p className="font-medium">{transaction.description || 'Transaction'}</p>
                      <p className="text-sm text-gray-500">{new Date(transaction.created_at).toLocaleDateString()}</p>
                    </div>
                    <div className={`font-medium ${transaction.amount > 0 ? 'text-green-600' : 'text-red-600'}`}>
                      {transaction.amount > 0 ? '+' : ''}৳{Math.abs(transaction.amount)}
                    </div>
                  </div>
                ))}
                {walletTransactions.length === 0 && (
                  <div className="text-center py-8 text-gray-500">
                    <CreditCard className="h-12 w-12 mx-auto mb-4 text-gray-300" />
                    <p>No transactions found</p>
                  </div>
                )}
              </div>
            </CardContent>
          </Card>
        </div>
      </TabsContent>

      {/* Reservations Tab */}
      <TabsContent value="reservations" className="space-y-6">
        <Card>
          <CardHeader>
            <CardTitle>My Reservations</CardTitle>
            <CardDescription>Your appointment reservations and bookings</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-4">
              {reservations.map((reservation: any) => (
                <div key={reservation.id} className="border rounded-lg p-6">
                  <div className="flex justify-between items-start mb-4">
                    <div>
                      <h3 className="font-semibold text-lg">Reservation #{reservation.id}</h3>
                      <p className="text-gray-500">{reservation.service_type || 'Service Reservation'}</p>
                    </div>
                    <Badge className={getStatusColor(reservation.status)}>{reservation.status}</Badge>
                  </div>
                  
                  <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
                    <div>
                      <p className="text-sm text-gray-500">Date</p>
                      <p className="font-medium">{new Date(reservation.reservation_date).toLocaleDateString()}</p>
                    </div>
                    <div>
                      <p className="text-sm text-gray-500">Time</p>
                      <p className="font-medium">{reservation.reservation_time || 'Not specified'}</p>
                    </div>
                    <div>
                      <p className="text-sm text-gray-500">Created</p>
                      <p className="font-medium">{new Date(reservation.created_at).toLocaleDateString()}</p>
                    </div>
                  </div>
                </div>
              ))}
              {reservations.length === 0 && (
                <div className="text-center py-12">
                  <Calendar className="h-16 w-16 mx-auto mb-4 text-gray-300" />
                  <h3 className="text-lg font-medium text-gray-900 mb-2">No Reservations Found</h3>
                  <p className="text-gray-500">You haven't made any reservations yet.</p>
                </div>
              )}
            </div>
          </CardContent>
        </Card>
      </TabsContent>

      {/* Complaints Tab */}
      <TabsContent value="complaints" className="space-y-6">
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <Card>
            <CardHeader>
              <CardTitle>Submit Complaint</CardTitle>
              <CardDescription>Report any issues or concerns</CardDescription>
            </CardHeader>
            <CardContent>
              <Form {...complaintForm}>
                <form onSubmit={complaintForm.handleSubmit((data) => complaintMutation.mutate(data))} className="space-y-4">
                  <FormField
                    control={complaintForm.control}
                    name="subject"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Subject</FormLabel>
                        <FormControl>
                          <Input placeholder="Brief description of the issue" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={complaintForm.control}
                    name="description"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Description</FormLabel>
                        <FormControl>
                          <Textarea placeholder="Detailed description of your complaint" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={complaintForm.control}
                    name="priority"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Priority</FormLabel>
                        <Select onValueChange={field.onChange} defaultValue={field.value}>
                          <FormControl>
                            <SelectTrigger>
                              <SelectValue placeholder="Select priority" />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            <SelectItem value="low">Low</SelectItem>
                            <SelectItem value="medium">Medium</SelectItem>
                            <SelectItem value="high">High</SelectItem>
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <Button type="submit" className="w-full" disabled={complaintMutation.isPending}>
                    {complaintMutation.isPending ? "Submitting..." : "Submit Complaint"}
                  </Button>
                </form>
              </Form>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>My Complaints</CardTitle>
              <CardDescription>Track your submitted complaints</CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-4">
                {complaints.map((complaint: any) => (
                  <div key={complaint.id} className="border rounded-lg p-4">
                    <div className="flex justify-between items-start mb-2">
                      <h4 className="font-medium">{complaint.subject}</h4>
                      <Badge className={getStatusColor(complaint.status)}>{complaint.status}</Badge>
                    </div>
                    <p className="text-sm text-gray-600 mb-2">{complaint.description}</p>
                    <p className="text-xs text-gray-500">
                      Submitted: {new Date(complaint.created_at).toLocaleDateString()}
                    </p>
                  </div>
                ))}
                {complaints.length === 0 && (
                  <div className="text-center py-8 text-gray-500">
                    <MessageSquare className="h-12 w-12 mx-auto mb-4 text-gray-300" />
                    <p>No complaints submitted</p>
                  </div>
                )}
              </div>
            </CardContent>
          </Card>
        </div>
      </TabsContent>
    </Tabs>
  </div>
</div>
); }

এইটা ডেস্কটপ ভিউর জন্য এবং মোবাইল ভিউর জন্য রেসপন্সিভ না। আর কাস্টমার ইন্টারফেস হবে আরো মর্ডন এবং ইন্টারএক্টিভ যেনো কাস্টমার ব্যবহার করে এবং দেখে তাদের ভালো লাগে আর ১০ টা এর মতো কোন রকম তাও আবার ফুল ফাংশনাল এবং লজিক্যাল না দেখতো তো ভালো করে