瀏覽代碼

QR取得設定整備

develop
sosuke.iwabuchi 1 年之前
父節點
當前提交
0e7c0121db
共有 23 個檔案被更改,包括 669 行新增165 行删除
  1. +5
    -0
      src/api/index.ts
  2. +70
    -0
      src/api/shop.ts
  3. +6
    -0
      src/api/url.ts
  4. +28
    -18
      src/components/hook-form/RHFAutoComplete.tsx
  5. +8
    -0
      src/contexts/AuthContext.tsx
  6. +5
    -12
      src/contexts/page/dashboard/parking/QRサービス券駐車場グループ管理Context.tsx
  7. +36
    -2
      src/contexts/page/dashboard/shop/店舗詳細Context.tsx
  8. +21
    -3
      src/layouts/dashbord/tab/店舗管理Tabs.tsx
  9. +28
    -0
      src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx
  10. +186
    -0
      src/pages/dashboard/shop/店舗詳細/QR取得設定/取得設定.tsx
  11. +22
    -0
      src/pages/dashboard/shop/店舗詳細/QR認証設定/index.tsx
  12. +99
    -0
      src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧.tsx
  13. +106
    -0
      src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx
  14. +1
    -1
      src/pages/dashboard/shop/店舗詳細/基本設定/index.tsx
  15. +0
    -0
      src/pages/dashboard/shop/店舗詳細/基本設定/設定.tsx
  16. +0
    -120
      src/pages/dashboard/shop/店舗詳細/設定/発行設定.tsx
  17. +0
    -0
      src/pages/dashboard/shop/店舗詳細/詳細/index.tsx
  18. +1
    -1
      src/pages/dashboard/shop/店舗詳細/詳細/デポジットチャージ.tsx
  19. +1
    -1
      src/pages/dashboard/shop/店舗詳細/詳細/詳細情報.tsx
  20. +3
    -1
      src/pages/index.ts
  21. +5
    -1
      src/routes/path.ts
  22. +19
    -5
      src/routes/sub/dashboard.tsx
  23. +19
    -0
      src/storage/cache/駐車場マスタ.ts

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


+ 70
- 0
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;
};

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


+ 28
- 18
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 <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 (
<Controller
name={name}
@@ -88,7 +98,7 @@ export default function RHFAutoComplete({ name, options, onFix, readOnly, ...oth
autoComplete
includeInputInList
noOptionsText="候補がありません"
getOptionLabel={(option) => option?.label ?? ''}
getOptionLabel={(option) => option?.label ?? ""}
isOptionEqualToValue={(option, value) => {
// if (typeof value !== 'object') return false;
return option.value === value.value;


+ 8
- 0
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(() => {


+ 5
- 12
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 (


+ 36
- 2
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<void>;
moveToMain: VoidFunction;
};

export const 店舗詳細Context = createContext<Context>({
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<QRサービス券取得設定 | null>(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,
}}


+ 21
- 3
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",
},


+ 28
- 0
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 <Page />;
}

function Page() {
const { shop, acquisitionSetting, certificationSetting } =
useContext(店舗詳細Context);

if (!shop || !acquisitionSetting || !certificationSetting) {
return null;
}

return (
<Box>
<Stack spacing={2}>
<取得設定 />
</Stack>
</Box>
);
}

+ 186
- 0
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<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>
);
}

+ 22
- 0
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 (
<Box>
<Stack spacing={2}>
<駐車場一覧 />
<駐車場追加 />
</Stack>
</Box>
);
}

+ 99
- 0
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 (
<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>
);
}

+ 106
- 0
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<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>
);
}

src/pages/dashboard/shop/店舗詳細/設定/index.tsx → 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 <Page />;
}


src/pages/dashboard/shop/店舗詳細/設定/設定.tsx → src/pages/dashboard/shop/店舗詳細/基本設定/設定.tsx 查看文件


+ 0
- 120
src/pages/dashboard/shop/店舗詳細/設定/発行設定.tsx 查看文件

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

src/pages/dashboard/shop/店舗詳細/index.tsx → src/pages/dashboard/shop/店舗詳細/詳細/index.tsx 查看文件


src/pages/dashboard/shop/店舗詳細/デポジットチャージ.tsx → 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;

src/pages/dashboard/shop/店舗詳細/詳細情報.tsx → 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);

+ 3
- 1
src/pages/index.ts 查看文件

@@ -45,7 +45,9 @@ export const TabID = {
NONE: id++,

店舗詳細_メイン: id++,
店舗詳細_設定: id++,
店舗詳細_基本設定: id++,
店舗詳細_QR認証設定: id++,
店舗詳細_QR取得設定: id++,

QRサービス券駐車場グループ管理_一覧: id++,
QRサービス券駐車場グループ管理_新規登録: id++,


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


+ 19
- 5
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取得設定]),
},
],
},


+ 19
- 0
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 駐車場マスタストア();

Loading…
取消
儲存