"use client"; import Link from "next/link"; import { useMemo, useState } from "react"; import { insertSetting, deleteSetting, updateSetting, } from "@/app/actions/settings-actions"; import { coinsToRc, parseStoredCoins, rcToCoins, } from "@/lib/coins-rc"; import type { DbSetting } from "@/types/database"; type Props = { rows: DbSetting[]; saveError: boolean; addError: string | null; }; function DefaultSettingRow({ row, index }: { row: DbSetting; index: number }) { const [value, setValue] = useState(row.value ?? ""); const saveDisabled = value.trim() === ""; return (
setValue(e.target.value)} autoComplete="off" className="mt-1.5 w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 shadow-sm focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100" />
); } function BetFeeRow({ row, index }: { row: DbSetting; index: number }) { const initial = Math.min( 100, Math.max(0, Math.round(Number(row.value ?? 0))), ); const [v, setV] = useState(initial); return (

0–100 (saved as the number shown).

setV(Number(e.target.value))} className="h-2 w-full min-w-[200px] max-w-md cursor-pointer accent-zinc-900 dark:accent-zinc-100" /> {v}
); } function EntryFeeRow({ row, index }: { row: DbSetting; index: number }) { const initialCoins = parseStoredCoins(row.value); const initialRc = coinsToRc(initialCoins); const [rcText, setRcText] = useState(() => initialRc.toFixed(1)); const [localError, setLocalError] = useState(null); const coinsPreview = useMemo(() => { const t = rcText.trim(); if (t === "") return null; return rcToCoins(Number(t)); }, [rcText]); const saveDisabled = rcText.trim() === ""; return (
{ setLocalError(null); const trimmed = rcText.trim(); if (trimmed === "") { e.preventDefault(); setLocalError( "Enter an RC value (one decimal place; tenths digit 0–3).", ); return; } const rc = Number(trimmed); const coins = rcToCoins(rc); if (coins === null) { e.preventDefault(); setLocalError( "Enter a valid RC with one decimal place; the tenths digit must be 0–3 (e.g. 5.1).", ); } }} >
setRcText(e.target.value)} className="mt-1.5 w-full max-w-xs rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 shadow-sm focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100" /> {localError ? (

{localError}

) : coinsPreview !== null ? (

Saves as {coinsPreview} coin{coinsPreview === 1 ? "" : "s"} in the database.

) : rcText.trim() !== "" ? (

Not a valid RC encoding yet — fix the value to save.

) : null}
); } function SettingRow({ row, index }: { row: DbSetting; index: number }) { if (row.key === "bet_fee") { return ; } if (row.key === "entry_fee") { return ; } return ; } export function AdminSettingsEditor({ rows, saveError, addError, }: Props) { const [newKey, setNewKey] = useState(""); const [newValue, setNewValue] = useState(""); return (
{saveError ? (
Could not save that row. Try again or check Supabase connectivity.
) : null}

Existing keys

{rows.length === 0 ? (

No settings rows yet. Add one below.

) : (
{rows.map((row, i) => ( ))}
)}

Add setting

{addError === "duplicate" ? (

That key already exists. Edit it in the list above instead.

) : addError === "missing" ? (

Enter a non-empty key.

) : addError === "missingValue" ? (

Enter a non-empty value.

) : addError === "config" ? (

Supabase admin client is not configured.

) : addError === "other" ? (

Could not insert. Check constraints and retry.

) : null}
setNewKey(e.target.value)} autoComplete="off" placeholder="e.g. maintenance_message" className="mt-1 w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 shadow-sm focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100" />
setNewValue(e.target.value)} autoComplete="off" className="mt-1 w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm text-zinc-900 shadow-sm focus:border-sky-500 focus:outline-none focus:ring-1 focus:ring-sky-500 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100" />

Back to dashboard

); }