From 244014f33a94cbe767961d12ac6113d4cc48d747 Mon Sep 17 00:00:00 2001 From: g Date: Mon, 12 Jan 2026 07:33:16 +0000 Subject: [PATCH] Improve admin UI and vendor invite experience Enhanced the admin dashboard tab styling for better clarity. Refactored InviteVendorCard with improved UI, feedback, and clipboard copy functionality. Fixed vendor store ID update to send raw object instead of JSON string. Ensured product price formatting is robust against non-numeric values. --- app/dashboard/admin/page.tsx | 4 +- app/dashboard/admin/vendors/page.tsx | 2 +- components/admin/InviteVendorCard.tsx | 101 ++++++++++++++++++++------ components/dashboard/content.tsx | 2 +- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/app/dashboard/admin/page.tsx b/app/dashboard/admin/page.tsx index 85e4661..def9a4e 100644 --- a/app/dashboard/admin/page.tsx +++ b/app/dashboard/admin/page.tsx @@ -403,11 +403,12 @@ export default function AdminPage() { - + handleTabHover("analytics")} onFocus={() => handleTabFocus("analytics")} + className="data-[state=active]:bg-background/80 data-[state=active]:backdrop-blur-sm data-[state=active]:text-foreground data-[state=active]:shadow-sm px-6 py-2 transition-all" > Analytics @@ -415,6 +416,7 @@ export default function AdminPage() { value="management" onMouseEnter={() => handleTabHover("management")} onFocus={() => handleTabFocus("management")} + className="data-[state=active]:bg-background/80 data-[state=active]:backdrop-blur-sm data-[state=active]:text-foreground data-[state=active]:shadow-sm px-6 py-2 transition-all" > Management diff --git a/app/dashboard/admin/vendors/page.tsx b/app/dashboard/admin/vendors/page.tsx index cfc2c09..48bff9e 100644 --- a/app/dashboard/admin/vendors/page.tsx +++ b/app/dashboard/admin/vendors/page.tsx @@ -61,7 +61,7 @@ export default function AdminVendorsPage() { setUpdating(true); await fetchClient(`/admin/vendors/${editingVendor._id}/store-id`, { method: 'PUT', - body: JSON.stringify({ storeId: newStoreId }) + body: { storeId: newStoreId } }); toast({ diff --git a/components/admin/InviteVendorCard.tsx b/components/admin/InviteVendorCard.tsx index b7295b6..0732f58 100644 --- a/components/admin/InviteVendorCard.tsx +++ b/components/admin/InviteVendorCard.tsx @@ -1,47 +1,104 @@ -"use client"; import { useState } from "react"; import { fetchClient } from "@/lib/api-client"; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Copy, Check, Ticket, Loader2, RefreshCw } from "lucide-react"; +import { useToast } from "@/hooks/use-toast"; export default function InviteVendorCard() { const [loading, setLoading] = useState(false); - const [message, setMessage] = useState(null); const [code, setCode] = useState(null); + const [copied, setCopied] = useState(false); + const { toast } = useToast(); async function handleInvite() { setLoading(true); - setMessage(null); setCode(null); + setCopied(false); try { const res = await fetchClient<{ code: string }>("/admin/invitations", { method: "POST" }); - setMessage("Invitation created"); setCode(res.code); + toast({ + title: "Invitation Created", + description: "New vendor invitation code generated successfully.", + }); } catch (e: any) { - setMessage(e?.message || "Failed to send invitation"); + toast({ + title: "Error", + description: e?.message || "Failed to generate invitation", + variant: "destructive", + }); } finally { setLoading(false); } } + const copyToClipboard = () => { + if (!code) return; + navigator.clipboard.writeText(code); + setCopied(true); + toast({ + title: "Copied", + description: "Invitation code copied to clipboard", + }); + setTimeout(() => setCopied(false), 2000); + }; + return ( -
-

Invite Vendor

-

Generate a new invitation code

-
- - {message &&

{message}

} - {code && ( -
- Code: {code} + + +
+ + + Invite Vendor + +
+ Generate a one-time invitation code. +
+ + {code ? ( +
+
+ {code} + +
+

+ Share this code with the new vendor. It expires in 7 days. +

+
+ ) : ( +
+ Click generate to create a new code.
)} -
-
+ + + + + ); } diff --git a/components/dashboard/content.tsx b/components/dashboard/content.tsx index de89b0b..f8f9c62 100644 --- a/components/dashboard/content.tsx +++ b/components/dashboard/content.tsx @@ -181,7 +181,7 @@ export default function Content({ username, orderStats }: ContentProps) {

{product.name}

- £{product.price.toFixed(2)} + £{(Number(product.price) || 0).toFixed(2)} ID: {product.id.slice(-6)}