Files
whowhat/frontend/src/components/ShoppingListItemRow.jsx
Kacper ce631feb5b
All checks were successful
Build and Push Docker Images / build-and-push (push) Successful in 1m33s
v1.1.2 Pole ilości: klawiatura numeryczna i mniejsza szerokość
Pole ilości na liście zakupów przyjmuje teraz tylko cyfry i otwiera
na telefonie klawiaturę numeryczną (inputMode=numeric) zamiast
zwykłej. Pole ilości jest też wyraźnie węższe niż pole nazwy
produktu (wcześniej rosło do tej samej szerokości przez konflikt
reguł CSS).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 15:23:09 +02:00

70 lines
2.3 KiB
JavaScript

import { useState } from 'react';
import { useUpdateShoppingItem, useDeleteShoppingItem } from '../api/queries.js';
import { useTranslation } from '../i18n/I18nContext.jsx';
import Icon from './Icon.jsx';
export default function ShoppingListItemRow({ item, listId }) {
const updateItem = useUpdateShoppingItem();
const deleteItem = useDeleteShoppingItem();
const { t } = useTranslation();
const [editing, setEditing] = useState(false);
const [name, setName] = useState(item.name);
const [quantity, setQuantity] = useState(item.quantity || '');
function toggleChecked() {
updateItem.mutate({ listId, itemId: item.id, checked: !item.checked });
}
function saveEdit() {
setEditing(false);
if (!name.trim()) {
setName(item.name);
return;
}
updateItem.mutate({ listId, itemId: item.id, name: name.trim(), quantity: quantity.trim() || null });
}
return (
<div className={`shopping-item-row ${item.checked ? 'checked' : ''}`}>
<input type="checkbox" checked={!!item.checked} onChange={toggleChecked} />
{editing ? (
<div className="shopping-item-edit">
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
onBlur={saveEdit}
onKeyDown={(e) => e.key === 'Enter' && saveEdit()}
autoFocus
/>
<input
type="text"
inputMode="numeric"
pattern="[0-9]*"
className="shopping-item-qty-input"
placeholder={t('shoppingListDetail.quantityPlaceholder')}
value={quantity}
onChange={(e) => setQuantity(e.target.value.replace(/\D/g, ''))}
onBlur={saveEdit}
onKeyDown={(e) => e.key === 'Enter' && saveEdit()}
/>
</div>
) : (
<button type="button" className="shopping-item-name" onClick={() => setEditing(true)}>
<span>{item.name}</span>
{item.quantity && <span className="shopping-item-qty">{item.quantity}</span>}
</button>
)}
<button
type="button"
className="icon-btn"
onClick={() => deleteItem.mutate({ listId, itemId: item.id })}
aria-label={t('common.delete')}
>
<Icon name="delete" />
</button>
</div>
);
}