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%
3.5 KB · 70 lines tsx
Raw Blame History
1'use client';23import { useActionState, useState } from 'react';4import { updateNotificationPrefsAction } from '@/lib/auth/account-actions';5import { idle } from '@/lib/auth/state';6import { Checkbox, Field, FormMessage, Select, SubmitButton } from '@/components/account/form';78const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];910export function PrefsForm({ prefs }: { prefs: { emailAlerts: boolean; newLoginEmails: boolean; digest: string; digestWeekday: number; quietStart: number | null; quietEnd: number | null; marketMoves: boolean } }) {11  const [state, action] = useActionState(updateNotificationPrefsAction, idle);12  const [quiet, setQuiet] = useState(prefs.quietStart !== null);13  return (14    <form action={action} className="space-y-5" noValidate>15      <FormMessage state={state} />16      <div className="space-y-3">17        <Checkbox name="emailAlerts" label="E-mail me when an alert triggers" description="Price thresholds, new listings, auctions ending, record sales, population updates." defaultChecked={prefs.emailAlerts} />18        <Checkbox name="marketMoves" label="Market moves in my categories" description="Notify when an index I track moves more than 3% in a day." defaultChecked={prefs.marketMoves} />19        <Checkbox name="newLoginEmails" label="New sign-in notifications" description="An e-mail whenever your account is accessed from a new device." defaultChecked={prefs.newLoginEmails} />20      </div>21      <div className="grid gap-4 sm:grid-cols-2">22        <Field label="Digest" name="digest" hint="A summary of your collection, watchlist movers and deals.">23          <Select name="digest" defaultValue={prefs.digest}>24            <option value="weekly">Weekly</option>25            <option value="daily">Daily</option>26            <option value="off">Off</option>27          </Select>28        </Field>29        <Field label="Weekly digest day" name="digestWeekday">30          <Select name="digestWeekday" defaultValue={String(prefs.digestWeekday)}>31            {DAYS.map((d, i) => (32              <option key={d} value={i}>33                {d}34              </option>35            ))}36          </Select>37        </Field>38      </div>39      <div className="space-y-3">40        <label className="flex items-start gap-2.5 text-sm">41          <input type="checkbox" name="quiet" checked={quiet} onChange={(e) => setQuiet(e.target.checked)} className="mt-0.5 h-4 w-4" />42          <span>43            <span className="block">Quiet hours (UTC)</span>44            <span className="block text-xs text-muted">Hold e-mails during these hours; they are delivered afterwards.</span>45          </span>46        </label>47        {quiet ? (48          <div className="grid max-w-xs grid-cols-2 gap-3">49            <Field label="From" name="quietStart">50              <Select name="quietStart" defaultValue={String(prefs.quietStart ?? 22)}>51                {Array.from({ length: 24 }, (_, h) => (52                  <option key={h} value={h}>{`${String(h).padStart(2, '0')}:00`}</option>53                ))}54              </Select>55            </Field>56            <Field label="To" name="quietEnd">57              <Select name="quietEnd" defaultValue={String(prefs.quietEnd ?? 7)}>58                {Array.from({ length: 24 }, (_, h) => (59                  <option key={h} value={h}>{`${String(h).padStart(2, '0')}:00`}</option>60                ))}61              </Select>62            </Field>63          </div>64        ) : null}65      </div>66      <SubmitButton pendingText="Saving…">Save preferences</SubmitButton>67    </form>68  );69}70