Product grid tweaks
This commit is contained in:
@@ -104,7 +104,7 @@ const DashboardLayout = () => {
|
||||
<div className="hidden lg:col-span-6 lg:block xl:hidden h-[740px]">
|
||||
<EventFeed />
|
||||
</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 />
|
||||
</div>
|
||||
<div className="col-span-12 xl:col-span-8 h-full w-full flex">
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
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 {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -46,6 +46,7 @@ const ProductGrid = ({
|
||||
direction: "desc",
|
||||
});
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [isSearchVisible, setIsSearchVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchProducts();
|
||||
@@ -163,6 +164,7 @@ const ProductGrid = ({
|
||||
return (
|
||||
<Card className="flex flex-col h-full bg-white dark:bg-gray-900/60 backdrop-blur-sm">
|
||||
<CardHeader className="p-6 pb-4">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">{title}</CardTitle>
|
||||
@@ -170,17 +172,19 @@ const ProductGrid = ({
|
||||
<CardDescription className="mt-1">{description}</CardDescription>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
{!error && (
|
||||
<div className="relative hidden sm:block">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="Search products..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-8 h-9 w-[200px]"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => setIsSearchVisible(!isSearchVisible)}
|
||||
className={cn(
|
||||
"h-9 w-9",
|
||||
isSearchVisible && "bg-muted"
|
||||
)}
|
||||
>
|
||||
<Search className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
<Select
|
||||
value={selectedTimeRange}
|
||||
@@ -199,6 +203,29 @@ const ProductGrid = ({
|
||||
</Select>
|
||||
</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>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="p-6 pt-0 flex-1 overflow-hidden -mt-1">
|
||||
@@ -225,39 +252,39 @@ const ProductGrid = ({
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<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.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 w-[50px] min-w-[35px] border-b" />
|
||||
<th className="p-1 text-left font-medium sticky top-0 bg-white dark:bg-background z-10 border-b">
|
||||
<Button
|
||||
variant={sorting.column === "name" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("name")}
|
||||
className="w-full justify-start h-8"
|
||||
className="w-full p-2 justify-start h-8"
|
||||
>
|
||||
Product
|
||||
</Button>
|
||||
</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
|
||||
variant={sorting.column === "totalQuantity" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("totalQuantity")}
|
||||
className="w-full justify-center h-8"
|
||||
className="w-full p-2 justify-center h-8"
|
||||
>
|
||||
Sold
|
||||
</Button>
|
||||
</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
|
||||
variant={sorting.column === "totalRevenue" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("totalRevenue")}
|
||||
className="w-full justify-center h-8"
|
||||
className="w-full p-2 justify-center h-8"
|
||||
>
|
||||
Rev
|
||||
</Button>
|
||||
</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
|
||||
variant={sorting.column === "orderCount" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("orderCount")}
|
||||
className="w-full justify-center h-8"
|
||||
className="w-full p-2 justify-center h-8"
|
||||
>
|
||||
Orders
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user