| @@ -21,6 +21,7 @@ export const ApiId = { | |||||
| SEASON_TICKET_CONTRACTS: id++, | SEASON_TICKET_CONTRACTS: id++, | ||||
| PAYMENT_PLANS: id++, | PAYMENT_PLANS: id++, | ||||
| SEASON_TICKET_CONTRACT_STICKER_RE_ORDER: id++, | SEASON_TICKET_CONTRACT_STICKER_RE_ORDER: id++, | ||||
| SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER: id++, | |||||
| SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER: id++, | SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER: id++, | ||||
| SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER: id++, | SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER: id++, | ||||
| SEASON_TICKET_CONTRACT_TERMINATE_ORDER: id++, | SEASON_TICKET_CONTRACT_TERMINATE_ORDER: id++, | ||||
| @@ -28,6 +28,7 @@ export type SeasonTicketContract = { | |||||
| can_change_plan_apply: boolean | null; | can_change_plan_apply: boolean | null; | ||||
| can_parking_certificate_apply: boolean | null; | can_parking_certificate_apply: boolean | null; | ||||
| is_terminated: boolean | null; | is_terminated: boolean | null; | ||||
| is_ic_season_ticket: boolean | null; | |||||
| revision: number; | revision: number; | ||||
| }; | }; | ||||
| @@ -84,6 +85,24 @@ export const reOrderSticker = async (data: StickerReOrderRequest) => { | |||||
| }); | }); | ||||
| return res; | return res; | ||||
| }; | }; | ||||
| // -------駐車場利用方法変更依頼------------------ | |||||
| type ParkingUseTypeChangeOrderRequest = { | |||||
| season_ticket_contract_record_no: string; | |||||
| parking_name: string; | |||||
| parking_use_type: string; | |||||
| memo?: string; | |||||
| }; | |||||
| export const parkingUseTypeChangeOrder = async ( | |||||
| data: ParkingUseTypeChangeOrderRequest | |||||
| ) => { | |||||
| const res = await request({ | |||||
| url: getUrl(ApiId.SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER), | |||||
| method: HttpMethod.POST, | |||||
| data: makeParam(data), | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| // -------定期券再発行依頼------------------ | // -------定期券再発行依頼------------------ | ||||
| type SeasonTicketReOrderRequest = { | type SeasonTicketReOrderRequest = { | ||||
| season_ticket_contract_record_no: string; | season_ticket_contract_record_no: string; | ||||
| @@ -14,6 +14,8 @@ const urls = { | |||||
| "season-ticket-contract/season-ticket-re-order", | "season-ticket-contract/season-ticket-re-order", | ||||
| [A.SEASON_TICKET_CONTRACT_STICKER_RE_ORDER]: | [A.SEASON_TICKET_CONTRACT_STICKER_RE_ORDER]: | ||||
| "season-ticket-contract/sticker-re-order", | "season-ticket-contract/sticker-re-order", | ||||
| [A.SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER]: | |||||
| "season-ticket-contract/parking-use-type-change-order", | |||||
| [A.SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER]: | [A.SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER]: | ||||
| "season-ticket-contract/parking-certificate-order", | "season-ticket-contract/parking-certificate-order", | ||||
| [A.SEASON_TICKET_CONTRACT_TERMINATE_ORDER]: | [A.SEASON_TICKET_CONTRACT_TERMINATE_ORDER]: | ||||
| @@ -143,6 +143,22 @@ export default function ContractDetail() { | |||||
| </Button> | </Button> | ||||
| </Box> | </Box> | ||||
| )} | )} | ||||
| {seasonTicketContract.is_ic_season_ticket && ( | |||||
| <Box> | |||||
| <Button | |||||
| variant="contained" | |||||
| onClick={() => { | |||||
| navigateWhenChanged( | |||||
| getPath( | |||||
| PageID.DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER | |||||
| ) | |||||
| ); | |||||
| }} | |||||
| > | |||||
| 駐車場利用方法変更申請 | |||||
| </Button> | |||||
| </Box> | |||||
| )} | |||||
| {seasonTicketContract.has_season_ticket && ( | {seasonTicketContract.has_season_ticket && ( | ||||
| <Box> | <Box> | ||||
| <Button | <Button | ||||
| @@ -0,0 +1,222 @@ | |||||
| import { yupResolver } from "@hookform/resolvers/yup"; | |||||
| import { | |||||
| Box, | |||||
| Button, | |||||
| Stack, | |||||
| Table, | |||||
| TableBody, | |||||
| TableCell, | |||||
| TableRow, | |||||
| Typography, | |||||
| } from "@mui/material"; | |||||
| import { HasChildren } from "@types"; | |||||
| import { | |||||
| parkingUseTypeChangeOrder, | |||||
| reOrderSticker, | |||||
| } from "api/season-ticket-contract"; | |||||
| import InputAlert from "components/form/InputAlert"; | |||||
| import TextFieldEx from "components/form/TextFieldEx"; | |||||
| import { FormProvider, RHFSelect, RHFTextField } from "components/hook-form"; | |||||
| import { SelectOptionProps } from "components/hook-form/RHFSelect"; | |||||
| import StackRow from "components/stack/StackRow"; | |||||
| import { useSeasonTicketContractContext } from "contexts/dashboard/SeasonTicketContractContext"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import useDashboard from "hooks/useDashBoard"; | |||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { PageID, TabID } from "pages"; | |||||
| import { useEffect, useState } from "react"; | |||||
| import { useForm } from "react-hook-form"; | |||||
| import { getPath } from "routes/path"; | |||||
| import { object, string } from "yup"; | |||||
| type AreaBoxProps = { | |||||
| label: string; | |||||
| } & HasChildren; | |||||
| function AreaBox({ label, children }: AreaBoxProps) { | |||||
| return ( | |||||
| <Box> | |||||
| <Typography variant="body2">{label}</Typography> | |||||
| {children} | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| type FormProps = { | |||||
| parking_use_type: string; | |||||
| memo: string; | |||||
| }; | |||||
| export default function ParkingUseTypeChangeOrder() { | |||||
| const { setHeaderTitle, setTabs } = useDashboard( | |||||
| PageID.DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER, | |||||
| TabID.NONE | |||||
| ); | |||||
| const form = useForm<FormProps>({ | |||||
| defaultValues: { | |||||
| parking_use_type: "", | |||||
| memo: "", | |||||
| }, | |||||
| resolver: yupResolver( | |||||
| object().shape({ | |||||
| parking_use_type: string().required("入力してください"), | |||||
| }) | |||||
| ), | |||||
| }); | |||||
| const { navigateWhenChanged } = useNavigateCustom(); | |||||
| const { error } = useSnackbarCustom(); | |||||
| const { selectedseasonTicketContract, backToDetailHome } = | |||||
| useSeasonTicketContractContext(); | |||||
| const [mode, setMode] = useState<"input" | "confirm" | "done">("input"); | |||||
| const { callAPI: callParkingUseTypeChangeOrder, errorMode } = useAPICall({ | |||||
| apiMethod: parkingUseTypeChangeOrder, | |||||
| backDrop: true, | |||||
| form, | |||||
| onSuccess: () => { | |||||
| setMode("done"); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("依頼失敗しました"); | |||||
| setMode("input"); | |||||
| }, | |||||
| }); | |||||
| const handleSubmit = () => { | |||||
| setMode("confirm"); | |||||
| }; | |||||
| const send = () => { | |||||
| if (selectedseasonTicketContract === null) return; | |||||
| callParkingUseTypeChangeOrder({ | |||||
| season_ticket_contract_record_no: | |||||
| selectedseasonTicketContract.season_ticekt_contract_record_no ?? "", | |||||
| parking_name: selectedseasonTicketContract.parking_name ?? "", | |||||
| ...form.getValues(), | |||||
| }); | |||||
| }; | |||||
| const options: SelectOptionProps[] = [ | |||||
| { value: "貸与ICカード", label: "貸与ICカード" }, | |||||
| { value: "個人所有Felica", label: "個人所有Felica" }, | |||||
| { value: "QRコード", label: "QRコード" }, | |||||
| ]; | |||||
| useEffect(() => { | |||||
| setHeaderTitle("駐車場利用方法変更依頼"); | |||||
| setTabs(null); | |||||
| }, [setHeaderTitle, setTabs]); | |||||
| useEffect(() => { | |||||
| if (selectedseasonTicketContract === null) { | |||||
| navigateWhenChanged( | |||||
| getPath(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST) | |||||
| ); | |||||
| } | |||||
| }, [selectedseasonTicketContract]); | |||||
| if (selectedseasonTicketContract === null) { | |||||
| return null; | |||||
| } | |||||
| if (mode === "done") { | |||||
| return ( | |||||
| <Box sx={{ mt: 1 }}> | |||||
| <Stack spacing={2}> | |||||
| <Box>依頼しました</Box> | |||||
| <Box> | |||||
| <Button onClick={backToDetailHome}>戻る</Button> | |||||
| </Box> | |||||
| </Stack> | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| if (mode === "confirm") { | |||||
| return ( | |||||
| <Box sx={{ mt: 1 }}> | |||||
| <Stack spacing={2}> | |||||
| <Box> | |||||
| <Typography>下記内容で申請を行います。</Typography> | |||||
| </Box> | |||||
| <Box> | |||||
| <Table size="small"> | |||||
| <TableBody> | |||||
| <TableRow> | |||||
| <TableCell>駐車場利用方法</TableCell> | |||||
| <TableCell> | |||||
| <TextFieldEx | |||||
| value={form.getValues("parking_use_type")} | |||||
| readOnly | |||||
| fullWidth | |||||
| /> | |||||
| </TableCell> | |||||
| </TableRow> | |||||
| <TableRow> | |||||
| <TableCell>備考</TableCell> | |||||
| <TableCell> | |||||
| <TextFieldEx | |||||
| multiline | |||||
| value={form.getValues("memo")} | |||||
| readOnly | |||||
| fullWidth | |||||
| /> | |||||
| </TableCell> | |||||
| </TableRow> | |||||
| </TableBody> | |||||
| </Table> | |||||
| </Box> | |||||
| <StackRow spacing={2}> | |||||
| <Button | |||||
| onClick={() => { | |||||
| setMode("input"); | |||||
| }} | |||||
| > | |||||
| 戻る | |||||
| </Button> | |||||
| <Button onClick={send} variant="contained"> | |||||
| 送信 | |||||
| </Button> | |||||
| </StackRow> | |||||
| </Stack> | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| return ( | |||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | |||||
| <Box sx={{ mt: 1 }}> | |||||
| <Stack spacing={2}> | |||||
| <Box> | |||||
| <Button onClick={backToDetailHome}>戻る</Button> | |||||
| </Box> | |||||
| <InputAlert error={errorMode} /> | |||||
| <AreaBox label="駐車場利用方法"> | |||||
| <RHFSelect name="parking_use_type" size="small" options={options} /> | |||||
| </AreaBox> | |||||
| <AreaBox label="備考"> | |||||
| <RHFTextField | |||||
| name="memo" | |||||
| size="small" | |||||
| multiline | |||||
| minRows={3} | |||||
| maxRows={10} | |||||
| /> | |||||
| </AreaBox> | |||||
| <Box> | |||||
| <Button variant="contained" type="submit"> | |||||
| 次へ | |||||
| </Button> | |||||
| </Box> | |||||
| </Stack> | |||||
| </Box> | |||||
| </FormProvider> | |||||
| ); | |||||
| } | |||||
| @@ -14,6 +14,7 @@ export const PageID = { | |||||
| DASHBOARD_SEASON_TICKET_CONTRACT_LIST: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_LIST: id++, | ||||
| DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL: id++, | ||||
| DASHBOARD_SEASON_TICKET_CONTRACT_STICKER_RE_ORDER: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_STICKER_RE_ORDER: id++, | ||||
| DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER: id++, | |||||
| DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER: id++, | ||||
| DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_CERTIFICATE_ORDER: id++, | ||||
| DASHBOARD_SEASON_TICKET_CONTRACT_TERMINATE_ORDER: id++, | DASHBOARD_SEASON_TICKET_CONTRACT_TERMINATE_ORDER: id++, | ||||
| @@ -39,6 +39,9 @@ const PATHS_DASHBOARD = { | |||||
| "/dashboard/contract/detail/:id", | "/dashboard/contract/detail/:id", | ||||
| [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_STICKER_RE_ORDER)]: | [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_STICKER_RE_ORDER)]: | ||||
| "/dashboard/contract/sticker-re-order", | "/dashboard/contract/sticker-re-order", | ||||
| [makePathKey( | |||||
| PageID.DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER | |||||
| )]: "/dashboard/contract/parking-use-type-change-order", | |||||
| [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER)]: | [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER)]: | ||||
| "/dashboard/contract/season-ticket-re-order", | "/dashboard/contract/season-ticket-re-order", | ||||
| [makePathKey( | [makePathKey( | ||||
| @@ -86,6 +86,11 @@ export default function DashboardRoutes(): RouteObject[] { | |||||
| const SeasonTicketReOrder = Loadable( | const SeasonTicketReOrder = Loadable( | ||||
| lazy(() => import("pages/dashboard/contract/season-ticket-re-order")) | lazy(() => import("pages/dashboard/contract/season-ticket-re-order")) | ||||
| ); | ); | ||||
| const ParkingUseTypeChangeOrder = Loadable( | |||||
| lazy( | |||||
| () => import("pages/dashboard/contract/parking-use-type-change-order") | |||||
| ) | |||||
| ); | |||||
| const TerminateOrder = Loadable( | const TerminateOrder = Loadable( | ||||
| lazy(() => import("pages/dashboard/contract/terminate-order")) | lazy(() => import("pages/dashboard/contract/terminate-order")) | ||||
| ); | ); | ||||
| @@ -124,6 +129,11 @@ export default function DashboardRoutes(): RouteObject[] { | |||||
| pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER, | pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_SEASON_TICKET_RE_ORDER, | ||||
| element: <SeasonTicketReOrder />, | element: <SeasonTicketReOrder />, | ||||
| }, | }, | ||||
| { | |||||
| pageId: | |||||
| PageID.DASHBOARD_SEASON_TICKET_CONTRACT_PARKING_USE_TYPE_CHANGE_ORDER, | |||||
| element: <ParkingUseTypeChangeOrder />, | |||||
| }, | |||||
| { | { | ||||
| pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_TERMINATE_ORDER, | pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_TERMINATE_ORDER, | ||||
| element: <TerminateOrder />, | element: <TerminateOrder />, | ||||