feat: Add expandable section for creating products with integrated product form
This commit is contained in:
@@ -75,7 +75,7 @@ export default function Navigation() {
|
||||
⚙️ Admin
|
||||
</Link>
|
||||
<Link
|
||||
href="/recipes/import"
|
||||
href="/recipes/create"
|
||||
style={{
|
||||
padding: '0.5rem 0.75rem',
|
||||
background: '#fff',
|
||||
@@ -87,7 +87,7 @@ export default function Navigation() {
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
📥 Importera recept
|
||||
⚡ Snabbimport recept
|
||||
</Link>
|
||||
</nav>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import ProductForm from '../../inventory/ProductForm';
|
||||
|
||||
export default function ExpandableCreateProductSection() {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
return (
|
||||
<section
|
||||
style={{
|
||||
border: '2px solid #0070f3',
|
||||
borderRadius: '8px',
|
||||
marginBottom: '1.5rem',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '1rem',
|
||||
background: '#0070f3',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
fontSize: '1.1rem',
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
transition: 'background 0.2s',
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.target as HTMLElement).style.background = '#0059cc';
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.target as HTMLElement).style.background = '#0070f3';
|
||||
}}
|
||||
>
|
||||
<span>➕ Skapa produkt</span>
|
||||
<span style={{ fontSize: '1.5rem', transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s' }}>
|
||||
▼
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{isExpanded && (
|
||||
<div style={{ padding: '1rem', background: '#f9f9f9' }}>
|
||||
<ProductForm />
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export default function MergePreviewForm({ products }: Props) {
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [isConfirming, setIsConfirming] = useState(false);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const fetchPreview = () => {
|
||||
setError(null);
|
||||
@@ -89,15 +90,44 @@ export default function MergePreviewForm({ products }: Props) {
|
||||
return (
|
||||
<section
|
||||
style={{
|
||||
border: '1px solid #ddd',
|
||||
border: '2px solid #10b981',
|
||||
borderRadius: '8px',
|
||||
padding: '1rem',
|
||||
marginBottom: '1.5rem',
|
||||
display: 'grid',
|
||||
gap: '1rem',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<h2 style={{ margin: 0 }}>Förhandsgranska merge</h2>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '1rem',
|
||||
background: '#10b981',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
fontSize: '1.1rem',
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
transition: 'background 0.2s',
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.target as HTMLElement).style.background = '#059669';
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.target as HTMLElement).style.background = '#10b981';
|
||||
}}
|
||||
>
|
||||
<span>🔄 Förhandsgranska merge</span>
|
||||
<span style={{ fontSize: '1.5rem', transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s' }}>
|
||||
▼
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{isExpanded && (
|
||||
<div style={{ padding: '1rem', background: '#f9fafb', display: 'grid', gap: '1rem' }}
|
||||
|
||||
<div style={{ display: 'grid', gap: '0.75rem', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))' }}>
|
||||
<label style={{ display: 'grid', gap: '0.3rem' }}>
|
||||
@@ -310,7 +340,7 @@ export default function MergePreviewForm({ products }: Props) {
|
||||
</article>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import type { Product } from '../../../features/inventory/types';
|
||||
import MergePreviewForm from './MergePreviewForm';
|
||||
import AdminProductList from './AdminProductList';
|
||||
import Navigation from '../../Navigation';
|
||||
import ExpandableCreateProductSection from './ExpandableCreateProductSection';
|
||||
|
||||
export default async function AdminProductsPage() {
|
||||
const products = await fetchJson<Product[]>('/api/products');
|
||||
@@ -13,6 +14,8 @@ export default async function AdminProductsPage() {
|
||||
<h1 style={{ marginBottom: '1.5rem' }}>Admin: Produkter</h1>
|
||||
<p>Här kan du granska och standardisera produktnamn.</p>
|
||||
|
||||
<ExpandableCreateProductSection />
|
||||
|
||||
<MergePreviewForm products={products} />
|
||||
|
||||
<AdminProductList products={products} />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import InventoryForm from './InventoryForm';
|
||||
import ProductForm from './ProductForm';
|
||||
import Link from 'next/link';
|
||||
import { fetchJson } from '../../lib/api';
|
||||
import type { InventoryItem, Product } from '../../features/inventory/types';
|
||||
@@ -109,7 +108,6 @@ export default async function InventoryPage({ searchParams }: InventoryPageProps
|
||||
<Navigation />
|
||||
<h1 style={{ marginBottom: '1.5rem' }}>Varor hemma</h1>
|
||||
|
||||
<ProductForm />
|
||||
<InventoryForm products={products} />
|
||||
|
||||
<section style={{ marginBottom: '1.5rem' }}>
|
||||
|
||||
Reference in New Issue
Block a user