Revamp dashboard UI with improved dark theme styles
All checks were successful
Build Frontend / build (push) Successful in 1m11s

Updated category, quick actions, and product table components to use enhanced dark theme styling, including new background colors, borders, gradients, and shadow effects. Improved visual hierarchy, contrast, and hover states for better user experience and consistency across dashboard elements.
This commit is contained in:
g
2026-01-12 08:19:59 +00:00
parent e369741b2d
commit 6997838bf7
3 changed files with 53 additions and 43 deletions

View File

@@ -263,10 +263,10 @@ export default function CategoriesPage() {
> >
<div <div
ref={ref} ref={ref}
className={`group flex items-center p-2 rounded-md transition-all duration-200 border border-transparent className={`group flex items-center p-3 rounded-xl transition-all duration-200 border mb-2
${isEditing ? 'bg-muted/50 border-primary/20' : ''} ${isEditing ? 'bg-indigo-500/10 border-indigo-500/30' : ''}
${isOver ? 'bg-muted border-primary/20' : 'hover:bg-muted/50 hover:border-border/50'} ${isOver ? 'bg-indigo-500/20 border-indigo-500/50 scale-[1.02]' : 'bg-black/40 border-white/5 hover:bg-black/60 hover:border-white/10 hover:shadow-lg'}
${isDragging ? 'opacity-50' : 'opacity-100'}`} ${isDragging ? 'opacity-30' : 'opacity-100'} backdrop-blur-sm`}
style={{ marginLeft: `${level * 24}px` }} style={{ marginLeft: `${level * 24}px` }}
data-handler-id={handlerId} data-handler-id={handlerId}
> >
@@ -384,51 +384,53 @@ export default function CategoriesPage() {
<div className="grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-5 gap-6 lg:gap-8"> <div className="grid grid-cols-1 lg:grid-cols-3 xl:grid-cols-5 gap-6 lg:gap-8">
{/* Add Category Card */} {/* Add Category Card */}
<Card className="lg:col-span-2 border-border/40 bg-background/50 backdrop-blur-sm shadow-sm h-fit sticky top-6"> <Card className="lg:col-span-2 border-white/10 bg-black/40 backdrop-blur-xl shadow-xl h-fit sticky top-6 rounded-xl overflow-hidden">
<CardHeader className="bg-muted/20 border-b border-border/40 pb-4"> <CardHeader className="bg-white/[0.02] border-b border-white/5 pb-4">
<CardTitle className="text-lg font-medium flex items-center"> <CardTitle className="text-lg font-bold flex items-center text-white">
<Plus className="mr-2 h-4 w-4 text-primary" /> <div className="p-2 mr-3 rounded-lg bg-indigo-500/10 border border-indigo-500/20">
<Plus className="h-4 w-4 text-indigo-400" />
</div>
Add New Category Add New Category
</CardTitle> </CardTitle>
<CardDescription> <CardDescription className="text-zinc-400">
Create a new category or subcategory Create a new category or subcategory
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="pt-6"> <CardContent className="pt-6">
<div className="space-y-4"> <div className="space-y-4">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium leading-none"> <label className="text-sm font-medium leading-none text-zinc-300">
Category Name Category Name
</label> </label>
<Input <Input
value={newCategoryName} value={newCategoryName}
onChange={(e) => setNewCategoryName(e.target.value)} onChange={(e) => setNewCategoryName(e.target.value)}
placeholder="e.g. Electronics, Clothing..." placeholder="e.g. Electronics, Clothing..."
className="h-10 border-border/50 bg-background/50 focus:bg-background transition-colors" className="h-10 border-white/10 bg-black/20 focus:bg-black/40 transition-colors text-white placeholder:text-zinc-600"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium leading-none"> <label className="text-sm font-medium leading-none text-zinc-300">
Parent Category Parent Category
</label> </label>
<Select <Select
value={selectedParentId || "none"} value={selectedParentId || "none"}
onValueChange={setSelectedParentId} onValueChange={setSelectedParentId}
> >
<SelectTrigger className="h-10 border-border/50 bg-background/50 focus:bg-background transition-colors"> <SelectTrigger className="h-10 border-white/10 bg-black/20 focus:bg-black/40 transition-colors text-white">
<SelectValue placeholder="Select parent category" /> <SelectValue placeholder="Select parent category" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent className="bg-zinc-900 border-white/10 text-white">
<SelectItem value="none">No parent (root category)</SelectItem> <SelectItem value="none" className="focus:bg-zinc-800">No parent (root category)</SelectItem>
{categories.map((cat) => ( {categories.map((cat) => (
<SelectItem key={cat._id} value={cat._id}> <SelectItem key={cat._id} value={cat._id} className="focus:bg-zinc-800">
{cat.name} {cat.name}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<Button onClick={handleAddCategory} className="w-full mt-2" size="lg"> <Button onClick={handleAddCategory} className="w-full mt-2 bg-indigo-600 hover:bg-indigo-700 text-white border-0" size="lg">
<Plus className="h-4 w-4 mr-2" /> <Plus className="h-4 w-4 mr-2" />
Add Category Add Category
</Button> </Button>
@@ -437,14 +439,14 @@ export default function CategoriesPage() {
</Card> </Card>
{/* Category List Card */} {/* Category List Card */}
<Card className="lg:col-span-3 border-border/40 bg-background/50 backdrop-blur-sm shadow-sm"> <Card className="lg:col-span-3 border-none bg-transparent shadow-none">
<CardHeader className="bg-muted/20 border-b border-border/40 pb-4"> <CardHeader className="pl-0 pt-0 pb-4">
<CardTitle className="text-lg font-medium">Structure</CardTitle> <CardTitle className="text-lg font-bold text-white">Structure</CardTitle>
<CardDescription> <CardDescription className="text-zinc-400">
Drag and drop to reorder categories Drag and drop to reorder categories
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="pt-6"> <CardContent className="p-0">
<DndProvider backend={HTML5Backend}> <DndProvider backend={HTML5Backend}>
<div className="space-y-2 min-h-[300px]"> <div className="space-y-2 min-h-[300px]">
{loading ? ( {loading ? (

View File

@@ -164,13 +164,16 @@ export default function QuickActions() {
const isModalAction = action.action === "modal"; const isModalAction = action.action === "modal";
const CardContentWrapper = () => ( const CardContentWrapper = () => (
<Card className="hover:border-primary/50 transition-colors cursor-pointer group h-full border-border/40 bg-background/50 backdrop-blur-sm"> <Card className="h-full border-none bg-black/40 backdrop-blur-xl hover:bg-black/60 transition-all duration-300 group overflow-hidden relative">
<CardContent className="p-6 flex flex-col items-center text-center"> <div className="absolute inset-0 border border-white/10 rounded-xl pointer-events-none group-hover:border-white/20 transition-colors" />
<div className={`p-3 rounded-xl ${action.color} mb-4 group-hover:scale-110 transition-transform`}> <div className={`absolute inset-0 bg-gradient-to-br ${action.color.split(' ')[0].replace('/10', '/5')} opacity-0 group-hover:opacity-100 transition-opacity duration-500`} />
<CardContent className="p-6 flex flex-col items-center text-center relative z-10">
<div className={`p-4 rounded-2xl ${action.color.replace('bg-', 'bg-opacity-10 bg-')} mb-4 group-hover:scale-110 transition-transform duration-300 shadow-lg shadow-black/20`}>
<action.icon className="h-6 w-6" /> <action.icon className="h-6 w-6" />
</div> </div>
<h3 className="font-semibold text-lg">{action.title}</h3> <h3 className="font-bold text-lg text-white group-hover:text-primary transition-colors">{action.title}</h3>
<p className="text-sm text-muted-foreground mt-1">{action.description}</p> <p className="text-sm text-zinc-400 mt-1">{action.description}</p>
</CardContent> </CardContent>
</Card> </Card>
); );
@@ -181,15 +184,15 @@ export default function QuickActions() {
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.1 }} transition={{ delay: index * 0.1 }}
whileHover={{ scale: 1.02 }} whileHover={{ y: -5 }}
whileTap={{ scale: 0.98 }} whileTap={{ scale: 0.98 }}
> >
{isModalAction ? ( {isModalAction ? (
<div onClick={() => setModalOpen(true)}> <div onClick={() => setModalOpen(true)} className="cursor-pointer h-full">
<CardContentWrapper /> <CardContentWrapper />
</div> </div>
) : ( ) : (
<Link href={action.href}> <Link href={action.href} className="h-full block">
<CardContentWrapper /> <CardContentWrapper />
</Link> </Link>
)} )}

View File

@@ -211,12 +211,14 @@ const ProductTable = ({
return ( return (
<div className="space-y-8"> <div className="space-y-8">
{/* Enabled Products Table */} {/* Enabled Products Table */}
<Card className="border-border/40 bg-background/50 backdrop-blur-sm shadow-sm overflow-hidden"> <Card className="border-white/10 bg-black/40 backdrop-blur-xl shadow-2xl overflow-hidden rounded-xl">
<CardHeader className="py-4 px-6 border-b border-border/50 bg-muted/30"> <CardHeader className="py-4 px-6 border-b border-white/5 bg-white/[0.02]">
<CardTitle className="text-lg font-medium flex items-center gap-2"> <CardTitle className="text-lg font-bold flex items-center gap-3 text-white">
<CheckCircle className="h-5 w-5 text-primary" /> <div className="p-2 rounded-lg bg-indigo-500/10 border border-indigo-500/20">
<CheckCircle className="h-5 w-5 text-indigo-400" />
</div>
Active Products Active Products
<Badge variant="secondary" className="ml-2 bg-background/80 backdrop-blur-sm"> <Badge variant="secondary" className="ml-2 bg-indigo-500/10 text-indigo-300 border-indigo-500/20 hover:bg-indigo-500/20">
{sortedEnabledProducts.length} {sortedEnabledProducts.length}
</Badge> </Badge>
</CardTitle> </CardTitle>
@@ -226,11 +228,14 @@ const ProductTable = ({
<Table> <Table>
{renderTableHeader()} {renderTableHeader()}
<TableBody> <TableBody>
<AnimatePresence mode="popLayout"> <AnimatePresence>
{loading ? ( {loading ? (
<TableRow> <TableRow>
<TableCell colSpan={6} className="h-32 text-center text-muted-foreground"> <TableCell colSpan={6} className="h-32 text-center text-muted-foreground">
Loading products... <div className="flex flex-col items-center gap-2">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-indigo-500 border-t-transparent" />
<span>Loading products...</span>
</div>
</TableCell> </TableCell>
</TableRow> </TableRow>
) : sortedEnabledProducts.length > 0 ? ( ) : sortedEnabledProducts.length > 0 ? (
@@ -239,7 +244,7 @@ const ProductTable = ({
<TableRow> <TableRow>
<TableCell colSpan={6} className="h-32 text-center text-muted-foreground"> <TableCell colSpan={6} className="h-32 text-center text-muted-foreground">
<div className="flex flex-col items-center justify-center gap-2"> <div className="flex flex-col items-center justify-center gap-2">
<PackageX className="h-8 w-8 opacity-50" /> <PackageX className="h-8 w-8 opacity-20" />
<p>No active products found</p> <p>No active products found</p>
</div> </div>
</TableCell> </TableCell>
@@ -254,12 +259,12 @@ const ProductTable = ({
{/* Disabled Products Section */} {/* Disabled Products Section */}
{!loading && disabledProducts.length > 0 && ( {!loading && disabledProducts.length > 0 && (
<Card className="border-border/40 bg-background/30 backdrop-blur-sm shadow-sm overflow-hidden opacity-90"> <Card className="border-white/5 bg-black/20 backdrop-blur-sm shadow-none overflow-hidden opacity-80 hover:opacity-100 transition-opacity">
<CardHeader className="py-4 px-6 border-b border-border/50 bg-muted/20"> <CardHeader className="py-4 px-6 border-b border-white/5 bg-white/[0.01]">
<CardTitle className="text-lg font-medium flex items-center gap-2 text-muted-foreground"> <CardTitle className="text-lg font-medium flex items-center gap-2 text-zinc-400">
<Archive className="h-5 w-5" /> <Archive className="h-5 w-5" />
Archived / Disabled Archived / Disabled
<Badge variant="outline" className="ml-2"> <Badge variant="outline" className="ml-2 border-white/10 text-zinc-500">
{sortedDisabledProducts.length} {sortedDisabledProducts.length}
</Badge> </Badge>
</CardTitle> </CardTitle>
@@ -269,7 +274,7 @@ const ProductTable = ({
<Table> <Table>
{renderTableHeader()} {renderTableHeader()}
<TableBody> <TableBody>
<AnimatePresence mode="popLayout"> <AnimatePresence>
{sortedDisabledProducts.map((product, index) => {sortedDisabledProducts.map((product, index) =>
renderProductRow(product, index, true), renderProductRow(product, index, true),
)} )}