Skip to content

[WIP] Build product dashboard UI with shadcn-ui components#53

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/build-product-dashboard-ui
Draft

[WIP] Build product dashboard UI with shadcn-ui components#53
Copilot wants to merge 2 commits intomainfrom
copilot/build-product-dashboard-ui

Conversation

Copy link
Contributor

Copilot AI commented Nov 25, 2025

  • Analyze existing codebase and product components
  • Set up environment and verify build passes
  • Create VariantManager component for variant CRUD operations
  • Create ImageUpload component with drag-to-reorder functionality
  • Enhance ProductsTable with search filters and bulk actions
  • Integrate components into product create/edit forms
  • Ensure mobile responsive design
  • Run type-check, lint and build validation
  • Take screenshots of UI changes
Original prompt

This section details on the original issue you should resolve

<issue_title>[Phase 1] Product Dashboard UI</issue_title>
<issue_description>## Priority: P0 (Critical)
Phase: 1 - E-Commerce Core
Epic: Product Management
Estimate: 5 days
Type: Story

Context

Build admin product dashboard UI with list, create/edit forms, variant management, and bulk operations using shadcn-ui components.

Acceptance Criteria

  • Product list shows 50+ products with <2s load time
  • Create form validates all required fields client-side and server-side
  • Variant management UI (add/remove up to 100 variants)
  • Image upload with preview and drag-to-reorder
  • Bulk actions work for 100+ selected products (delete, publish, archive)
  • Search and filters apply instantly (<500ms)
  • Mobile responsive (tested on 375px, 768px, 1024px breakpoints)

Technical Implementation

1. Product List Page (src/app/(dashboard)/products/page.tsx)

'use client';

import { useState, useEffect } from 'react';
import { DataTable } from '@/components/data-table';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Plus, Search } from 'lucide-react';
import { useRouter } from 'next/navigation';

export default function ProductsPage() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const router = useRouter();

  useEffect(() => {
    fetchProducts();
  }, [search]);

  const fetchProducts = async () => {
    const response = await fetch(`/api/products?search=${search}`);
    const data = await response.json();
    setProducts(data);
    setLoading(false);
  };

  const columns = [
    { accessorKey: 'name', header: 'Name' },
    { accessorKey: 'sku', header: 'SKU' },
    { accessorKey: 'price', header: 'Price', cell: ({ row }) => `$${row.original.price}` },
    { accessorKey: '_count.variants', header: 'Variants' },
    {
      id: 'actions',
      cell: ({ row }) => (
        <Button
          variant="ghost"
          size="sm"
          onClick={() => router.push(`/products/${row.original.id}`)}
        >
          Edit
        </Button>
      )
    }
  ];

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">Products</h1>
        <Button onClick={() => router.push('/products/new')}>
          <Plus className="mr-2 h-4 w-4" />
          New Product
        </Button>
      </div>

      <div className="flex items-center gap-2">
        <Input
          placeholder="Search products..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="max-w-sm"
        />
        <Search className="h-4 w-4 text-muted-foreground" />
      </div>

      <DataTable
        columns={columns}
        data={products}
        loading={loading}
      />
    </div>
  );
}

2. Product Create/Edit Form (src/app/(dashboard)/products/[id]/page.tsx)

'use client';

import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Card } from '@/components/ui/card';

const productSchema = z.object({
  name: z.string().min(1, 'Name required').max(255),
  sku: z.string().min(1, 'SKU required'),
  price: z.number().positive('Price must be positive'),
  description: z.string().optional(),
  categoryId: z.string().optional(),
  variants: z.array(z.object({
    name: z.string().min(1),
    sku: z.string().min(1),
    price: z.number().positive(),
    stock: z.number().int().min(0)
  })).optional()
});

type ProductFormData = z.infer<typeof productSchema>;

export default function ProductEditPage({ params }: { params: { id: string } }) {
  const [variants, setVariants] = useState<any[]>([]);
  const { register, handleSubmit, formState: { errors } } = useForm<ProductFormData>({
    resolver: zodResolver(productSchema)
  });

  const onSubmit = async (data: ProductFormData) => {
    const response = await fetch(`/api/products${params.id !== 'new' ? `/${params.id}` : ''}`, {
      method: params.id !== 'new' ? 'PUT' : 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ...data, variants })
    });

    if (response.ok) {
      router.push('/products');
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
      <Card className="p-6">
        <h2 className="text-xl font-semibold mb-4">Basic Information</h2>

        <div className="space-y-4">
          <div>
            <Label htmlFor="name">Product Name</Label>
            <Input {...

</details>

- Fixes CodeStorm-Hub/stormcomui#17

<!-- START COPILOT CODING AGENT TIPS -->
---

 Let Copilot coding agent [set things up for you](https://github.com/CodeStorm-Hub/stormcomui/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link

vercel bot commented Nov 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
stormcomui Ready Ready Preview Comment Nov 25, 2025 2:09am

Co-authored-by: syed-reza98 <71028588+syed-reza98@users.noreply.github.com>
@github-actions
Copy link

Automated review (GitHub Models):

The pull request is a work-in-progress and addresses several parts of the referenced issue (#17), but many acceptance criteria from the original prompt remain incomplete (e.g., variant management UI, image upload with drag-to-reorder, bulk actions, full mobile responsiveness). No commit or merged PR resolving all requirements was found. Additional development is needed to fully resolve the issue.

Confidence: 0.8

Evidence:

  • src/app/(dashboard)/products/page.tsx : The file exists and implements the products list page, but many referenced acceptance criteria (bulk actions, variant management, mobile responsiveness, drag-to-reorder uploads) are not clearly present.
  • src/app/(dashboard)/products/[id]/page.tsx : The create/edit form is present, but missing implementation details such as the VariantManager, ImageUpload with drag-to-reorder, and other required features.

@syed-reza98 syed-reza98 mentioned this pull request Feb 28, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants