Files
frontend/src/pages/card/ui/OperationForm/OperationForm.stories.tsx
T
ksv741 94adbafa34
Frontend verify / commits (pull_request) Successful in 29s
Frontend verify / security (pull_request) Successful in 11s
Frontend verify / verify (pull_request) Successful in 8m43s
refactor: simplify calendar and form state
2026-09-28 20:23:02 +03:00

125 lines
3.3 KiB
TypeScript

import type { Meta, StoryObj } from "@storybook/react-vite";
import { Alert } from "@mantine/core";
import { type FC, useState } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
import type { OperationValues } from "./OperationForm.types";
import { OperationFormView } from "./OperationForm.view";
type ExampleProps = { conflict?: boolean; pending?: boolean };
const OperationExample: FC<ExampleProps> = (props) => {
const [opened, setOpened] = useState(true);
const [action, setAction] = useState("");
const methods = useForm<OperationValues>({
defaultValues: {
amount: "500",
cardId: "demo",
categoryId: "",
date: "2026-08-01",
description: "Синтетический возврат",
kind: "refund",
originalExpenseId: "purchase",
targetCardId: "",
},
});
const kind = useWatch({ control: methods.control, name: "kind" });
return (
<FormProvider {...methods}>
<OperationFormView
categoriesOpen={false}
editing
emptyExpenses={false}
feedback={
props.conflict && (
<Alert color="orange" role="alert">
Синтетический конфликт версии
</Alert>
)
}
fields={{
cards: [{ label: "Учебная карта", value: "demo" }],
categories: [],
dateInputValue: () => "2026-08-01",
defaultCategory: "",
editing: true,
kind,
kinds: [{ label: "Возврат", value: "refund" }],
maxDate: () => "2026-08-27",
refundCardId: "demo",
targets: [],
validDate: value => value === "2026-08-01",
}}
latest={
props.conflict
? {
details: "Учебная версия",
onAdopt: () => setAction("Локальное принятие версии"),
version: 2,
}
: undefined
}
loadingExpenses={false}
nextDisabled
onAddCategory={() => {}}
onCancel={() => setOpened(false)}
onClose={() => !props.pending && setOpened(false)}
onExitTransitionEnd={() => setAction("Форма закрыта")}
onNext={() => {}}
onPrevious={() => {}}
onReload={
props.conflict ? () => setAction("Локальный reload") : undefined
}
onSubmit={(event) => {
event.preventDefault();
setAction("Локальный submit");
}}
opened={opened}
pending={Boolean(props.pending)}
previousDisabled
refund={{
editing: true,
expenses: [
{
label: "01.07.2026 · Учебная покупка · 500 ₽",
value: "purchase",
},
],
limit: { currency: "RUB", value: "500" },
}}
saveDisabled={false}
sourcePage={1}
/>
<output aria-live="polite">{action}</output>
</FormProvider>
);
};
const meta = {
component: OperationExample,
parameters: {
docs: {
description: {
component:
"Synthetic presentation без API/VM. Date callbacks фиксируют fixture 01.08.2026; денежная validation, recovery и nested category flow проверяются application tests. Actions только локальные.",
},
},
},
tags: ["autodocs"],
title: "Product/OperationForm",
} satisfies Meta<typeof OperationExample>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Refund: Story = {};
export const Pending: Story = { args: { pending: true } };
export const Conflict: Story = { args: { conflict: true } };