feat(admin): implement product management — list, create, edit, archive (Plan 03)
Covers checklist items 3.1–3.4, 3.10–3.11 (product list, create, edit, archive/restore, SEO fields, admin search). Backend (convex/products.ts): - Extended create/update with shortDescription, brand, attributes, seoTitle, seoDescription, canonicalSlug - Both mutations now set createdAt/updatedAt timestamps - Added getByIdForAdmin (admin-only, returns full product with relations) UI — new pages: - products/page.tsx: table with debounced search, column visibility dropdown, client-side sort, 10-row skeleton, load-more pagination, row preview dialog, per-row actions menu - products/new/page.tsx: create product page - products/[id]/edit/page.tsx: pre-populated edit page with archive button UI — new components: - ProductForm: shared form (create + edit); zod + react-hook-form, auto-slug, collapsible Attributes + SEO sections, submit spinner - ProductPreviewDialog: read-only full-product dialog - ProductActionsMenu: kebab menu (Edit link + Archive AlertDialog) ShadCN components installed: table, badge, alert-dialog, dialog, scroll-area, form, select, label, checkbox, textarea Also: - Updated CLAUDE.md: form submit buttons must use inline SVG spinner with data-icon="inline-start"; link-styled buttons use buttonVariants on <Link> (Button render prop not in TS types) - Updated docs: checklist and plan marked complete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
41
package-lock.json
generated
41
package-lock.json
generated
@@ -47,6 +47,7 @@
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.2.0",
|
||||
"@clerk/nextjs": "^6.38.2",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@hugeicons/core-free-icons": "^3.3.0",
|
||||
"@hugeicons/react": "^1.1.5",
|
||||
"@repo/convex": "*",
|
||||
@@ -56,7 +57,9 @@
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.400.0",
|
||||
"radix-ui": "^1.4.3",
|
||||
"tailwind-merge": "^2.6.1"
|
||||
"react-hook-form": "^7.71.2",
|
||||
"tailwind-merge": "^2.6.1",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.2.0",
|
||||
@@ -1769,6 +1772,18 @@
|
||||
"hono": "^4"
|
||||
}
|
||||
},
|
||||
"node_modules/@hookform/resolvers": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz",
|
||||
"integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@standard-schema/utils": "^0.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-hook-form": "^7.55.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@hugeicons/core-free-icons": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@hugeicons/core-free-icons/-/core-free-icons-3.3.0.tgz",
|
||||
@@ -8522,6 +8537,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@standard-schema/utils": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
|
||||
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@stripe/react-stripe-js": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-5.6.0.tgz",
|
||||
@@ -15605,6 +15626,23 @@
|
||||
"react": "^19.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/react-hook-form": {
|
||||
"version": "7.71.2",
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz",
|
||||
"integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/react-hook-form"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@@ -18161,7 +18199,6 @@
|
||||
"version": "3.25.76",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
|
||||
Reference in New Issue
Block a user