Product grid tweaks

This commit is contained in:
2024-12-23 00:15:40 -05:00
parent 86c2c10187
commit 8f047a6d18
2 changed files with 72 additions and 45 deletions

View File

@@ -104,7 +104,7 @@ const DashboardLayout = () => {
<div className="hidden lg:col-span-6 lg:block xl:hidden h-[740px]"> <div className="hidden lg:col-span-6 lg:block xl:hidden h-[740px]">
<EventFeed /> <EventFeed />
</div> </div>
<div className="col-span-12 lg:col-span-6 xl:col-span-4 h-[740px]"> <div className="col-span-12 lg:col-span-6 xl:col-span-4 h-[600px] lg:h-[740px]">
<ProductGrid /> <ProductGrid />
</div> </div>
<div className="col-span-12 xl:col-span-8 h-full w-full flex"> <div className="col-span-12 xl:col-span-8 h-full w-full flex">

View File

@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import axios from "axios"; import axios from "axios";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area"; import { ScrollArea } from "@/components/ui/scroll-area";
import { Loader2, ArrowUpDown, AlertCircle, Package, Settings2, Search } from "lucide-react"; import { Loader2, ArrowUpDown, AlertCircle, Package, Settings2, Search, X } from "lucide-react";
import { import {
Table, Table,
TableBody, TableBody,
@@ -46,6 +46,7 @@ const ProductGrid = ({
direction: "desc", direction: "desc",
}); });
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
const [isSearchVisible, setIsSearchVisible] = useState(false);
useEffect(() => { useEffect(() => {
fetchProducts(); fetchProducts();
@@ -163,41 +164,67 @@ const ProductGrid = ({
return ( return (
<Card className="flex flex-col h-full bg-white dark:bg-gray-900/60 backdrop-blur-sm"> <Card className="flex flex-col h-full bg-white dark:bg-gray-900/60 backdrop-blur-sm">
<CardHeader className="p-6 pb-4"> <CardHeader className="p-6 pb-4">
<div className="flex justify-between items-start"> <div className="flex flex-col gap-4">
<div> <div className="flex justify-between items-start">
<CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">{title}</CardTitle> <div>
{description && ( <CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">{title}</CardTitle>
<CardDescription className="mt-1">{description}</CardDescription> {description && (
)} <CardDescription className="mt-1">{description}</CardDescription>
</div> )}
<div className="flex items-center gap-4"> </div>
{!error && ( <div className="flex items-center gap-2">
<div className="relative hidden sm:block"> {!error && (
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" /> <Button
<Input variant="outline"
placeholder="Search products..." size="icon"
value={searchQuery} onClick={() => setIsSearchVisible(!isSearchVisible)}
onChange={(e) => setSearchQuery(e.target.value)} className={cn(
className="pl-8 h-9 w-[200px]" "h-9 w-9",
/> isSearchVisible && "bg-muted"
</div> )}
)} >
<Select <Search className="h-4 w-4" />
value={selectedTimeRange} </Button>
onValueChange={handleTimeRangeChange} )}
> <Select
<SelectTrigger className="w-[130px] h-9"> value={selectedTimeRange}
<SelectValue placeholder="Select time range" /> onValueChange={handleTimeRangeChange}
</SelectTrigger> >
<SelectContent> <SelectTrigger className="w-[130px] h-9">
{TIME_RANGES.map((range) => ( <SelectValue placeholder="Select time range" />
<SelectItem key={range.value} value={range.value}> </SelectTrigger>
{range.label} <SelectContent>
</SelectItem> {TIME_RANGES.map((range) => (
))} <SelectItem key={range.value} value={range.value}>
</SelectContent> {range.label}
</Select> </SelectItem>
))}
</SelectContent>
</Select>
</div>
</div> </div>
{isSearchVisible && !error && (
<div className="relative w-full">
<Search className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder="Search products..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-9 pr-9 h-9 w-full"
autoFocus
/>
{searchQuery && (
<Button
variant="ghost"
size="icon"
className="absolute right-1 top-1 h-7 w-7"
onClick={() => setSearchQuery("")}
>
<X className="h-4 w-4" />
</Button>
)}
</div>
)}
</div> </div>
</CardHeader> </CardHeader>
@@ -225,39 +252,39 @@ const ProductGrid = ({
<table className="w-full"> <table className="w-full">
<thead> <thead>
<tr className="hover:bg-transparent"> <tr className="hover:bg-transparent">
<th className="p-1.5 text-left font-medium sticky top-0 bg-white dark:bg-background z-10 w-[50px] min-w-[50px] border-b" /> <th className="p-1 text-left font-medium sticky top-0 bg-white dark:bg-background z-10 w-[50px] min-w-[35px] border-b" />
<th className="p-1.5 text-left font-medium sticky top-0 bg-white dark:bg-background z-10 min-w-[200px] border-b"> <th className="p-1 text-left font-medium sticky top-0 bg-white dark:bg-background z-10 border-b">
<Button <Button
variant={sorting.column === "name" ? "default" : "ghost"} variant={sorting.column === "name" ? "default" : "ghost"}
onClick={() => handleSort("name")} onClick={() => handleSort("name")}
className="w-full justify-start h-8" className="w-full p-2 justify-start h-8"
> >
Product Product
</Button> </Button>
</th> </th>
<th className="p-1.5 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b"> <th className="p-1 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b">
<Button <Button
variant={sorting.column === "totalQuantity" ? "default" : "ghost"} variant={sorting.column === "totalQuantity" ? "default" : "ghost"}
onClick={() => handleSort("totalQuantity")} onClick={() => handleSort("totalQuantity")}
className="w-full justify-center h-8" className="w-full p-2 justify-center h-8"
> >
Sold Sold
</Button> </Button>
</th> </th>
<th className="p-1.5 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b"> <th className="p-1 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b">
<Button <Button
variant={sorting.column === "totalRevenue" ? "default" : "ghost"} variant={sorting.column === "totalRevenue" ? "default" : "ghost"}
onClick={() => handleSort("totalRevenue")} onClick={() => handleSort("totalRevenue")}
className="w-full justify-center h-8" className="w-full p-2 justify-center h-8"
> >
Rev Rev
</Button> </Button>
</th> </th>
<th className="p-1.5 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b"> <th className="p-1 font-medium text-center sticky top-0 bg-white dark:bg-background z-10 border-b">
<Button <Button
variant={sorting.column === "orderCount" ? "default" : "ghost"} variant={sorting.column === "orderCount" ? "default" : "ghost"}
onClick={() => handleSort("orderCount")} onClick={() => handleSort("orderCount")}
className="w-full justify-center h-8" className="w-full p-2 justify-center h-8"
> >
Orders Orders
</Button> </Button>