feat(ui): add finance plan editor
Plans default to an equal split, each slice is individually editable, and plans compose with splits. Cancelling keeps past slices. planBalance delegates to domain slicesBalance rather than recomputing the same total-minus-slices arithmetic, per the project's one-implementation rule for shared math.
This commit is contained in:
1 parent
5a11941d39
commit
5b879809d2
4 files changed
+235
-1
No files matched your search
@@ -11,6 +11,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { SplitEditor } from "./SplitEditor.tsx";
|
||||
import { PlanEditor } from "./PlanEditor.tsx";
|
||||
import {
|
||||
emptyDraft,
|
||||
fromPurchase,
|
||||
@@ -20,7 +21,7 @@ import {
|
||||
} from "../purchaseForm.ts";
|
||||
import { useDataset } from "../hooks/useDataset.ts";
|
||||
import { useMutate } from "../hooks/useMutate.ts";
|
||||
import { addPurchase, updatePurchase } from "../../store/actions.ts";
|
||||
import { addPurchase, cancelScheduleFrom, updatePurchase } from "../../store/actions.ts";
|
||||
import { CURRENCIES, type MonthId, type Purchase } from "../../domain/types.ts";
|
||||
|
||||
interface Props {
|
||||
@@ -128,6 +129,22 @@ export function PurchaseDialog({ monthId, purchase, trigger }: Props) {
|
||||
|
||||
<SplitEditor draft={draft} posts={activePosts} onChange={setDraft} />
|
||||
|
||||
<PlanEditor draft={draft} onChange={setDraft} />
|
||||
|
||||
{purchase?.schedule && !purchase.schedule.cancelledFromMonth && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
mutate((data) => cancelScheduleFrom(data, purchase.id, monthId));
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
Cancel remaining slices from {monthId}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{errors.length > 0 && (
|
||||
<ul className="space-y-1 text-sm text-destructive">
|
||||
{errors.map((message) => (
|
||||
|
||||
Reference in new issue
Block a user