Преглед на файлове

領収証Email送付依頼 機能追加

develop
sosuke.iwabuchi преди 2 години
родител
ревизия
3724a3c149
променени са 9 файла, в които са добавени 275 реда и са изтрити 2 реда
  1. +16
    -1
      src/api/app/receipt-issuing-order.ts
  2. +1
    -0
      src/api/index.ts
  3. +1
    -0
      src/api/url.ts
  4. +1
    -0
      src/codes/page.ts
  5. +171
    -0
      src/pages/app/EmailOrder.tsx
  6. +72
    -0
      src/pages/app/hooks/useInputEmailStep.tsx
  7. +6
    -1
      src/pages/app/hooks/useReceiptIssuingOrderSelectHowToGet.tsx
  8. +5
    -0
      src/routes/index.tsx
  9. +2
    -0
      src/routes/path.ts

+ 16
- 1
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;
};

+ 1
- 0
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++,


+ 1
- 0
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",


+ 1
- 0
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++,



+ 171
- 0
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 (
<TableRow>
<TableCell sx={{ borderRight: "1px solid rgba(224, 224, 224, 1)" }}>
{title}
</TableCell>
<TableCell>{value}</TableCell>
</TableRow>
);
};

type SectionProps = {
title: string;
subtitle?: string;
} & HasChildren;
const Section = ({ title, subtitle, children }: SectionProps) => {
return (
<Paper
sx={{ py: 2, border: "1px solid rgba(224, 224, 224, 1)" }}
elevation={0}
>
<Box>
<Typography variant="subtitle1">{title}</Typography>
{subtitle && <Typography variant="body2">{subtitle}</Typography>}
</Box>
<Box sx={{ mt: 2 }}>{children}</Box>
</Paper>
);
};

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 (
<>
<Box sx={{ p: 3, pt: 5, mx: "auto", maxWidth: 500 }} textAlign="center">
<Stack spacing={3}>
<Box>
<Typography variant="h5">領収証Email送付依頼</Typography>
</Box>

<Section title="">
<Stepper activeStep={currentStep}>
<Step>
<StepLabel>Email送信先入力</StepLabel>
</Step>
<Step>
<StepLabel>確認</StepLabel>
</Step>
<Step>
<StepLabel>完了</StepLabel>
</Step>
</Stepper>
{mode === "input" && input.element}
{mode === "confirm" && (
<Stack spacing={2} sx={{ p: 1, py: 3, m: 1 }}>
<Typography variant="h5">Email送信先情報確認</Typography>
<Table>
<TableBody>
<TableRowCustom
title="Email"
value={input.values("email")}
/>
</TableBody>
</Table>
<Stack direction="row" spacing={2}>
<Button
variant="text"
onClick={() => {
setMode("input");
}}
>
戻る
</Button>
<Button variant="contained" onClick={handleConfirm}>
確定
</Button>
</Stack>
</Stack>
)}
{mode === "done" && (
<Stack spacing={2} sx={{ p: 1, py: 3, m: 1 }}>
<Box>受付いたしました。</Box>
<Button onClick={navigateToHome}>戻る</Button>
</Stack>
)}
</Section>
</Stack>
</Box>
</>
);
}

+ 72
- 0
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 (
<Box sx={{ maxWidth: 500 }}>
<Typography variant="subtitle1">{title}</Typography>
{children}
</Box>
);
}

type FormProps = {
email: string;
};

type Props = {
onNext?: VoidFunction;
onPrev?: VoidFunction;
};
export default function useInputEmailStep({ onNext, onPrev }: Props) {
const form = useForm<FormProps>({
defaultValues: {
email: "",
},
resolver: yupResolver(
Yup.object().shape({
email: Yup.string().required("必須項目です"),
})
),
});

const handleSubmit = () => {
if (onNext) {
onNext();
}
};

const handlePrev = () => {
if (onPrev) {
onPrev();
}
};

const element = (
<FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}>
<Stack spacing={2} sx={{ p: 1, m: 1 }} textAlign="left">
<AreaBox title="Email">
<RHFTextField name="email" />
</AreaBox>
<Divider />
<Stack direction="row" spacing={2}>
<Button variant="text" onClick={handlePrev}>
戻る
</Button>
<Button variant="contained" type="submit">
次へ
</Button>
</Stack>
</Stack>
</FormProvider>
);

return { element, values: form.getValues, setValue: form.setValue };
}

+ 6
- 1
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 = (
<Stack spacing={1}>
@@ -31,7 +34,9 @@ export default function useReceiptIssuingOrderSelectHowToGet() {
</Button>
</Box>
<Box>
<Button variant="contained">メール送信依頼</Button>
<Button variant="contained" onClick={handleClickEmail}>
メール送信依頼
</Button>
</Box>
{!order?.status_order_mail_datetime && (
<Box>


+ 5
- 0
src/routes/index.tsx Целия файл

@@ -50,6 +50,10 @@ const AppRoutes = (): RouteObject => ({
path: getRoute(PageID.APP_RECEIPT_ISSUING_ORDER_MAIL_ORDER),
element: <MailOrder />,
},
{
path: getRoute(PageID.APP_RECEIPT_ISSUING_ORDER_EMAIL_ORDER),
element: <EmailOrder />,
},
],
});

@@ -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")));


+ 2
- 0
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)]:


Loading…
Отказ
Запис