| @@ -36,6 +36,11 @@ export const ApiId = { | |||||
| デポジット情報取得: id++, | デポジット情報取得: id++, | ||||
| デポジットチャージ: id++, | デポジットチャージ: id++, | ||||
| 店舗設定: id++, | 店舗設定: id++, | ||||
| 店舗QR設定取得: id++, | |||||
| 店舗QR設定認証設定追加: id++, | |||||
| 店舗QR設定認証設定削除: id++, | |||||
| 店舗QR設定取得設定変更: id++, | |||||
| 店舗QR設定取得設定無効化: id++, | |||||
| // QRサービス券関連------------------------------- | // QRサービス券関連------------------------------- | ||||
| QRサービス券駐車場グループ一覧取得: id++, | QRサービス券駐車場グループ一覧取得: id++, | ||||
| @@ -10,6 +10,21 @@ export type 店舗 = { | |||||
| under_amount_when_auth: number; | under_amount_when_auth: number; | ||||
| under_amount_when_use: number; | under_amount_when_use: number; | ||||
| }; | }; | ||||
| export type QRサービス券認証設定 = { | |||||
| parking_management_code: string; | |||||
| parking_name: string; | |||||
| discount_ticket_code: number; | |||||
| }; | |||||
| export type QRサービス券取得設定 = { | |||||
| qr_service_parking_group_id: string; | |||||
| qr_service_parking_group_name: string; | |||||
| parking_management_code: string; | |||||
| parking_name: string; | |||||
| shop_no: number; | |||||
| discount_ticket_code: number; | |||||
| }; | |||||
| // -------店舗一覧取得--------------- | // -------店舗一覧取得--------------- | ||||
| export type 店舗一覧取得Request = { | export type 店舗一覧取得Request = { | ||||
| shop_id?: string; | shop_id?: string; | ||||
| @@ -104,3 +119,58 @@ export const 店舗設定 = async (param: 店舗設定Request) => { | |||||
| }); | }); | ||||
| return res; | return res; | ||||
| }; | }; | ||||
| // -------店舗QR設定取得--------------- | |||||
| export type 店舗QR設定取得Request = { | |||||
| shop_id: string; | |||||
| }; | |||||
| export type 店舗QR設定取得Response = { | |||||
| data: { | |||||
| shop_id: string; | |||||
| certification: QRサービス券認証設定[]; | |||||
| acquisition: QRサービス券取得設定 | null; | |||||
| }; | |||||
| } & APICommonResponse; | |||||
| export const 店舗QR設定取得 = async (param: 店舗QR設定取得Request) => { | |||||
| const res = await request<店舗QR設定取得Response>({ | |||||
| url: getUrl(ApiId.店舗QR設定取得), | |||||
| method: HttpMethod.GET, | |||||
| data: new URLSearchParams(param), | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| // -------店舗QR設定取得設定変更--------------- | |||||
| export type 店舗QR設定取得設定変更Request = { | |||||
| shop_id: string; | |||||
| qr_service_parking_group_id: string; | |||||
| shop_no: string; | |||||
| discount_ticket_code: string; | |||||
| }; | |||||
| export type 店舗QR設定取得設定変更Response = {} & APICommonResponse; | |||||
| export const 店舗QR設定取得設定変更 = async ( | |||||
| param: 店舗QR設定取得設定変更Request | |||||
| ) => { | |||||
| const res = await request<店舗QR設定取得設定変更Response>({ | |||||
| url: getUrl(ApiId.店舗QR設定取得設定変更), | |||||
| method: HttpMethod.POST, | |||||
| data: makeParam(param), | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| // -------店舗QR設定取得設定無効化--------------- | |||||
| export type 店舗QR設定取得設定無効化Request = { | |||||
| shop_id: string; | |||||
| }; | |||||
| export type 店舗QR設定取得設定無効化Response = {} & APICommonResponse; | |||||
| export const 店舗QR設定取得設定無効化 = async ( | |||||
| param: 店舗QR設定取得設定無効化Request | |||||
| ) => { | |||||
| const res = await request<店舗QR設定取得設定無効化Response>({ | |||||
| url: getUrl(ApiId.店舗QR設定取得設定無効化), | |||||
| method: HttpMethod.POST, | |||||
| data: makeParam(param), | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| @@ -31,6 +31,12 @@ const urls = { | |||||
| [A.デポジット情報取得]: "shop/deposit", | [A.デポジット情報取得]: "shop/deposit", | ||||
| [A.デポジットチャージ]: "shop/deposit/charge", | [A.デポジットチャージ]: "shop/deposit/charge", | ||||
| [A.店舗設定]: "shop/config", | [A.店舗設定]: "shop/config", | ||||
| [A.店舗設定]: "shop/config", | |||||
| [A.店舗QR設定取得]: "shop/config/detail", | |||||
| [A.店舗QR設定認証設定追加]: "shop/config/certification/add", | |||||
| [A.店舗QR設定認証設定削除]: "shop/config/certification/remove", | |||||
| [A.店舗QR設定取得設定変更]: "shop/config/acquisition/enable", | |||||
| [A.店舗QR設定取得設定無効化]: "shop/config/acquisition/disable", | |||||
| // QRサービス券関連------------------------------- | // QRサービス券関連------------------------------- | ||||
| [A.QRサービス券駐車場グループ一覧取得]: "qr-service/parking-group/list", | [A.QRサービス券駐車場グループ一覧取得]: "qr-service/parking-group/list", | ||||
| @@ -1,7 +1,7 @@ | |||||
| import { useFormContext, Controller } from 'react-hook-form'; | |||||
| import { Autocomplete, TextField, TextFieldProps } from '@mui/material'; | |||||
| import React, { useEffect, useMemo } from 'react'; | |||||
| import TextFieldEx from '../form/TextFieldEx'; | |||||
| import { useFormContext, Controller } from "react-hook-form"; | |||||
| import { Autocomplete, TextField, TextFieldProps } from "@mui/material"; | |||||
| import React, { useEffect, useMemo } from "react"; | |||||
| import TextFieldEx from "../form/TextFieldEx"; | |||||
| // ---------------------------------------------------------------------- | // ---------------------------------------------------------------------- | ||||
| @@ -14,15 +14,15 @@ export type AutoCompleteOptionType = AutoCompleteOption | string | null; | |||||
| export const getValue = (option: AutoCompleteOptionType): string => { | export const getValue = (option: AutoCompleteOptionType): string => { | ||||
| if (option === null) { | if (option === null) { | ||||
| return ''; | |||||
| return ""; | |||||
| } | } | ||||
| if (typeof option === 'object') { | |||||
| if (typeof option === "object") { | |||||
| return option.value; | return option.value; | ||||
| } | } | ||||
| if (typeof option === 'string') { | |||||
| if (typeof option === "string") { | |||||
| return option; | return option; | ||||
| } | } | ||||
| return ''; | |||||
| return ""; | |||||
| }; | }; | ||||
| type IProps = { | type IProps = { | ||||
| @@ -45,24 +45,30 @@ export const getAutoCompleteOption = ( | |||||
| return options.find((option) => option.value === value) ?? null; | return options.find((option) => option.value === value) ?? null; | ||||
| }; | }; | ||||
| export default function RHFAutoComplete({ name, options, onFix, readOnly, ...other }: Props) { | |||||
| export default function RHFAutoComplete({ | |||||
| name, | |||||
| options, | |||||
| onFix, | |||||
| readOnly, | |||||
| ...other | |||||
| }: Props) { | |||||
| const { control, watch, setValue } = useFormContext(); | const { control, watch, setValue } = useFormContext(); | ||||
| const value: AutoCompleteOption | string | null = watch(name); | const value: AutoCompleteOption | string | null = watch(name); | ||||
| const valueStr = useMemo(() => { | const valueStr = useMemo(() => { | ||||
| if (value === null) return ''; | |||||
| if (value === undefined) return ''; | |||||
| if (typeof value === 'string') { | |||||
| if (value === null) return ""; | |||||
| if (value === undefined) return ""; | |||||
| if (typeof value === "string") { | |||||
| return value; | return value; | ||||
| } else { | } else { | ||||
| return value.label ?? ''; | |||||
| return value.label ?? ""; | |||||
| } | } | ||||
| }, [value]); | }, [value]); | ||||
| // string型からAutoCompleteOptionへ変換してフォームへセットする | // string型からAutoCompleteOptionへ変換してフォームへセットする | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (typeof value === 'string' && options) { | |||||
| if (value === '') { | |||||
| if (typeof value === "string" && options) { | |||||
| if (value === "") { | |||||
| setValue(name, null); | setValue(name, null); | ||||
| } else { | } else { | ||||
| const val = getAutoCompleteOption(options, value); | const val = getAutoCompleteOption(options, value); | ||||
| @@ -74,9 +80,13 @@ export default function RHFAutoComplete({ name, options, onFix, readOnly, ...oth | |||||
| }, [value, options]); | }, [value, options]); | ||||
| if (readOnly) { | if (readOnly) { | ||||
| return <TextFieldEx readOnly {...other} value={valueStr} variant="standard" />; | |||||
| return ( | |||||
| <TextFieldEx readOnly {...other} value={valueStr} variant="standard" /> | |||||
| ); | |||||
| } | } | ||||
| if (typeof value === 'string') return null; | |||||
| // if (typeof value === 'string') return null; | |||||
| if (typeof value === "string") | |||||
| return <TextFieldEx fullWidth {...other} value={""} />; | |||||
| return ( | return ( | ||||
| <Controller | <Controller | ||||
| name={name} | name={name} | ||||
| @@ -88,7 +98,7 @@ export default function RHFAutoComplete({ name, options, onFix, readOnly, ...oth | |||||
| autoComplete | autoComplete | ||||
| includeInputInList | includeInputInList | ||||
| noOptionsText="候補がありません" | noOptionsText="候補がありません" | ||||
| getOptionLabel={(option) => option?.label ?? ''} | |||||
| getOptionLabel={(option) => option?.label ?? ""} | |||||
| isOptionEqualToValue={(option, value) => { | isOptionEqualToValue={(option, value) => { | ||||
| // if (typeof value !== 'object') return false; | // if (typeof value !== 'object') return false; | ||||
| return option.value === value.value; | return option.value === value.value; | ||||
| @@ -14,6 +14,7 @@ import useNavigateCustom from "hooks/useNavigateCustom"; | |||||
| import { PageID } from "pages"; | import { PageID } from "pages"; | ||||
| import { createContext, memo, useEffect, useMemo, useState } from "react"; | import { createContext, memo, useEffect, useMemo, useState } from "react"; | ||||
| import { getPath } from "routes/path"; | import { getPath } from "routes/path"; | ||||
| import 駐車場マスタストア from "storage/cache/駐車場マスタ"; | |||||
| type SwitchedUser = { | type SwitchedUser = { | ||||
| user_id: string; | user_id: string; | ||||
| @@ -173,6 +174,11 @@ function AuthContextProvider({ children }: Props) { | |||||
| setShopId(null); | setShopId(null); | ||||
| }; | }; | ||||
| const cacheClear = () => { | |||||
| 駐車場マスタストア.clear(); | |||||
| 駐車場マスタストア.clear(); | |||||
| }; | |||||
| const login = async (email: string, password: string) => { | const login = async (email: string, password: string) => { | ||||
| const res: APICommonResponse | null = await callLogin({ email, password }); | const res: APICommonResponse | null = await callLogin({ email, password }); | ||||
| return res?.result === ResultCode.SUCCESS; | return res?.result === ResultCode.SUCCESS; | ||||
| @@ -191,10 +197,12 @@ function AuthContextProvider({ children }: Props) { | |||||
| const switchShopRole = async (user_id: string) => { | const switchShopRole = async (user_id: string) => { | ||||
| await call店舗成り代わり開始({ user_id }); | await call店舗成り代わり開始({ user_id }); | ||||
| navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW)); | navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW)); | ||||
| cacheClear(); | |||||
| }; | }; | ||||
| const switchEnd = async () => { | const switchEnd = async () => { | ||||
| await call成り代わり終了({}); | await call成り代わり終了({}); | ||||
| navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW)); | navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW)); | ||||
| cacheClear(); | |||||
| }; | }; | ||||
| const isSwitched = useMemo(() => { | const isSwitched = useMemo(() => { | ||||
| @@ -1,5 +1,5 @@ | |||||
| import { HasChildren } from "@types"; | import { HasChildren } from "@types"; | ||||
| import { 駐車場マスタ, 駐車場マスタ一覧取得 } from "api/parking"; | |||||
| import { 駐車場マスタ } from "api/parking"; | |||||
| import { | import { | ||||
| QRサービス券駐車場グループ, | QRサービス券駐車場グループ, | ||||
| QRサービス券駐車場グループ一覧取得, | QRサービス券駐車場グループ一覧取得, | ||||
| @@ -13,6 +13,7 @@ import { PageID, TabID } from "pages"; | |||||
| import { createContext, useEffect, useMemo, useState } from "react"; | import { createContext, useEffect, useMemo, useState } from "react"; | ||||
| import { useParams } from "react-router-dom"; | import { useParams } from "react-router-dom"; | ||||
| import { getPath } from "routes/path"; | import { getPath } from "routes/path"; | ||||
| import 駐車場マスタストア from "storage/cache/駐車場マスタ"; | |||||
| type Context = { | type Context = { | ||||
| parkings: 駐車場マスタ[]; | parkings: 駐車場マスタ[]; | ||||
| @@ -55,16 +56,6 @@ function QRサービス券駐車場グループ管理ContextProvider({ children | |||||
| error("データ取得失敗"); | error("データ取得失敗"); | ||||
| }, | }, | ||||
| }); | }); | ||||
| const { callAPI: call駐車場マスタ一覧取得 } = useAPICall({ | |||||
| apiMethod: 駐車場マスタ一覧取得, | |||||
| backDrop: true, | |||||
| onSuccess: ({ data }) => { | |||||
| setParkings(data.list); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("データ取得失敗"); | |||||
| }, | |||||
| }); | |||||
| const fetch = async () => { | const fetch = async () => { | ||||
| await callQRサービス券駐車場グループ一覧取得({}); | await callQRサービス券駐車場グループ一覧取得({}); | ||||
| @@ -107,7 +98,9 @@ function QRサービス券駐車場グループ管理ContextProvider({ children | |||||
| useEffect(() => { | useEffect(() => { | ||||
| fetch(); | fetch(); | ||||
| call駐車場マスタ一覧取得({}); | |||||
| 駐車場マスタストア.get().then((parkings) => { | |||||
| setParkings(parkings); | |||||
| }); | |||||
| }, []); | }, []); | ||||
| return ( | return ( | ||||
| @@ -1,5 +1,11 @@ | |||||
| import { HasChildren } from "@types"; | import { HasChildren } from "@types"; | ||||
| import { 店舗, 店舗一覧取得 } from "api/shop"; | |||||
| import { | |||||
| QRサービス券取得設定, | |||||
| QRサービス券認証設定, | |||||
| 店舗, | |||||
| 店舗QR設定取得, | |||||
| 店舗一覧取得, | |||||
| } from "api/shop"; | |||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useDashboard from "hooks/useDashBoard"; | import useDashboard from "hooks/useDashBoard"; | ||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | import useNavigateCustom from "hooks/useNavigateCustom"; | ||||
| @@ -12,12 +18,16 @@ import { getPath } from "routes/path"; | |||||
| type Context = { | type Context = { | ||||
| shop: 店舗 | null; | shop: 店舗 | null; | ||||
| certificationSetting: QRサービス券認証設定[]; | |||||
| acquisitionSetting: QRサービス券取得設定 | null; | |||||
| fetch: () => Promise<void>; | fetch: () => Promise<void>; | ||||
| moveToMain: VoidFunction; | moveToMain: VoidFunction; | ||||
| }; | }; | ||||
| export const 店舗詳細Context = createContext<Context>({ | export const 店舗詳細Context = createContext<Context>({ | ||||
| shop: null, | shop: null, | ||||
| certificationSetting: [], | |||||
| acquisitionSetting: null, | |||||
| fetch: async () => {}, | fetch: async () => {}, | ||||
| moveToMain: () => {}, | moveToMain: () => {}, | ||||
| }); | }); | ||||
| @@ -27,6 +37,11 @@ function 店舗詳細ContextProvider({ children }: Props) { | |||||
| const { shopId: paramShopId } = useParams(); | const { shopId: paramShopId } = useParams(); | ||||
| const [shop, setShop] = useState<店舗 | null>(null); | const [shop, setShop] = useState<店舗 | null>(null); | ||||
| const [certificationSetting, setCertificationSetting] = useState< | |||||
| QRサービス券認証設定[] | |||||
| >([]); | |||||
| const [acquisitionSetting, setAcquisitionSetting] = | |||||
| useState<QRサービス券取得設定 | null>(null); | |||||
| const { success, error } = useSnackbarCustom(); | const { success, error } = useSnackbarCustom(); | ||||
| const { navigateWhenChanged } = useNavigateCustom(); | const { navigateWhenChanged } = useNavigateCustom(); | ||||
| @@ -47,8 +62,25 @@ function 店舗詳細ContextProvider({ children }: Props) { | |||||
| }, | }, | ||||
| }); | }); | ||||
| const { callAPI: call店舗QR設定取得 } = useAPICall({ | |||||
| apiMethod: 店舗QR設定取得, | |||||
| backDrop: true, | |||||
| onSuccess: ({ data }) => { | |||||
| setAcquisitionSetting(data.acquisition); | |||||
| setCertificationSetting(data.certification); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("データ取得失敗"); | |||||
| navigateWhenChanged(getPath(PageID.店舗一覧)); | |||||
| }, | |||||
| }); | |||||
| const fetch = async () => { | const fetch = async () => { | ||||
| await call店舗一覧取得({ | |||||
| if (!paramShopId) return; | |||||
| call店舗一覧取得({ | |||||
| shop_id: paramShopId, | |||||
| }); | |||||
| call店舗QR設定取得({ | |||||
| shop_id: paramShopId, | shop_id: paramShopId, | ||||
| }); | }); | ||||
| }; | }; | ||||
| @@ -77,6 +109,8 @@ function 店舗詳細ContextProvider({ children }: Props) { | |||||
| <店舗詳細Context.Provider | <店舗詳細Context.Provider | ||||
| value={{ | value={{ | ||||
| shop, | shop, | ||||
| certificationSetting, | |||||
| acquisitionSetting, | |||||
| fetch, | fetch, | ||||
| moveToMain, | moveToMain, | ||||
| }} | }} | ||||
| @@ -20,9 +20,27 @@ export default function useA店舗管理Tabs() { | |||||
| }), | }), | ||||
| }, | }, | ||||
| { | { | ||||
| label: "設定", | |||||
| tabId: TabID.店舗詳細_設定, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_設定], { | |||||
| label: "基本設定", | |||||
| tabId: TabID.店舗詳細_基本設定, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_基本設定], { | |||||
| query: { | |||||
| shopId: shop?.shop_id ?? "aaaaa", | |||||
| }, | |||||
| }), | |||||
| }, | |||||
| { | |||||
| label: "認証設定", | |||||
| tabId: TabID.店舗詳細_QR認証設定, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_QR認証設定], { | |||||
| query: { | |||||
| shopId: shop?.shop_id ?? "aaaaa", | |||||
| }, | |||||
| }), | |||||
| }, | |||||
| { | |||||
| label: "取得設定", | |||||
| tabId: TabID.店舗詳細_QR取得設定, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_QR取得設定], { | |||||
| query: { | query: { | ||||
| shopId: shop?.shop_id ?? "aaaaa", | shopId: shop?.shop_id ?? "aaaaa", | ||||
| }, | }, | ||||
| @@ -0,0 +1,28 @@ | |||||
| import { Box, Stack } from "@mui/material"; | |||||
| import useDashboard from "hooks/useDashBoard"; | |||||
| import { PageID, TabID } from "pages"; | |||||
| import 取得設定 from "./取得設定"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import { useContext } from "react"; | |||||
| export default function Main() { | |||||
| const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_QR取得設定); | |||||
| return <Page />; | |||||
| } | |||||
| function Page() { | |||||
| const { shop, acquisitionSetting, certificationSetting } = | |||||
| useContext(店舗詳細Context); | |||||
| if (!shop || !acquisitionSetting || !certificationSetting) { | |||||
| return null; | |||||
| } | |||||
| return ( | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <取得設定 /> | |||||
| </Stack> | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| @@ -0,0 +1,186 @@ | |||||
| import { yupResolver } from "@hookform/resolvers/yup"; | |||||
| import { Box, Button, Card, Grid, Stack, Typography } from "@mui/material"; | |||||
| import { | |||||
| QRサービス券駐車場グループ, | |||||
| QRサービス券駐車場グループ一覧取得, | |||||
| } from "api/qr-service"; | |||||
| import { | |||||
| 店舗QR設定取得設定変更, | |||||
| 店舗QR設定取得設定無効化, | |||||
| 店舗設定, | |||||
| } from "api/shop"; | |||||
| import { FormProvider, RHFTextField } from "components/hook-form"; | |||||
| import RHFAutoComplete, { | |||||
| AutoCompleteOptionType, | |||||
| getValue, | |||||
| } from "components/hook-form/RHFAutoComplete"; | |||||
| import StackRow from "components/stack/StackRow"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import { useDialog } from "hooks/useDialog"; | |||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useContext, useEffect, useMemo, useState } from "react"; | |||||
| import { useForm } from "react-hook-form"; | |||||
| import { number, object } from "yup"; | |||||
| type FormProps = { | |||||
| qr_service_parking_group_id: AutoCompleteOptionType; | |||||
| shop_no: string; | |||||
| discount_ticket_code: string; | |||||
| }; | |||||
| export default function 取得設定() { | |||||
| const { shop, fetch, moveToMain, acquisitionSetting } = | |||||
| useContext(店舗詳細Context); | |||||
| const { success, error } = useSnackbarCustom(); | |||||
| const { navigateWhenChanged } = useNavigateCustom(); | |||||
| const [groups, setGroups] = useState<QRサービス券駐車場グループ[] | null>( | |||||
| null | |||||
| ); | |||||
| const form = useForm<FormProps>({ | |||||
| defaultValues: { | |||||
| qr_service_parking_group_id: acquisitionSetting | |||||
| ? String(acquisitionSetting.qr_service_parking_group_id) | |||||
| : null, | |||||
| shop_no: acquisitionSetting ? String(acquisitionSetting.shop_no) : "", | |||||
| discount_ticket_code: acquisitionSetting | |||||
| ? String(acquisitionSetting.discount_ticket_code) | |||||
| : "", | |||||
| }, | |||||
| resolver: yupResolver( | |||||
| object().shape({ | |||||
| qr_service_parking_group_id: object().required("必須項目です"), | |||||
| shop_no: number().typeError("数値を入力してください"), | |||||
| discount_ticket_code: number().typeError("数値を入力してください"), | |||||
| }) | |||||
| ), | |||||
| }); | |||||
| const { callAPI: callQRサービス券駐車場グループ一覧取得 } = useAPICall({ | |||||
| apiMethod: QRサービス券駐車場グループ一覧取得, | |||||
| backDrop: true, | |||||
| onSuccess: ({ data }) => { | |||||
| setGroups(data.list); | |||||
| }, | |||||
| }); | |||||
| const options = useMemo(() => { | |||||
| return ( | |||||
| groups?.map((g) => ({ | |||||
| label: g.name, | |||||
| value: g.id, | |||||
| })) ?? [] | |||||
| ); | |||||
| }, [groups]); | |||||
| const { callAPI: call店舗QR設定取得設定変更 } = useAPICall({ | |||||
| apiMethod: 店舗QR設定取得設定変更, | |||||
| backDrop: true, | |||||
| form, | |||||
| onSuccess: () => { | |||||
| success("設定しました"); | |||||
| fetch(); | |||||
| moveToMain(); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const { callAPI: call店舗QR設定取得設定無効化 } = useAPICall({ | |||||
| apiMethod: 店舗QR設定取得設定無効化, | |||||
| backDrop: true, | |||||
| form, | |||||
| onSuccess: () => { | |||||
| success("削除しました"); | |||||
| fetch(); | |||||
| moveToMain(); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const { element, isAgree, open } = useDialog({ | |||||
| message: "削除しますか", | |||||
| }); | |||||
| const handleSubmit = (data: FormProps) => { | |||||
| if (shop === null) return; | |||||
| const qrServiceParkingGroupId = getValue(data.qr_service_parking_group_id); | |||||
| call店舗QR設定取得設定変更({ | |||||
| ...data, | |||||
| shop_id: shop.shop_id, | |||||
| qr_service_parking_group_id: qrServiceParkingGroupId, | |||||
| }); | |||||
| }; | |||||
| const handleDelete = () => { | |||||
| open(); | |||||
| }; | |||||
| useEffect(() => { | |||||
| callQRサービス券駐車場グループ一覧取得({}); | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| if (isAgree && shop) { | |||||
| call店舗QR設定取得設定無効化({ | |||||
| shop_id: shop?.shop_id, | |||||
| }); | |||||
| } | |||||
| }, [isAgree, shop]); | |||||
| return ( | |||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | |||||
| <Card sx={{ p: 2 }} elevation={1}> | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <Typography variant="h6">QRサービス券取得設定</Typography> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>QRサービス券駐車場グループ</Typography> | |||||
| <StackRow> | |||||
| <RHFAutoComplete | |||||
| name="qr_service_parking_group_id" | |||||
| size="small" | |||||
| options={options} | |||||
| /> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>店舗番号</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="shop_no" /> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>サービス券コード</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="discount_ticket_code" /> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <StackRow> | |||||
| <Button type="submit" variant="contained"> | |||||
| 設定 | |||||
| </Button> | |||||
| {!!acquisitionSetting && ( | |||||
| <Button type="button" color="error" onClick={handleDelete}> | |||||
| 削除 | |||||
| </Button> | |||||
| )} | |||||
| </StackRow> | |||||
| </Stack> | |||||
| </Box> | |||||
| </Card> | |||||
| {element} | |||||
| </FormProvider> | |||||
| ); | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| import { Box, Stack } from "@mui/material"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import useDashboard from "hooks/useDashBoard"; | |||||
| import { PageID, TabID } from "pages"; | |||||
| import { useContext } from "react"; | |||||
| import 駐車場一覧 from "./駐車場一覧"; | |||||
| import 駐車場追加 from "./駐車場追加"; | |||||
| export default function Page() { | |||||
| const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_QR認証設定); | |||||
| const {} = useContext(店舗詳細Context); | |||||
| return ( | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <駐車場一覧 /> | |||||
| <駐車場追加 /> | |||||
| </Stack> | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| @@ -0,0 +1,99 @@ | |||||
| import { Box, Button, Card, Grid, Stack, Typography } from "@mui/material"; | |||||
| import { 駐車場マスタ } from "api/parking"; | |||||
| import { QRサービス券駐車場グループ駐車場削除登録 } from "api/qr-service"; | |||||
| import { QRサービス券駐車場グループ管理Context } from "contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import { useDialog } from "hooks/useDialog"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useContext, useEffect, useState } from "react"; | |||||
| export default function 駐車場一覧() { | |||||
| const { fetch, selectedGroup } = useContext( | |||||
| QRサービス券駐車場グループ管理Context | |||||
| ); | |||||
| const { success, error } = useSnackbarCustom(); | |||||
| const { callAPI: callQRサービス券駐車場グループ駐車場削除登録 } = useAPICall({ | |||||
| apiMethod: QRサービス券駐車場グループ駐車場削除登録, | |||||
| backDrop: true, | |||||
| onSuccess: () => { | |||||
| success("削除しました"); | |||||
| fetch(); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const [削除予定駐車場管理コード, set削除予定駐車場管理コード] = useState< | |||||
| string | null | |||||
| >(null); | |||||
| const { element, open, isAgree } = useDialog({ | |||||
| message: "削除しますか?", | |||||
| }); | |||||
| const deleteDataConfirm = (parkingManagementCode: string) => { | |||||
| set削除予定駐車場管理コード(parkingManagementCode); | |||||
| open(); | |||||
| }; | |||||
| useEffect(() => { | |||||
| if (isAgree && selectedGroup && 削除予定駐車場管理コード) { | |||||
| callQRサービス券駐車場グループ駐車場削除登録({ | |||||
| id: selectedGroup.id, | |||||
| parking_management_code: 削除予定駐車場管理コード, | |||||
| }); | |||||
| } | |||||
| }, [isAgree]); | |||||
| if (selectedGroup === null) { | |||||
| return null; | |||||
| } | |||||
| return ( | |||||
| <Card sx={{ p: 2 }} elevation={1}> | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <Typography variant="h6">グループに含まれる駐車場</Typography> | |||||
| <Stack spacing={1}> | |||||
| {selectedGroup.parkings.map((p) => ( | |||||
| <Row | |||||
| parking={p} | |||||
| key={p.parking_management_code} | |||||
| deleteData={deleteDataConfirm} | |||||
| /> | |||||
| ))} | |||||
| {selectedGroup.parkings.length === 0 && ( | |||||
| <Typography>登録なし</Typography> | |||||
| )} | |||||
| </Stack> | |||||
| </Stack> | |||||
| </Box> | |||||
| {element} | |||||
| </Card> | |||||
| ); | |||||
| } | |||||
| type RowProps = { | |||||
| parking: 駐車場マスタ; | |||||
| deleteData: (parkingManagementCode: string) => void; | |||||
| }; | |||||
| function Row({ parking, deleteData }: RowProps) { | |||||
| const handleClick = () => { | |||||
| deleteData(parking.parking_management_code); | |||||
| }; | |||||
| return ( | |||||
| <Grid container> | |||||
| <Grid item xs={10}> | |||||
| {parking.parking_name}({parking.parking_management_code}) | |||||
| </Grid> | |||||
| <Grid item xs={2}> | |||||
| <Button color="error" onClick={handleClick}> | |||||
| 削除 | |||||
| </Button> | |||||
| </Grid> | |||||
| </Grid> | |||||
| ); | |||||
| } | |||||
| @@ -0,0 +1,106 @@ | |||||
| import { yupResolver } from "@hookform/resolvers/yup"; | |||||
| import { Box, Button, Card, Grid, Stack, Typography } from "@mui/material"; | |||||
| import { QRサービス券駐車場グループ駐車場追加登録 } from "api/qr-service"; | |||||
| import { FormProvider, RHFAutoComplete } from "components/hook-form"; | |||||
| import { | |||||
| AutoCompleteOption, | |||||
| AutoCompleteOptionType, | |||||
| getValue, | |||||
| } from "components/hook-form/RHFAutoComplete"; | |||||
| import StackRow from "components/stack/StackRow"; | |||||
| import { QRサービス券駐車場グループ管理Context } from "contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useContext, useMemo } from "react"; | |||||
| import { useForm } from "react-hook-form"; | |||||
| import { object } from "yup"; | |||||
| type FormProps = { | |||||
| parking_management_code: AutoCompleteOptionType; | |||||
| }; | |||||
| export default function 駐車場追加() { | |||||
| const { fetch, selectedGroup, parkings } = useContext( | |||||
| QRサービス券駐車場グループ管理Context | |||||
| ); | |||||
| const { success, error } = useSnackbarCustom(); | |||||
| const form = useForm<FormProps>({ | |||||
| defaultValues: { | |||||
| parking_management_code: null, | |||||
| }, | |||||
| resolver: yupResolver( | |||||
| object().shape({ | |||||
| parking_management_code: object().required("必須項目です"), | |||||
| }) | |||||
| ), | |||||
| }); | |||||
| const { callAPI: callQRサービス券駐車場グループ駐車場追加登録 } = useAPICall({ | |||||
| apiMethod: QRサービス券駐車場グループ駐車場追加登録, | |||||
| backDrop: true, | |||||
| form, | |||||
| onSuccess: () => { | |||||
| success("追加しました"); | |||||
| fetch(); | |||||
| form.setValue("parking_management_code", null); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const options: AutoCompleteOption[] = useMemo(() => { | |||||
| return parkings | |||||
| .filter( | |||||
| (p) => | |||||
| !selectedGroup?.parkings.find( | |||||
| (ele) => ele.parking_management_code === p.parking_management_code | |||||
| ) | |||||
| ) | |||||
| .map((p) => ({ | |||||
| label: p.parking_name, | |||||
| value: p.parking_management_code, | |||||
| })); | |||||
| }, [parkings, selectedGroup]); | |||||
| const handleSubmit = (data: FormProps) => { | |||||
| if (selectedGroup === null) return; | |||||
| const parkingManagementCode = getValue(data.parking_management_code); | |||||
| callQRサービス券駐車場グループ駐車場追加登録({ | |||||
| id: selectedGroup.id, | |||||
| parking_management_code: parkingManagementCode, | |||||
| }); | |||||
| }; | |||||
| return ( | |||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | |||||
| <Card sx={{ p: 2 }} elevation={1}> | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <Typography variant="h6">駐車場追加</Typography> | |||||
| <StackRow> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>駐車場</Typography> | |||||
| <StackRow> | |||||
| <RHFAutoComplete | |||||
| name="parking_management_code" | |||||
| options={options} | |||||
| size="small" | |||||
| /> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </StackRow> | |||||
| <StackRow> | |||||
| <Button type="submit" variant="contained"> | |||||
| 追加 | |||||
| </Button> | |||||
| </StackRow> | |||||
| </Stack> | |||||
| </Box> | |||||
| </Card> | |||||
| </FormProvider> | |||||
| ); | |||||
| } | |||||
| @@ -4,7 +4,7 @@ import { PageID, TabID } from "pages"; | |||||
| import 設定 from "./設定"; | import 設定 from "./設定"; | ||||
| export default function 店舗詳細設定() { | export default function 店舗詳細設定() { | ||||
| const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_設定); | |||||
| const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_基本設定); | |||||
| return <Page />; | return <Page />; | ||||
| } | } | ||||
| @@ -1,120 +0,0 @@ | |||||
| import { yupResolver } from "@hookform/resolvers/yup"; | |||||
| import { Box, Button, Card, Grid, Stack, Typography } from "@mui/material"; | |||||
| import { 店舗設定 } from "api/shop"; | |||||
| import { FormProvider, RHFTextField } from "components/hook-form"; | |||||
| import StackRow from "components/stack/StackRow"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useContext } from "react"; | |||||
| import { useForm } from "react-hook-form"; | |||||
| import { number, object } from "yup"; | |||||
| type FormProps = { | |||||
| qr_service_expire_min: number; | |||||
| under_amount_when_create: number; | |||||
| under_amount_when_auth: number; | |||||
| under_amount_when_use: number; | |||||
| }; | |||||
| export default function 設定_() { | |||||
| const { shop, fetch, moveToMain } = useContext(店舗詳細Context); | |||||
| const { success, error } = useSnackbarCustom(); | |||||
| const { navigateWhenChanged } = useNavigateCustom(); | |||||
| const form = useForm<FormProps>({ | |||||
| defaultValues: { | |||||
| qr_service_expire_min: shop?.qr_service_expire_min ?? 0, | |||||
| under_amount_when_create: shop?.under_amount_when_create ?? 0, | |||||
| under_amount_when_auth: shop?.under_amount_when_auth ?? 0, | |||||
| under_amount_when_use: shop?.under_amount_when_use ?? 0, | |||||
| }, | |||||
| resolver: yupResolver( | |||||
| object().shape({ | |||||
| qr_service_expire_min: number().typeError("数値を入力してください"), | |||||
| under_amount_when_create: number().typeError("数値を入力してください"), | |||||
| under_amount_when_auth: number().typeError("数値を入力してください"), | |||||
| under_amount_when_use: number().typeError("数値を入力してください"), | |||||
| }) | |||||
| ), | |||||
| }); | |||||
| const { callAPI: call店舗設定 } = useAPICall({ | |||||
| apiMethod: 店舗設定, | |||||
| backDrop: true, | |||||
| form, | |||||
| onSuccess: () => { | |||||
| success("設定しました"); | |||||
| fetch(); | |||||
| moveToMain(); | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const handleSubmit = (data: FormProps) => { | |||||
| if (shop === null) return; | |||||
| call店舗設定({ | |||||
| shop_id: shop.shop_id, | |||||
| qr_service_expire_min: String(data.qr_service_expire_min), | |||||
| under_amount_when_auth: String(data.under_amount_when_auth), | |||||
| under_amount_when_create: String(data.under_amount_when_create), | |||||
| under_amount_when_use: String(data.under_amount_when_use), | |||||
| }); | |||||
| }; | |||||
| return ( | |||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | |||||
| <Card sx={{ p: 2 }} elevation={1}> | |||||
| <Box> | |||||
| <Stack spacing={2}> | |||||
| <Typography variant="h6">基本設定</Typography> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>QRサービス券有効期限</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="qr_service_expire_min" /> | |||||
| <Typography>分</Typography> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>発行時デポジット下限値</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="under_amount_when_create" /> | |||||
| <Typography>円</Typography> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>認証時デポジット下限値</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="under_amount_when_auth" /> | |||||
| <Typography>円</Typography> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid container columnGap={2}> | |||||
| <Grid item xs={12} md={6}> | |||||
| <Typography>利用時デポジット下限値</Typography> | |||||
| <StackRow> | |||||
| <RHFTextField type="number" name="under_amount_when_use" /> | |||||
| <Typography>円</Typography> | |||||
| </StackRow> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <StackRow> | |||||
| <Button type="submit" variant="contained"> | |||||
| 設定 | |||||
| </Button> | |||||
| </StackRow> | |||||
| </Stack> | |||||
| </Box> | |||||
| </Card> | |||||
| </FormProvider> | |||||
| ); | |||||
| } | |||||
| @@ -8,7 +8,7 @@ import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useContext } from "react"; | import { useContext } from "react"; | ||||
| import { useForm } from "react-hook-form"; | import { useForm } from "react-hook-form"; | ||||
| import { number, object } from "yup"; | import { number, object } from "yup"; | ||||
| import { 店舗詳細Context } from "../../../../contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| type FormProps = { | type FormProps = { | ||||
| amount: string; | amount: string; | ||||
| @@ -2,7 +2,7 @@ import { Box, Card, Stack, Typography } from "@mui/material"; | |||||
| import { SimpleDataList } from "components/table"; | import { SimpleDataList } from "components/table"; | ||||
| import { useContext, useMemo } from "react"; | import { useContext, useMemo } from "react"; | ||||
| import { numberFormat } from "utils/string"; | import { numberFormat } from "utils/string"; | ||||
| import { 店舗詳細Context } from "../../../../contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context"; | |||||
| export default function 詳細情報() { | export default function 詳細情報() { | ||||
| const { shop } = useContext(店舗詳細Context); | const { shop } = useContext(店舗詳細Context); | ||||
| @@ -45,7 +45,9 @@ export const TabID = { | |||||
| NONE: id++, | NONE: id++, | ||||
| 店舗詳細_メイン: id++, | 店舗詳細_メイン: id++, | ||||
| 店舗詳細_設定: id++, | |||||
| 店舗詳細_基本設定: id++, | |||||
| 店舗詳細_QR認証設定: id++, | |||||
| 店舗詳細_QR取得設定: id++, | |||||
| QRサービス券駐車場グループ管理_一覧: id++, | QRサービス券駐車場グループ管理_一覧: id++, | ||||
| QRサービス券駐車場グループ管理_新規登録: id++, | QRサービス券駐車場グループ管理_新規登録: id++, | ||||
| @@ -57,8 +57,12 @@ const PATHS_DASHBOARD = { | |||||
| [makePathKey(PageID.店舗新規登録)]: "/dashboard/shop/register", | [makePathKey(PageID.店舗新規登録)]: "/dashboard/shop/register", | ||||
| [makePathKey([PageID.店舗詳細, TabID.店舗詳細_メイン])]: | [makePathKey([PageID.店舗詳細, TabID.店舗詳細_メイン])]: | ||||
| "/dashboard/shop/detail/:shopId", | "/dashboard/shop/detail/:shopId", | ||||
| [makePathKey([PageID.店舗詳細, TabID.店舗詳細_設定])]: | |||||
| [makePathKey([PageID.店舗詳細, TabID.店舗詳細_基本設定])]: | |||||
| "/dashboard/shop/detail/setting/:shopId", | "/dashboard/shop/detail/setting/:shopId", | ||||
| [makePathKey([PageID.店舗詳細, TabID.店舗詳細_QR認証設定])]: | |||||
| "/dashboard/shop/detail/setting/qr/certification/:shopId", | |||||
| [makePathKey([PageID.店舗詳細, TabID.店舗詳細_QR取得設定])]: | |||||
| "/dashboard/shop/detail/setting/qr/acquisition/:shopId", | |||||
| [makePathKey(PageID.サービス券発行用QRコード)]: "/dashboard/qrcode/generate", | [makePathKey(PageID.サービス券発行用QRコード)]: "/dashboard/qrcode/generate", | ||||
| [makePathKey(PageID.サービス券利用履歴)]: "/dashboard/qrcode/history", | [makePathKey(PageID.サービス券利用履歴)]: "/dashboard/qrcode/history", | ||||
| @@ -57,10 +57,16 @@ export default function DashboardRoutes(): RouteObject[] { | |||||
| lazy(() => import("pages/dashboard/shop/店舗一覧")) | lazy(() => import("pages/dashboard/shop/店舗一覧")) | ||||
| ); | ); | ||||
| const 店舗詳細 = Loadable( | const 店舗詳細 = Loadable( | ||||
| lazy(() => import("pages/dashboard/shop/店舗詳細")) | |||||
| lazy(() => import("pages/dashboard/shop/店舗詳細/詳細")) | |||||
| ); | ); | ||||
| const 店舗詳細設定 = Loadable( | |||||
| lazy(() => import("pages/dashboard/shop/店舗詳細/設定")) | |||||
| const 店舗詳細基本設定 = Loadable( | |||||
| lazy(() => import("pages/dashboard/shop/店舗詳細/基本設定")) | |||||
| ); | |||||
| const 店舗詳細QR取得設定 = Loadable( | |||||
| lazy(() => import("pages/dashboard/shop/店舗詳細/QR取得設定")) | |||||
| ); | |||||
| const 店舗詳細QR認証設定 = Loadable( | |||||
| lazy(() => import("pages/dashboard/shop/店舗詳細/QR認証設定")) | |||||
| ); | ); | ||||
| const allChildren: { | const allChildren: { | ||||
| @@ -138,8 +144,16 @@ export default function DashboardRoutes(): RouteObject[] { | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_メイン]), | path: getPath([PageID.店舗詳細, TabID.店舗詳細_メイン]), | ||||
| }, | }, | ||||
| { | { | ||||
| element: <店舗詳細設定 />, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_設定]), | |||||
| element: <店舗詳細基本設定 />, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_基本設定]), | |||||
| }, | |||||
| { | |||||
| element: <店舗詳細QR認証設定 />, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_QR認証設定]), | |||||
| }, | |||||
| { | |||||
| element: <店舗詳細QR取得設定 />, | |||||
| path: getPath([PageID.店舗詳細, TabID.店舗詳細_QR取得設定]), | |||||
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| @@ -0,0 +1,19 @@ | |||||
| import { 駐車場マスタ, 駐車場マスタ一覧取得 } from "api/parking"; | |||||
| class 駐車場マスタストア { | |||||
| private list: 駐車場マスタ[] | undefined = undefined; | |||||
| async get() { | |||||
| if (this.list === undefined) { | |||||
| const res = await 駐車場マスタ一覧取得({}); | |||||
| this.list = res?.data.list ?? []; | |||||
| } | |||||
| return this.list; | |||||
| } | |||||
| async clear() { | |||||
| this.list = undefined; | |||||
| } | |||||
| } | |||||
| export default new 駐車場マスタストア(); | |||||