v0.19.0 — Pantry: tag what you used items for
Quick-pick chips (Family dinner, Dinner party, Taking on a trip, Meal prep, Gave it away) in the Use dialog, alongside the existing freeform notes field — picking one fills the note, no schema change needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import { Minus } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { PantryItem } from "./pantry-client";
|
||||
|
||||
const QUICK_REASONS = ["Family dinner", "Dinner party", "Taking on a trip", "Meal prep", "Gave it away"];
|
||||
|
||||
export function UseItemDialog({ item, onSuccess }: { item: PantryItem; onSuccess: () => void }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [amount, setAmount] = useState("1");
|
||||
const [notes, setNotes] = useState("");
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [selectedReason, setSelectedReason] = useState<string | null>(null);
|
||||
const notesRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
function pickReason(reason: string) {
|
||||
if (selectedReason === reason) {
|
||||
setSelectedReason(null);
|
||||
setNotes("");
|
||||
} else {
|
||||
setSelectedReason(reason);
|
||||
setNotes(reason);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
@@ -28,6 +43,7 @@ export function UseItemDialog({ item, onSuccess }: { item: PantryItem; onSuccess
|
||||
setOpen(false);
|
||||
setAmount("1");
|
||||
setNotes("");
|
||||
setSelectedReason(null);
|
||||
onSuccess();
|
||||
} catch (err) {
|
||||
setError(String(err).replace("Error: ", ""));
|
||||
@@ -44,7 +60,7 @@ export function UseItemDialog({ item, onSuccess }: { item: PantryItem; onSuccess
|
||||
<Minus className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<Dialog open={open} onOpenChange={o => { setOpen(o); if (!o) { setSelectedReason(null); setNotes(""); } }}>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Use {item.name}</DialogTitle>
|
||||
@@ -66,9 +82,32 @@ export function UseItemDialog({ item, onSuccess }: { item: PantryItem; onSuccess
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label>Notes (optional)</Label>
|
||||
<input className={inputCls} value={notes} onChange={e => setNotes(e.target.value)} placeholder="e.g. used in chicken soup" />
|
||||
<div className="space-y-1.5">
|
||||
<Label>What's it for? (optional)</Label>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{QUICK_REASONS.map(reason => (
|
||||
<button
|
||||
key={reason}
|
||||
type="button"
|
||||
onClick={() => pickReason(reason)}
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1 text-xs",
|
||||
selectedReason === reason
|
||||
? "bg-primary text-primary-foreground border-primary"
|
||||
: "bg-background hover:bg-accent"
|
||||
)}
|
||||
>
|
||||
{reason}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<input
|
||||
ref={notesRef}
|
||||
className={inputCls}
|
||||
value={notes}
|
||||
onChange={e => { setNotes(e.target.value); setSelectedReason(null); }}
|
||||
placeholder="e.g. used in chicken soup, or pick a tag above"
|
||||
/>
|
||||
</div>
|
||||
{error && <p className="text-sm text-destructive">{error}</p>}
|
||||
<DialogFooter>
|
||||
|
||||
@@ -8,6 +8,13 @@ export type ChangelogEntry = {
|
||||
};
|
||||
|
||||
export const CHANGELOG: ChangelogEntry[] = [
|
||||
{
|
||||
version: "0.19.0",
|
||||
date: "2026-06-29",
|
||||
changes: [
|
||||
"Pantry: when you use something, you can now tag why with one tap — Family dinner, Dinner party, Taking on a trip, Meal prep, Gave it away — or type your own note instead.",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "0.18.1",
|
||||
date: "2026-06-29",
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Bump on every user-visible release. Changelog entries live in `src/lib/changelog.ts`.
|
||||
export const APP_VERSION = "0.18.1";
|
||||
export const APP_VERSION = "0.19.0";
|
||||
|
||||
Reference in New Issue
Block a user