diff --git a/src/api/index.ts b/src/api/index.ts
index 0d923d0..8662f6e 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -36,6 +36,11 @@ export const ApiId = {
デポジット情報取得: id++,
デポジットチャージ: id++,
店舗設定: id++,
+ 店舗QR設定取得: id++,
+ 店舗QR設定認証設定追加: id++,
+ 店舗QR設定認証設定削除: id++,
+ 店舗QR設定取得設定変更: id++,
+ 店舗QR設定取得設定無効化: id++,
// QRサービス券関連-------------------------------
QRサービス券駐車場グループ一覧取得: id++,
diff --git a/src/api/shop.ts b/src/api/shop.ts
index 64d70ee..12d5370 100644
--- a/src/api/shop.ts
+++ b/src/api/shop.ts
@@ -10,6 +10,21 @@ export type 店舗 = {
under_amount_when_auth: 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 = {
shop_id?: string;
@@ -104,3 +119,58 @@ export const 店舗設定 = async (param: 店舗設定Request) => {
});
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;
+};
diff --git a/src/api/url.ts b/src/api/url.ts
index 41e6e53..49f7f78 100644
--- a/src/api/url.ts
+++ b/src/api/url.ts
@@ -31,6 +31,12 @@ const urls = {
[A.デポジット情報取得]: "shop/deposit",
[A.デポジットチャージ]: "shop/deposit/charge",
[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サービス券関連-------------------------------
[A.QRサービス券駐車場グループ一覧取得]: "qr-service/parking-group/list",
diff --git a/src/components/hook-form/RHFAutoComplete.tsx b/src/components/hook-form/RHFAutoComplete.tsx
index 5f0c65f..873000a 100644
--- a/src/components/hook-form/RHFAutoComplete.tsx
+++ b/src/components/hook-form/RHFAutoComplete.tsx
@@ -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 => {
if (option === null) {
- return '';
+ return "";
}
- if (typeof option === 'object') {
+ if (typeof option === "object") {
return option.value;
}
- if (typeof option === 'string') {
+ if (typeof option === "string") {
return option;
}
- return '';
+ return "";
};
type IProps = {
@@ -45,24 +45,30 @@ export const getAutoCompleteOption = (
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 value: AutoCompleteOption | string | null = watch(name);
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;
} else {
- return value.label ?? '';
+ return value.label ?? "";
}
}, [value]);
// string型からAutoCompleteOptionへ変換してフォームへセットする
useEffect(() => {
- if (typeof value === 'string' && options) {
- if (value === '') {
+ if (typeof value === "string" && options) {
+ if (value === "") {
setValue(name, null);
} else {
const val = getAutoCompleteOption(options, value);
@@ -74,9 +80,13 @@ export default function RHFAutoComplete({ name, options, onFix, readOnly, ...oth
}, [value, options]);
if (readOnly) {
- return ;
+ return (
+
+ );
}
- if (typeof value === 'string') return null;
+ // if (typeof value === 'string') return null;
+ if (typeof value === "string")
+ return ;
return (
option?.label ?? ''}
+ getOptionLabel={(option) => option?.label ?? ""}
isOptionEqualToValue={(option, value) => {
// if (typeof value !== 'object') return false;
return option.value === value.value;
diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx
index 18a5bad..33ce84f 100644
--- a/src/contexts/AuthContext.tsx
+++ b/src/contexts/AuthContext.tsx
@@ -14,6 +14,7 @@ import useNavigateCustom from "hooks/useNavigateCustom";
import { PageID } from "pages";
import { createContext, memo, useEffect, useMemo, useState } from "react";
import { getPath } from "routes/path";
+import 駐車場マスタストア from "storage/cache/駐車場マスタ";
type SwitchedUser = {
user_id: string;
@@ -173,6 +174,11 @@ function AuthContextProvider({ children }: Props) {
setShopId(null);
};
+ const cacheClear = () => {
+ 駐車場マスタストア.clear();
+ 駐車場マスタストア.clear();
+ };
+
const login = async (email: string, password: string) => {
const res: APICommonResponse | null = await callLogin({ email, password });
return res?.result === ResultCode.SUCCESS;
@@ -191,10 +197,12 @@ function AuthContextProvider({ children }: Props) {
const switchShopRole = async (user_id: string) => {
await call店舗成り代わり開始({ user_id });
navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW));
+ cacheClear();
};
const switchEnd = async () => {
await call成り代わり終了({});
navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW));
+ cacheClear();
};
const isSwitched = useMemo(() => {
diff --git a/src/contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context.tsx b/src/contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context.tsx
index 9fffda0..e7e22b3 100644
--- a/src/contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context.tsx
+++ b/src/contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context.tsx
@@ -1,5 +1,5 @@
import { HasChildren } from "@types";
-import { 駐車場マスタ, 駐車場マスタ一覧取得 } from "api/parking";
+import { 駐車場マスタ } from "api/parking";
import {
QRサービス券駐車場グループ,
QRサービス券駐車場グループ一覧取得,
@@ -13,6 +13,7 @@ import { PageID, TabID } from "pages";
import { createContext, useEffect, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { getPath } from "routes/path";
+import 駐車場マスタストア from "storage/cache/駐車場マスタ";
type Context = {
parkings: 駐車場マスタ[];
@@ -55,16 +56,6 @@ function QRサービス券駐車場グループ管理ContextProvider({ children
error("データ取得失敗");
},
});
- const { callAPI: call駐車場マスタ一覧取得 } = useAPICall({
- apiMethod: 駐車場マスタ一覧取得,
- backDrop: true,
- onSuccess: ({ data }) => {
- setParkings(data.list);
- },
- onFailed: () => {
- error("データ取得失敗");
- },
- });
const fetch = async () => {
await callQRサービス券駐車場グループ一覧取得({});
@@ -107,7 +98,9 @@ function QRサービス券駐車場グループ管理ContextProvider({ children
useEffect(() => {
fetch();
- call駐車場マスタ一覧取得({});
+ 駐車場マスタストア.get().then((parkings) => {
+ setParkings(parkings);
+ });
}, []);
return (
diff --git a/src/contexts/page/dashboard/shop/店舗詳細Context.tsx b/src/contexts/page/dashboard/shop/店舗詳細Context.tsx
index 56725f9..4c25879 100644
--- a/src/contexts/page/dashboard/shop/店舗詳細Context.tsx
+++ b/src/contexts/page/dashboard/shop/店舗詳細Context.tsx
@@ -1,5 +1,11 @@
import { HasChildren } from "@types";
-import { 店舗, 店舗一覧取得 } from "api/shop";
+import {
+ QRサービス券取得設定,
+ QRサービス券認証設定,
+ 店舗,
+ 店舗QR設定取得,
+ 店舗一覧取得,
+} from "api/shop";
import useAPICall from "hooks/useAPICall";
import useDashboard from "hooks/useDashBoard";
import useNavigateCustom from "hooks/useNavigateCustom";
@@ -12,12 +18,16 @@ import { getPath } from "routes/path";
type Context = {
shop: 店舗 | null;
+ certificationSetting: QRサービス券認証設定[];
+ acquisitionSetting: QRサービス券取得設定 | null;
fetch: () => Promise;
moveToMain: VoidFunction;
};
export const 店舗詳細Context = createContext({
shop: null,
+ certificationSetting: [],
+ acquisitionSetting: null,
fetch: async () => {},
moveToMain: () => {},
});
@@ -27,6 +37,11 @@ function 店舗詳細ContextProvider({ children }: Props) {
const { shopId: paramShopId } = useParams();
const [shop, setShop] = useState<店舗 | null>(null);
+ const [certificationSetting, setCertificationSetting] = useState<
+ QRサービス券認証設定[]
+ >([]);
+ const [acquisitionSetting, setAcquisitionSetting] =
+ useState(null);
const { success, error } = useSnackbarCustom();
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 () => {
- await call店舗一覧取得({
+ if (!paramShopId) return;
+ call店舗一覧取得({
+ shop_id: paramShopId,
+ });
+ call店舗QR設定取得({
shop_id: paramShopId,
});
};
@@ -77,6 +109,8 @@ function 店舗詳細ContextProvider({ children }: Props) {
<店舗詳細Context.Provider
value={{
shop,
+ certificationSetting,
+ acquisitionSetting,
fetch,
moveToMain,
}}
diff --git a/src/layouts/dashbord/tab/店舗管理Tabs.tsx b/src/layouts/dashbord/tab/店舗管理Tabs.tsx
index 8975cdd..c321a0f 100644
--- a/src/layouts/dashbord/tab/店舗管理Tabs.tsx
+++ b/src/layouts/dashbord/tab/店舗管理Tabs.tsx
@@ -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: {
shopId: shop?.shop_id ?? "aaaaa",
},
diff --git a/src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx b/src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx
new file mode 100644
index 0000000..9dfa08e
--- /dev/null
+++ b/src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx
@@ -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 ;
+}
+
+function Page() {
+ const { shop, acquisitionSetting, certificationSetting } =
+ useContext(店舗詳細Context);
+
+ if (!shop || !acquisitionSetting || !certificationSetting) {
+ return null;
+ }
+
+ return (
+
+
+ <取得設定 />
+
+
+ );
+}
diff --git a/src/pages/dashboard/shop/店舗詳細/QR取得設定/取得設定.tsx b/src/pages/dashboard/shop/店舗詳細/QR取得設定/取得設定.tsx
new file mode 100644
index 0000000..d0636df
--- /dev/null
+++ b/src/pages/dashboard/shop/店舗詳細/QR取得設定/取得設定.tsx
@@ -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(
+ null
+ );
+
+ const form = useForm({
+ 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 (
+
+
+
+
+ QRサービス券取得設定
+
+
+ QRサービス券駐車場グループ
+
+
+
+
+
+
+
+ 店舗番号
+
+
+
+
+
+
+
+ サービス券コード
+
+
+
+
+
+
+
+ {!!acquisitionSetting && (
+
+ )}
+
+
+
+
+ {element}
+
+ );
+}
diff --git a/src/pages/dashboard/shop/店舗詳細/QR認証設定/index.tsx b/src/pages/dashboard/shop/店舗詳細/QR認証設定/index.tsx
new file mode 100644
index 0000000..bedc024
--- /dev/null
+++ b/src/pages/dashboard/shop/店舗詳細/QR認証設定/index.tsx
@@ -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 (
+
+
+ <駐車場一覧 />
+ <駐車場追加 />
+
+
+ );
+}
diff --git a/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧.tsx b/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧.tsx
new file mode 100644
index 0000000..985cb0c
--- /dev/null
+++ b/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧.tsx
@@ -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 (
+
+
+
+ グループに含まれる駐車場
+
+ {selectedGroup.parkings.map((p) => (
+
+ ))}
+ {selectedGroup.parkings.length === 0 && (
+ 登録なし
+ )}
+
+
+
+ {element}
+
+ );
+}
+
+type RowProps = {
+ parking: 駐車場マスタ;
+ deleteData: (parkingManagementCode: string) => void;
+};
+function Row({ parking, deleteData }: RowProps) {
+ const handleClick = () => {
+ deleteData(parking.parking_management_code);
+ };
+
+ return (
+
+
+ {parking.parking_name}({parking.parking_management_code})
+
+
+
+
+
+ );
+}
diff --git a/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx b/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx
new file mode 100644
index 0000000..f7b18f8
--- /dev/null
+++ b/src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx
@@ -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({
+ 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 (
+
+
+
+
+ 駐車場追加
+
+
+
+ 駐車場
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/dashboard/shop/店舗詳細/設定/index.tsx b/src/pages/dashboard/shop/店舗詳細/基本設定/index.tsx
similarity index 96%
rename from src/pages/dashboard/shop/店舗詳細/設定/index.tsx
rename to src/pages/dashboard/shop/店舗詳細/基本設定/index.tsx
index 1130a34..c1bb604 100644
--- a/src/pages/dashboard/shop/店舗詳細/設定/index.tsx
+++ b/src/pages/dashboard/shop/店舗詳細/基本設定/index.tsx
@@ -4,7 +4,7 @@ import { PageID, TabID } from "pages";
import 設定 from "./設定";
export default function 店舗詳細設定() {
- const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_設定);
+ const {} = useDashboard(PageID.店舗詳細, TabID.店舗詳細_基本設定);
return ;
}
diff --git a/src/pages/dashboard/shop/店舗詳細/設定/設定.tsx b/src/pages/dashboard/shop/店舗詳細/基本設定/設定.tsx
similarity index 100%
rename from src/pages/dashboard/shop/店舗詳細/設定/設定.tsx
rename to src/pages/dashboard/shop/店舗詳細/基本設定/設定.tsx
diff --git a/src/pages/dashboard/shop/店舗詳細/設定/発行設定.tsx b/src/pages/dashboard/shop/店舗詳細/設定/発行設定.tsx
deleted file mode 100644
index 18504ca..0000000
--- a/src/pages/dashboard/shop/店舗詳細/設定/発行設定.tsx
+++ /dev/null
@@ -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({
- 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 (
-
-
-
-
- 基本設定
-
-
- QRサービス券有効期限
-
-
- 分
-
-
-
-
-
- 発行時デポジット下限値
-
-
- 円
-
-
-
-
-
- 認証時デポジット下限値
-
-
- 円
-
-
-
-
-
- 利用時デポジット下限値
-
-
- 円
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/pages/dashboard/shop/店舗詳細/index.tsx b/src/pages/dashboard/shop/店舗詳細/詳細/index.tsx
similarity index 100%
rename from src/pages/dashboard/shop/店舗詳細/index.tsx
rename to src/pages/dashboard/shop/店舗詳細/詳細/index.tsx
diff --git a/src/pages/dashboard/shop/店舗詳細/デポジットチャージ.tsx b/src/pages/dashboard/shop/店舗詳細/詳細/デポジットチャージ.tsx
similarity index 96%
rename from src/pages/dashboard/shop/店舗詳細/デポジットチャージ.tsx
rename to src/pages/dashboard/shop/店舗詳細/詳細/デポジットチャージ.tsx
index 177dfd3..3d5b2ca 100644
--- a/src/pages/dashboard/shop/店舗詳細/デポジットチャージ.tsx
+++ b/src/pages/dashboard/shop/店舗詳細/詳細/デポジットチャージ.tsx
@@ -8,7 +8,7 @@ import useSnackbarCustom from "hooks/useSnackbarCustom";
import { useContext } from "react";
import { useForm } from "react-hook-form";
import { number, object } from "yup";
-import { 店舗詳細Context } from "../../../../contexts/page/dashboard/shop/店舗詳細Context";
+import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context";
type FormProps = {
amount: string;
diff --git a/src/pages/dashboard/shop/店舗詳細/詳細情報.tsx b/src/pages/dashboard/shop/店舗詳細/詳細/詳細情報.tsx
similarity index 88%
rename from src/pages/dashboard/shop/店舗詳細/詳細情報.tsx
rename to src/pages/dashboard/shop/店舗詳細/詳細/詳細情報.tsx
index 31d4c7c..2bad7ac 100644
--- a/src/pages/dashboard/shop/店舗詳細/詳細情報.tsx
+++ b/src/pages/dashboard/shop/店舗詳細/詳細/詳細情報.tsx
@@ -2,7 +2,7 @@ import { Box, Card, Stack, Typography } from "@mui/material";
import { SimpleDataList } from "components/table";
import { useContext, useMemo } from "react";
import { numberFormat } from "utils/string";
-import { 店舗詳細Context } from "../../../../contexts/page/dashboard/shop/店舗詳細Context";
+import { 店舗詳細Context } from "contexts/page/dashboard/shop/店舗詳細Context";
export default function 詳細情報() {
const { shop } = useContext(店舗詳細Context);
diff --git a/src/pages/index.ts b/src/pages/index.ts
index a103a0e..8e272b9 100644
--- a/src/pages/index.ts
+++ b/src/pages/index.ts
@@ -45,7 +45,9 @@ export const TabID = {
NONE: id++,
店舗詳細_メイン: id++,
- 店舗詳細_設定: id++,
+ 店舗詳細_基本設定: id++,
+ 店舗詳細_QR認証設定: id++,
+ 店舗詳細_QR取得設定: id++,
QRサービス券駐車場グループ管理_一覧: id++,
QRサービス券駐車場グループ管理_新規登録: id++,
diff --git a/src/routes/path.ts b/src/routes/path.ts
index 117fdc1..91bf81b 100644
--- a/src/routes/path.ts
+++ b/src/routes/path.ts
@@ -57,8 +57,12 @@ const PATHS_DASHBOARD = {
[makePathKey(PageID.店舗新規登録)]: "/dashboard/shop/register",
[makePathKey([PageID.店舗詳細, TabID.店舗詳細_メイン])]:
"/dashboard/shop/detail/:shopId",
- [makePathKey([PageID.店舗詳細, TabID.店舗詳細_設定])]:
+ [makePathKey([PageID.店舗詳細, TabID.店舗詳細_基本設定])]:
"/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.サービス券利用履歴)]: "/dashboard/qrcode/history",
diff --git a/src/routes/sub/dashboard.tsx b/src/routes/sub/dashboard.tsx
index e092a8e..b7d1d39 100644
--- a/src/routes/sub/dashboard.tsx
+++ b/src/routes/sub/dashboard.tsx
@@ -57,10 +57,16 @@ export default function DashboardRoutes(): RouteObject[] {
lazy(() => import("pages/dashboard/shop/店舗一覧"))
);
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: {
@@ -138,8 +144,16 @@ export default function DashboardRoutes(): RouteObject[] {
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取得設定]),
},
],
},
diff --git a/src/storage/cache/駐車場マスタ.ts b/src/storage/cache/駐車場マスタ.ts
new file mode 100644
index 0000000..ea11de7
--- /dev/null
+++ b/src/storage/cache/駐車場マスタ.ts
@@ -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 駐車場マスタストア();