Add admin order details modal and improve admin UI
Introduces an admin-only OrderDetailsModal component for viewing and managing order details, including status updates and transaction info. Updates OrdersTable to support the modal, and enhances the admin dashboard page with lazy loading and skeletons for better UX. Also fixes API client base URL handling for /api prefix.
This commit is contained in:
@@ -1,16 +1,61 @@
|
||||
"use client";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
import React from "react";
|
||||
import AdminAnalytics from "@/components/admin/AdminAnalytics";
|
||||
import InviteVendorCard from "@/components/admin/InviteVendorCard";
|
||||
import BanUserCard from "@/components/admin/BanUserCard";
|
||||
import InvitationsListCard from "@/components/admin/InvitationsListCard";
|
||||
import VendorsCard from "@/components/admin/VendorsCard";
|
||||
import React, { Suspense, lazy, useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import Link from "next/link";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
|
||||
// Lazy load admin components
|
||||
const AdminAnalytics = lazy(() => import("@/components/admin/AdminAnalytics"));
|
||||
const InviteVendorCard = lazy(() => import("@/components/admin/InviteVendorCard"));
|
||||
const BanUserCard = lazy(() => import("@/components/admin/BanUserCard"));
|
||||
const InvitationsListCard = lazy(() => import("@/components/admin/InvitationsListCard"));
|
||||
const VendorsCard = lazy(() => import("@/components/admin/VendorsCard"));
|
||||
|
||||
// Loading skeleton for admin components
|
||||
function AdminComponentSkeleton() {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Skeleton className="h-6 w-48" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-full" />
|
||||
<Skeleton className="h-4 w-3/4" />
|
||||
<Skeleton className="h-4 w-1/2" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Loading skeleton for management cards
|
||||
function ManagementCardsSkeleton() {
|
||||
return (
|
||||
<div className="grid gap-4 lg:gap-6 sm:grid-cols-2 lg:grid-cols-3 items-stretch">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<Card key={i}>
|
||||
<CardHeader>
|
||||
<Skeleton className="h-6 w-32" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-20 w-full" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AdminPage() {
|
||||
const [activeTab, setActiveTab] = useState("analytics");
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -23,23 +68,27 @@ export default function AdminPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="analytics" className="space-y-6">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-6">
|
||||
<TabsList>
|
||||
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
||||
<TabsTrigger value="management">Management</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="analytics" className="space-y-6">
|
||||
<AdminAnalytics />
|
||||
<Suspense fallback={<AdminComponentSkeleton />}>
|
||||
<AdminAnalytics />
|
||||
</Suspense>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="management" className="space-y-6">
|
||||
<div className="grid gap-4 lg:gap-6 sm:grid-cols-2 lg:grid-cols-3 items-stretch">
|
||||
<VendorsCard />
|
||||
<InviteVendorCard />
|
||||
<BanUserCard />
|
||||
<InvitationsListCard />
|
||||
</div>
|
||||
<Suspense fallback={<ManagementCardsSkeleton />}>
|
||||
<div className="grid gap-4 lg:gap-6 sm:grid-cols-2 lg:grid-cols-3 items-stretch">
|
||||
<VendorsCard />
|
||||
<InviteVendorCard />
|
||||
<BanUserCard />
|
||||
<InvitationsListCard />
|
||||
</div>
|
||||
</Suspense>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user