Refactor logging in IcaRecipeParser and QuickImportService to use NestJS Logger

- Updated IcaRecipeParser to replace console.log statements with Logger for better logging practices.
- Enhanced QuickImportService with Logger for consistent logging and error handling.
- Changed quantity validation in CreateRecipeIngredientDto and CreateRecipeDto to allow zero.
- Removed CanonicalNameForm and NameForm components from the frontend.
- Updated EditProductForm to use a select dropdown for categories instead of a text input.
- Added validation for product name, canonical name, and category length in product update action.
- Refactored unit options into a separate file for better reusability across components.
- Removed unused API fetching functions and inventory types to clean up the codebase.
This commit is contained in:
Nils-Johan Gynther
2026-04-16 18:18:27 +02:00
parent 3f6d32ae44
commit d5b360fd62
19 changed files with 74 additions and 751 deletions
@@ -1,79 +0,0 @@
'use client';
import { useState, useTransition } from 'react';
import { updateCanonicalName } from '../../inventory/actions';
type Props = {
id: number;
currentCanonicalName: string | null;
};
export default function CanonicalNameForm({
id,
currentCanonicalName,
}: Props) {
const [isPending, startTransition] = useTransition();
const [error, setError] = useState<string | null>(null);
return (
<form
onSubmit={(e) => {
e.preventDefault();
setError(null);
const form = e.currentTarget;
const formData = new FormData(form);
startTransition(async () => {
try {
await updateCanonicalName(formData);
} catch (err) {
setError(err instanceof Error ? err.message : 'Okänt fel');
}
});
}}
style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap' }}
>
<input
type="hidden"
name="id"
value={id}
/>
<input
name="canonicalName"
type="text"
defaultValue={currentCanonicalName || ''}
placeholder="Canonical name"
style={{
padding: '0.75rem',
border: '1px solid #ddd',
borderRadius: '4px',
fontSize: '1rem',
boxSizing: 'border-box',
minHeight: '44px',
minWidth: '220px',
flex: '1 1 200px',
}}
/>
<button
type="submit"
disabled={isPending}
style={{
padding: '0.75rem 1.5rem',
background: '#0070f3',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '1rem',
minHeight: '44px',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
{isPending ? 'Sparar...' : 'Spara'}
</button>
{error ? <span style={{ color: 'crimson' }}>{error}</span> : null}
</form>
);
}
@@ -110,13 +110,23 @@ export default function EditProductForm({ product }: Props) {
<label style={{ display: 'grid', gap: '0.25rem', fontSize: '0.9rem' }}>
<span style={{ fontWeight: 600 }}>Kategori</span>
<input
<select
name="category"
type="text"
defaultValue={product.category ?? ''}
style={inputStyle}
placeholder="T.ex. Kött, Grönsaker, Mejeriprodukter"
/>
>
<option value=""> Ingen kategori </option>
<option value="Kött & Fisk">Kött &amp; Fisk</option>
<option value="Mejeri & Ägg">Mejeri &amp; Ägg</option>
<option value="Grönsaker & Frukt">Grönsaker &amp; Frukt</option>
<option value="Torrvaror & Skafferi">Torrvaror &amp; Skafferi</option>
<option value="Bröd & Bakverk">Bröd &amp; Bakverk</option>
<option value="Kryddor & Smaksättning">Kryddor &amp; Smaksättning</option>
<option value="Dryck">Dryck</option>
<option value="Frysta varor">Frysta varor</option>
<option value="Konserver">Konserver</option>
<option value="Övrigt">Övrigt</option>
</select>
</label>
<div style={{ display: 'grid', gap: '0.25rem', fontSize: '0.85rem', color: '#888' }}>
+5
View File
@@ -9,6 +9,11 @@ export async function updateProduct(formData: FormData) {
const canonicalName = String(formData.get('canonicalName') || '').trim();
const category = String(formData.get('category') || '').trim();
if (!name) throw new Error('Namn får inte vara tomt.');
if (name.length > 100) throw new Error('Namn får inte vara längre än 100 tecken.');
if (canonicalName.length > 100) throw new Error('Canonical name får inte vara längre än 100 tecken.');
if (category.length > 100) throw new Error('Kategori får inte vara längre än 100 tecken.');
const res = await fetch(`${API_BASE}/api/products/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },