match the budget picker to the rules picker

This commit is contained in:
Owen
2026-08-10 13:55:05 -04:00
parent 7e6e0a8a9c
commit f2e7f83b3d
+48 -96
View File
@@ -1,13 +1,10 @@
"use client"; "use client";
import { import {
SettingsFormCell,
SettingsFormGrid,
SettingsSection, SettingsSection,
SettingsSectionBody, SettingsSectionBody,
SettingsSectionDescription, SettingsSectionDescription,
SettingsSectionFooter, SettingsSectionFooter,
SettingsSectionForm,
SettingsSectionHeader, SettingsSectionHeader,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
@@ -281,22 +278,13 @@ export function BudgetsEditor({
</SettingsSectionHeader> </SettingsSectionHeader>
<SettingsSectionBody> <SettingsSectionBody>
<SettingsSectionForm>
<SettingsFormGrid>
<SettingsFormCell span="half">
<div className="space-y-4"> <div className="space-y-4">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead> <TableHead>{t("aiBudgetAmount")}</TableHead>
{t("aiBudgetUnit")} <TableHead>{t("aiBudgetUnit")}</TableHead>
</TableHead> <TableHead>{t("aiBudgetPeriod")}</TableHead>
<TableHead>
{t("aiBudgetPeriod")}
</TableHead>
<TableHead>
{t("aiBudgetAmount")}
</TableHead>
<TableHead></TableHead> <TableHead></TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
@@ -310,29 +298,46 @@ export function BudgetsEditor({
/> />
) : ( ) : (
rows.map((row) => { rows.map((row) => {
const showConflict = const showConflict = conflictingKeys.has(
conflictingKeys.has(
row.key row.key
); );
const showInvalidAmount = const showInvalidAmount =
attemptedSave && attemptedSave &&
invalidAmountKeys.has( invalidAmountKeys.has(row.key);
row.key
);
return ( return (
<TableRow key={row.key}> <TableRow key={row.key}>
<TableCell>
<Input
type="number"
min="0"
step="any"
placeholder={t(
"aiBudgetAmountPlaceholder"
)}
value={row.amount}
aria-invalid={
showInvalidAmount
}
disabled={
saveLoading ||
budgetsQuery.isLoading
}
onChange={(e) =>
updateRow(row.key, {
amount: e.target
.value
})
}
className="w-full min-w-0"
/>
</TableCell>
<TableCell> <TableCell>
<Select <Select
value={row.unit} value={row.unit}
onValueChange={( onValueChange={(value) =>
value updateRow(row.key, {
) =>
updateRow(
row.key,
{
unit: value as AiBudgetUnit unit: value as AiBudgetUnit
} })
)
} }
disabled={ disabled={
saveLoading || saveLoading ||
@@ -349,16 +354,10 @@ export function BudgetsEditor({
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{AI_BUDGET_UNITS.map( {AI_BUDGET_UNITS.map(
( (unit) => (
unit
) => (
<SelectItem <SelectItem
key={ key={unit}
unit value={unit}
}
value={
unit
}
> >
{ {
unitLabels[ unitLabels[
@@ -373,18 +372,11 @@ export function BudgetsEditor({
</TableCell> </TableCell>
<TableCell> <TableCell>
<Select <Select
value={ value={row.period}
row.period onValueChange={(value) =>
} updateRow(row.key, {
onValueChange={(
value
) =>
updateRow(
row.key,
{
period: value as AiBudgetPeriod period: value as AiBudgetPeriod
} })
)
} }
disabled={ disabled={
saveLoading || saveLoading ||
@@ -401,13 +393,9 @@ export function BudgetsEditor({
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{AI_BUDGET_PERIODS.map( {AI_BUDGET_PERIODS.map(
( (period) => (
period
) => (
<SelectItem <SelectItem
key={ key={period}
period
}
value={ value={
period period
} }
@@ -424,53 +412,21 @@ export function BudgetsEditor({
</Select> </Select>
</TableCell> </TableCell>
<TableCell> <TableCell>
<Input <div className="flex items-center justify-end space-x-2">
type="number"
min="0"
step="any"
placeholder={t(
"aiBudgetAmountPlaceholder"
)}
value={
row.amount
}
aria-invalid={
showInvalidAmount
}
disabled={
saveLoading ||
budgetsQuery.isLoading
}
onChange={(e) =>
updateRow(
row.key,
{
amount: e
.target
.value
}
)
}
className="w-full min-w-0"
/>
</TableCell>
<TableCell>
<Button <Button
type="button" type="button"
variant="ghost" variant="outline"
size="icon"
disabled={ disabled={
saveLoading || saveLoading ||
budgetsQuery.isLoading budgetsQuery.isLoading
} }
onClick={() => onClick={() =>
removeRow( removeRow(row.key)
row.key
)
} }
> >
<Trash2 className="h-4 w-4 text-destructive" /> Delete
</Button> </Button>
</div>
</TableCell> </TableCell>
</TableRow> </TableRow>
); );
@@ -479,8 +435,7 @@ export function BudgetsEditor({
</TableBody> </TableBody>
</Table> </Table>
{(conflictingKeys.size > 0 || {(conflictingKeys.size > 0 ||
(attemptedSave && (attemptedSave && invalidAmountKeys.size > 0)) && (
invalidAmountKeys.size > 0)) && (
<p className="text-xs text-destructive"> <p className="text-xs text-destructive">
{conflictingKeys.size > 0 {conflictingKeys.size > 0
? t("aiBudgetConflictError") ? t("aiBudgetConflictError")
@@ -489,9 +444,6 @@ export function BudgetsEditor({
)} )}
{rows.length > 0 && addRowButton} {rows.length > 0 && addRowButton}
</div> </div>
</SettingsFormCell>
</SettingsFormGrid>
</SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
<SettingsSectionFooter> <SettingsSectionFooter>