Recipe-app main

This commit is contained in:
2026-04-09 09:14:39 +02:00
commit 962f4e4be5
10015 changed files with 2445177 additions and 0 deletions
@@ -0,0 +1,189 @@
'use client';
import { useState, useTransition } from 'react';
import { updateInventoryItem } from './actions';
import type { InventoryItem } from '../../features/inventory/types';
type Props = {
item: InventoryItem;
};
function toDateInputValue(value: string | null) {
if (!value) return '';
return value.slice(0, 10);
}
export default function InventoryEditForm({ item }: Props) {
const [isEditing, setIsEditing] = useState(false);
const [isPending, startTransition] = useTransition();
const [error, setError] = useState<string | null>(null);
if (!isEditing) {
return (
<button
type="button"
onClick={() => setIsEditing(true)}
style={{ padding: '0.5rem 0.75rem' }}
>
Redigera
</button>
);
}
return (
<div
style={{
width: '100%',
display: 'grid',
gap: '0.75rem',
marginTop: '0.5rem',
}}
>
<form
onSubmit={(e) => {
e.preventDefault();
setError(null);
const form = e.currentTarget;
const formData = new FormData(form);
startTransition(async () => {
try {
await updateInventoryItem(formData);
setIsEditing(false);
} catch (err) {
setError(err instanceof Error ? err.message : 'Okänt fel');
}
});
}}
style={{
display: 'grid',
gap: '0.75rem',
border: '1px solid #eee',
borderRadius: '8px',
padding: '0.75rem',
background: '#fafafa',
}}
>
<input type="hidden" name="id" value={item.id} />
<div
style={{
display: 'grid',
gap: '0.75rem',
gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
}}
>
<label>
Mängd
<br />
<input
name="quantity"
type="number"
step="0.01"
min="0"
defaultValue={item.quantity}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label>
Enhet
<br />
<input
name="unit"
type="text"
defaultValue={item.unit}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label>
Plats
<br />
<input
name="location"
type="text"
defaultValue={item.location || ''}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label>
Varumärke
<br />
<input
name="brand"
type="text"
defaultValue={item.brand || ''}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label>
Bäst före
<br />
<input
name="bestBeforeDate"
type="date"
defaultValue={toDateInputValue(item.bestBeforeDate)}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
</div>
<label>
Passar till
<br />
<input
name="suitableFor"
type="text"
defaultValue={item.suitableFor || ''}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label>
Kommentar
<br />
<input
name="comment"
type="text"
defaultValue={item.comment || ''}
style={{ width: '100%', padding: '0.5rem' }}
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<input
name="opened"
type="checkbox"
defaultChecked={item.opened ?? false}
/>
Öppnad
</label>
<div style={{ display: 'flex', gap: '0.75rem', flexWrap: 'wrap' }}>
<button
type="submit"
disabled={isPending}
style={{ padding: '0.6rem 0.9rem' }}
>
{isPending ? 'Sparar...' : 'Spara ändringar'}
</button>
<button
type="button"
onClick={() => setIsEditing(false)}
disabled={isPending}
style={{ padding: '0.6rem 0.9rem' }}
>
Avbryt
</button>
</div>
</form>
{error ? <p style={{ color: 'crimson', margin: 0 }}>{error}</p> : null}
</div>
);
}