SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
2.8 KB · 68 lines tsx
Raw Blame History
1'use client';23import { useActionState, useState } from 'react';4import { toggleWatchAction, updateWatchItemAction } from '@/lib/account/actions';5import { idle } from '@/lib/auth/state';6import { Field, FormMessage, Select, SubmitButton, TextInput } from '@/components/account/form';7import { AssetPicker } from '@/components/account/asset-picker';8import { CATEGORIES } from '@rareindex/taxonomy';910export function WatchAddForm() {11  const [mode, setMode] = useState<'asset' | 'category'>('asset');12  return (13    <form action={toggleWatchAction} className="space-y-3">14      <div className="flex gap-1 text-xs">15        {(['asset', 'category'] as const).map((m) => (16          <button key={m} type="button" onClick={() => setMode(m)} className={`rounded-full border px-3 py-1 ${mode === m ? 'border-fg bg-accent text-accent-fg' : 'border-border text-muted'}`}>17            {m === 'asset' ? 'Asset' : 'Category / market'}18          </button>19        ))}20      </div>21      <input type="hidden" name="targetType" value={mode} />22      {mode === 'asset' ? (23        <AssetPicker name="targetId" withVariant={false} />24      ) : (25        <Field label="Category" name="targetId">26          <Select name="targetId" defaultValue="pokemon">27            {CATEGORIES.map((c) => (28              <option key={c.slug} value={c.slug}>29                {'— '.repeat(c.level)}30                {c.name}31              </option>32            ))}33          </Select>34        </Field>35      )}36      <SubmitButton pendingText="Adding…">Watch</SubmitButton>37    </form>38  );39}4041export function WatchNoteForm({ itemId, note, targetPriceUsd }: { itemId: string; note: string | null; targetPriceUsd: number | null }) {42  const [state, action] = useActionState(updateWatchItemAction, idle);43  const [open, setOpen] = useState(false);44  if (!open) {45    return (46      <button type="button" onClick={() => setOpen(true)} className="max-w-full truncate text-left text-xs text-muted hover:text-fg">47        {note ? note : targetPriceUsd ? 'Edit target' : '+ note / target'}48      </button>49    );50  }51  return (52    <form action={action} className="flex flex-col gap-1">53      <input type="hidden" name="itemId" value={itemId} />54      <TextInput name="note" defaultValue={note ?? ''} placeholder="Note" maxLength={500} className="h-8 text-xs md:text-xs" />55      <TextInput name="targetPriceUsd" type="number" min={0} step="0.01" defaultValue={targetPriceUsd ?? ''} placeholder="Target (USD)" className="h-8 text-xs md:text-xs" />56      <div className="flex items-center gap-2">57        <SubmitButton variant="secondary" className="h-7 px-2 text-xs">58          Save59        </SubmitButton>60        <button type="button" onClick={() => setOpen(false)} className="text-xs text-muted">61          Cancel62        </button>63        <FormMessage state={state} className="py-0.5 text-xs" />64      </div>65    </form>66  );67}68