diff --git a/src/api/app/receipt-issuing-order.ts b/src/api/app/receipt-issuing-order.ts index 58e9efc..b4fbbfa 100644 --- a/src/api/app/receipt-issuing-order.ts +++ b/src/api/app/receipt-issuing-order.ts @@ -1,4 +1,4 @@ -import { ApiId, HttpMethod, makeParam, request } from ".."; +import { ApiId, HttpMethod, TimestampRequest, makeParam, request } from ".."; import { getUrl } from "../url"; export type AppReceiptIssuingOrder = { @@ -56,3 +56,18 @@ export const mailRequest = async (data: MailOrderRequest) => { }); return res; }; + +// 領収証Email送付依頼 ------------------------------- +export type EmailOrderRequest = { + access_token: string; + email: string; +} & TimestampRequest; + +export const emailRequest = async (data: EmailOrderRequest) => { + const res = await request({ + url: getUrl(ApiId.RECEIPT_ISSUING_ORDER_EMAIL_ORDER), + method: HttpMethod.POST, + data: makeParam(data), + }); + return res; +}; diff --git a/src/api/index.ts b/src/api/index.ts index 5538cda..e15e188 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -19,6 +19,7 @@ export const ApiId = { RECEIPT_ISSUING_ORDER_CONFIRM: id++, DOWNLOAD_RECEIPT: id++, RECEIPT_ISSUING_ORDER_MAIL_ORDER: id++, + RECEIPT_ISSUING_ORDER_EMAIL_ORDER: id++, // DASHBOARD向け------------------------------- CHANGE_CONTRACT: id++, diff --git a/src/api/url.ts b/src/api/url.ts index 1113c26..3218c24 100644 --- a/src/api/url.ts +++ b/src/api/url.ts @@ -15,6 +15,7 @@ const urls = { [A.RECEIPT_ISSUING_ORDER_MAIL_ORDER]: "receipt-issuing-order/mail-order", [A.RECEIPT_ISSUING_ORDER_MAIL_POST_COMPLETE]: "receipt-issuing-order/mail-complete", + [A.RECEIPT_ISSUING_ORDER_EMAIL_ORDER]: "receipt-issuing-order/email-order", [A.RECEIPT_ISSUING_ORDER_HANDELRS]: "receipt-issuing-order/handlers", [A.RECEIPT_ISSUING_ORDER_CHANGE_HANDELR]: "receipt-issuing-order/change-handler", diff --git a/src/codes/page.ts b/src/codes/page.ts index 3f6ff41..96d26ef 100644 --- a/src/codes/page.ts +++ b/src/codes/page.ts @@ -8,6 +8,7 @@ export const PageID = { APP_RECEIPT_ISSUING_ORDER_INDEX: id++, APP_RECEIPT_ISSUING_ORDER_MAIL_ORDER: id++, + APP_RECEIPT_ISSUING_ORDER_EMAIL_ORDER: id++, DASHBOARD_OVERVIEW: id++, diff --git a/src/pages/app/EmailOrder.tsx b/src/pages/app/EmailOrder.tsx new file mode 100644 index 0000000..d3ea22d --- /dev/null +++ b/src/pages/app/EmailOrder.tsx @@ -0,0 +1,171 @@ +import { + Box, + Button, + Paper, + Stack, + Step, + StepLabel, + Stepper, + Table, + TableBody, + TableCell, + TableRow, + Typography, +} from "@mui/material"; +import { HasChildren } from "@types"; +import { emailRequest } from "api/app/receipt-issuing-order"; +import useAPICall from "hooks/useAPICall"; +import useApp from "hooks/useApp"; +import useNavigateCustom from "hooks/useNavigateCustom"; +import useSnackbarCustom from "hooks/useSnackbarCustom"; +import { useMemo, useState } from "react"; +import useInputEmailStep from "./hooks/useInputEmailStep"; + +type TableRowCustomProps = { + title: string; + value: string; +}; +const TableRowCustom = ({ title, value }: TableRowCustomProps) => { + return ( + + + {title} + + {value} + + ); +}; + +type SectionProps = { + title: string; + subtitle?: string; +} & HasChildren; +const Section = ({ title, subtitle, children }: SectionProps) => { + return ( + + + {title} + {subtitle && {subtitle}} + + {children} + + ); +}; + +export default function EmailOrder() { + const { + tokenResult, + token, + navigateToHome, + fetch, + receiptIssuingOrder: order, + } = useApp(); + + const { success, error } = useSnackbarCustom(); + + const { navigate } = useNavigateCustom(); + + const [mode, setMode] = useState<"input" | "confirm" | "done">("input"); + + const input = useInputEmailStep({ + onNext: () => { + setMode("confirm"); + }, + onPrev: () => { + navigate(-1); + }, + }); + + const requestEmailAPI = useAPICall({ + apiMethod: emailRequest, + backDrop: true, + onSuccess: () => { + fetch(); + setMode("done"); + }, + onFailed: () => { + error("登録失敗"); + }, + }); + + const currentStep = useMemo(() => { + if (mode === "input") return 0; + if (mode === "confirm") return 1; + if (mode === "done") return 2; + }, [mode]); + + const handleConfirm = () => { + if (!order) return; + requestEmailAPI.callAPI({ + access_token: token, + timestamp: order.updated_at, + ...input.values(), + }); + }; + + if (tokenResult !== "ok") { + return null; + } + + return ( + <> + + + + 領収証Email送付依頼 + + +
+ + + Email送信先入力 + + + 確認 + + + 完了 + + + {mode === "input" && input.element} + {mode === "confirm" && ( + + Email送信先情報確認 + + + + +
+ + + + +
+ )} + {mode === "done" && ( + + 受付いたしました。 + + + )} +
+
+
+ + ); +} diff --git a/src/pages/app/hooks/useInputEmailStep.tsx b/src/pages/app/hooks/useInputEmailStep.tsx new file mode 100644 index 0000000..67eee00 --- /dev/null +++ b/src/pages/app/hooks/useInputEmailStep.tsx @@ -0,0 +1,72 @@ +import { yupResolver } from "@hookform/resolvers/yup"; +import { Box, Button, Divider, Stack, Typography } from "@mui/material"; +import { HasChildren } from "@types"; +import { FormProvider, RHFTextField } from "components/hook-form"; +import { useForm } from "react-hook-form"; +import * as Yup from "yup"; + +type AreaBoxProps = { + title: string; +} & HasChildren; +function AreaBox({ title, children }: AreaBoxProps) { + return ( + + {title} + {children} + + ); +} + +type FormProps = { + email: string; +}; + +type Props = { + onNext?: VoidFunction; + onPrev?: VoidFunction; +}; +export default function useInputEmailStep({ onNext, onPrev }: Props) { + const form = useForm({ + defaultValues: { + email: "", + }, + resolver: yupResolver( + Yup.object().shape({ + email: Yup.string().required("必須項目です"), + }) + ), + }); + + const handleSubmit = () => { + if (onNext) { + onNext(); + } + }; + + const handlePrev = () => { + if (onPrev) { + onPrev(); + } + }; + + const element = ( + + + + + + + + + + + + + ); + + return { element, values: form.getValues, setValue: form.setValue }; +} diff --git a/src/pages/app/hooks/useReceiptIssuingOrderSelectHowToGet.tsx b/src/pages/app/hooks/useReceiptIssuingOrderSelectHowToGet.tsx index faf1d7e..e522f6f 100644 --- a/src/pages/app/hooks/useReceiptIssuingOrderSelectHowToGet.tsx +++ b/src/pages/app/hooks/useReceiptIssuingOrderSelectHowToGet.tsx @@ -22,6 +22,9 @@ export default function useReceiptIssuingOrderSelectHowToGet() { const handleClickMail = () => { navigateWhenChanged(getPath(PageID.APP_RECEIPT_ISSUING_ORDER_MAIL_ORDER)); }; + const handleClickEmail = () => { + navigateWhenChanged(getPath(PageID.APP_RECEIPT_ISSUING_ORDER_EMAIL_ORDER)); + }; const element = ( @@ -31,7 +34,9 @@ export default function useReceiptIssuingOrderSelectHowToGet() { - + {!order?.status_order_mail_datetime && ( diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 157bb54..30567fc 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -50,6 +50,10 @@ const AppRoutes = (): RouteObject => ({ path: getRoute(PageID.APP_RECEIPT_ISSUING_ORDER_MAIL_ORDER), element: , }, + { + path: getRoute(PageID.APP_RECEIPT_ISSUING_ORDER_EMAIL_ORDER), + element: , + }, ], }); @@ -149,6 +153,7 @@ const ReceiptIssuingOrder = Loadable( lazy(() => import("pages/app/ReceiptIssuingOrder")) ); const MailOrder = Loadable(lazy(() => import("pages/app/MailOrder"))); +const EmailOrder = Loadable(lazy(() => import("pages/app/EmailOrder"))); //ダッシュボード ---------------------------- const Dashboard = Loadable(lazy(() => import("pages/dashboard"))); diff --git a/src/routes/path.ts b/src/routes/path.ts index 0a26e8c..9ac9a0f 100644 --- a/src/routes/path.ts +++ b/src/routes/path.ts @@ -43,6 +43,8 @@ const PATHS = { "/app/receipt-issuing-order/:token", [makePathKey(PageID.APP_RECEIPT_ISSUING_ORDER_MAIL_ORDER)]: "/app/receipt-issuing-order/mail", + [makePathKey(PageID.APP_RECEIPT_ISSUING_ORDER_EMAIL_ORDER)]: + "/app/receipt-issuing-order/email", // 契約関連 [makePathKey(PageID.DASHBOARD_CONTRACT_LIST)]: