瀏覽代碼

QR取得周りの整備

develop
sosuke.iwabuchi 1 年之前
父節點
當前提交
4dfa95995c
共有 22 個檔案被更改,包括 609 行新增53 行删除
  1. +2
    -0
      src/api/index.ts
  2. +31
    -2
      src/api/login-user.ts
  3. +33
    -0
      src/api/qr-service.ts
  4. +3
    -0
      src/api/url.ts
  5. +3
    -3
      src/auth/route.ts
  6. +1
    -1
      src/contexts/AuthContext.tsx
  7. +7
    -6
      src/contexts/page/dashboard/shop/店舗詳細Context.tsx
  8. +19
    -4
      src/layouts/dashbord/navigator.tsx
  9. +85
    -0
      src/pages/dashboard/login-user/店舗/一覧/SearchBox.tsx
  10. +100
    -0
      src/pages/dashboard/login-user/店舗/一覧/TableBox.tsx
  11. +38
    -0
      src/pages/dashboard/login-user/店舗/一覧/index.tsx
  12. +149
    -0
      src/pages/dashboard/login-user/店舗/新規登録/index.tsx
  13. +2
    -5
      src/pages/dashboard/login-user/顧客ログインユーザ一覧/SearchBox.tsx
  14. +3
    -3
      src/pages/dashboard/login-user/顧客ログインユーザ一覧/TableBox.tsx
  15. +2
    -2
      src/pages/dashboard/login-user/顧客ログインユーザ一覧/index.tsx
  16. +90
    -13
      src/pages/dashboard/qr-service/サービス券発行用QRコード.tsx
  17. +5
    -1
      src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx
  18. +1
    -1
      src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧/index.tsx
  19. +1
    -0
      src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx
  20. +1
    -1
      src/pages/qr-service/QRサービス券発行申請.tsx
  21. +6
    -3
      src/routes/path.ts
  22. +27
    -8
      src/routes/sub/dashboard.tsx

+ 2
- 0
src/api/index.ts 查看文件

@@ -51,6 +51,8 @@ export const ApiId = {
QRサービス券駐車場グループ新規登録: id++,
QRサービス券駐車場グループ駐車場追加登録: id++,
QRサービス券駐車場グループ駐車場削除登録: id++,
QRサービス券取得用トークン取得: id++,
QRサービス券取得用トークンリフレッシュ: id++,
QRサービス券取得: id++,
} as const;
export type ApiId = (typeof ApiId)[keyof typeof ApiId];


+ 31
- 2
src/api/login-user.ts 查看文件

@@ -1,7 +1,7 @@
import { APICommonResponse, ApiId, HttpMethod, makeParam, request } from "api";
import { getUrl } from "./url";

export type 運営会社ログインユーザ = {
export type 顧客ログインユーザ = {
id: string;
name: string;
email: string;
@@ -9,6 +9,14 @@ export type 運営会社ログインユーザ = {
customer_name: string;
};

export type 店舗ログインユーザ = {
id: string;
name: string;
email: string;
shop_id: string;
shop_name: string;
};

// -------顧客ログインユーザ新規登録---------------
export type 顧客ログインユーザ新規登録Request = {
name: string;
@@ -62,7 +70,7 @@ export type 顧客ログインユーザ一覧取得Request = {
};
export type 顧客ログインユーザ一覧取得Response = {
data: {
list: 運営会社ログインユーザ[];
list: 顧客ログインユーザ[];
};
} & APICommonResponse;
export const 顧客ログインユーザ一覧取得 = async (
@@ -75,3 +83,24 @@ export const 顧客ログインユーザ一覧取得 = async (
});
return res;
};

// -------店舗ログインユーザ一覧取得---------------
export type 店舗ログインユーザ一覧取得Request = {
email?: string;
name?: string;
};
export type 店舗ログインユーザ一覧取得Response = {
data: {
list: 店舗ログインユーザ[];
};
} & APICommonResponse;
export const 店舗ログインユーザ一覧取得 = async (
param: 店舗ログインユーザ一覧取得Request
) => {
const res = await request<店舗ログインユーザ一覧取得Response>({
url: getUrl(ApiId.店舗ログインユーザ一覧取得),
method: HttpMethod.GET,
data: new URLSearchParams(param),
});
return res;
};

+ 33
- 0
src/api/qr-service.ts 查看文件

@@ -102,3 +102,36 @@ export const QRサービス券駐車場グループ駐車場削除登録 = async
});
return res;
};

// -------QRサービス券取得用トークン取得---------------
export type QRサービス券取得用トークン取得Request = {};
export type QRサービス券取得用トークン取得Response = {
data: {
token: string;
};
} & APICommonResponse;
export const QRサービス券取得用トークン取得 = async (
param: QRサービス券取得用トークン取得Request
) => {
const res = await request<QRサービス券取得用トークン取得Response>({
url: getUrl(ApiId.QRサービス券取得用トークン取得),
method: HttpMethod.GET,
data: makeParam(param),
});
return res;
};

// -------QRサービス券取得用トークンリフレッシュ---------------
export type QRサービス券取得用トークンリフレッシュRequest = {};
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;
};

+ 3
- 0
src/api/url.ts 查看文件

@@ -49,6 +49,9 @@ const urls = {
"qr-service/parking-group/parking/add",
[A.QRサービス券駐車場グループ駐車場削除登録]:
"qr-service/parking-group/parking/remove",
[A.QRサービス券取得用トークン取得]: "qr-service/acquisition/token",
[A.QRサービス券取得用トークンリフレッシュ]:
"qr-service/acquisition/token/refresh",
[A.QRサービス券取得]: "qr-service/get-ticket",
};



+ 3
- 3
src/auth/route.ts 查看文件

@@ -1,9 +1,9 @@
import { PageID as P } from "pages";
import { UserRole } from "./UserRole";

const 共通ルート = [P.LOGIN, P.LOGOUT];
const 認証後共通ルート = [P.DASHBOARD_ENPTY, P.DASHBOARD_OVERVIEW];
const 管理者顧客共通ルート = [P.成り代わり終了];
const 共通ルート: P[] = [P.LOGIN, P.LOGOUT, P.成り代わり終了];
const 認証後共通ルート: P[] = [P.DASHBOARD_ENPTY, P.DASHBOARD_OVERVIEW];
const 管理者顧客共通ルート: P[] = [];

const 認可別許可ルート: {
[route: string]: P[];


+ 1
- 1
src/contexts/AuthContext.tsx 查看文件

@@ -176,7 +176,6 @@ function AuthContextProvider({ children }: Props) {

const cacheClear = () => {
駐車場マスタストア.clear();
駐車場マスタストア.clear();
};

const login = async (email: string, password: string) => {
@@ -193,6 +192,7 @@ function AuthContextProvider({ children }: Props) {
user_id,
});
navigateWhenChanged(getPath(PageID.DASHBOARD_OVERVIEW));
cacheClear();
};
const switchShopRole = async (user_id: string) => {
await call店舗成り代わり開始({ user_id });


+ 7
- 6
src/contexts/page/dashboard/shop/店舗詳細Context.tsx 查看文件

@@ -20,8 +20,8 @@ import 駐車場マスタストア from "storage/cache/駐車場マスタ";

type Context = {
shop: 店舗 | null;
certificationSetting: QRサービス券認証設定[];
acquisitionSetting: QRサービス券取得設定 | null;
certificationSetting: QRサービス券認証設定[] | undefined;
acquisitionSetting: QRサービス券取得設定 | null | undefined;
parkings: 駐車場マスタ[];
fetch: () => Promise<void>;
moveToMain: VoidFunction;
@@ -43,10 +43,11 @@ function 店舗詳細ContextProvider({ children }: Props) {
const [shop, setShop] = useState<店舗 | null>(null);
const [parkings, setParkings] = useState<駐車場マスタ[]>([]);
const [certificationSetting, setCertificationSetting] = useState<
QRサービス券認証設定[]
>([]);
const [acquisitionSetting, setAcquisitionSetting] =
useState<QRサービス券取得設定 | null>(null);
QRサービス券認証設定[] | undefined
>(undefined);
const [acquisitionSetting, setAcquisitionSetting] = useState<
QRサービス券取得設定 | null | undefined
>(undefined);
const { success, error } = useSnackbarCustom();
const { navigateWhenChanged } = useNavigateCustom();



+ 19
- 4
src/layouts/dashbord/navigator.tsx 查看文件

@@ -90,20 +90,30 @@ export default function Navigator(props: DrawerProps) {
icon: <ArticleIcon />,
id: PageID.ログインユーザ_顧客新規登録,
},
{
label: "店舗一覧",
icon: <ArticleIcon />,
id: PageID.ログインユーザ_店舗一覧,
},
{
label: "店舗新規登録",
icon: <ArticleIcon />,
id: PageID.ログインユーザ_店舗新規登録,
},
],
},
{
label: "店舗管理",
children: [
{
label: "店舗新規登録",
label: "店舗一覧",
icon: <ArticleIcon />,
id: PageID.店舗新規登録,
id: PageID.店舗一覧,
},
{
label: "店舗一覧",
label: "店舗新規登録",
icon: <ArticleIcon />,
id: PageID.店舗一覧,
id: PageID.店舗新規登録,
},
],
},
@@ -129,6 +139,11 @@ export default function Navigator(props: DrawerProps) {
{
label: "QRサービス券",
children: [
{
label: "サービス券発行",
icon: <ArticleIcon />,
id: PageID.サービス券発行用QRコード,
},
{
label: "利用履歴",
icon: <ArticleIcon />,


+ 85
- 0
src/pages/dashboard/login-user/店舗/一覧/SearchBox.tsx 查看文件

@@ -0,0 +1,85 @@
import { Box, Grid, Stack, Typography } from "@mui/material";
import { Dictionary } from "@types";
import { 店舗ログインユーザ, 店舗ログインユーザ一覧取得 } from "api/login-user";
import { FormProvider, RHFTextField } from "components/hook-form";
import useAPICall from "hooks/useAPICall";
import useSearchConditionContext from "hooks/useSearchConditionContext";
import { UseTableReturn } from "hooks/useTable";
import { isEqual } from "lodash";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";

type FormProps = {
name: string;
email: string;
};

type CommonProps = {
table: UseTableReturn<店舗ログインユーザ>;
};
export default function SearchBox({ table }: CommonProps) {
const [lastSendSearchCondition, setLastSendSearchCondition] =
useState<object>({ default: false });
const { condition, initialized, get, addCondition } =
useSearchConditionContext();
const form = useForm<FormProps>({
defaultValues: {
name: "",
email: "",
},
});

const { callAPI: call店舗ログインユーザ一覧取得, makeSendData } = useAPICall({
apiMethod: 店舗ログインユーザ一覧取得,
form,
backDrop: true,
onSuccess: ({ data }) => {
table.setRowData(data.list);
},
});

const handleBlur = () => {
addCondition(form.getValues());
};
const handleSubmit = async (data: FormProps) => {
addCondition(data);
};

const fetch = async (data: Dictionary) => {
const sendData = makeSendData(data);
if (!isEqual(sendData, lastSendSearchCondition)) {
setLastSendSearchCondition(sendData);
call店舗ログインユーザ一覧取得(sendData);
}
};

// 初期値設定
useEffect(() => {
if (initialized) {
fetch(condition);
form.setValue("name", get("name"));
form.setValue("email", get("email"));
}
}, [condition, initialized]);

return (
<FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}>
<Box sx={{ p: 1, m: 1 }}>
<Grid container spacing={2} mt={-1}>
<Grid item xs={12} lg={6}>
<Stack>
<Typography>名前</Typography>
<RHFTextField name="name" onBlur={handleBlur} />
</Stack>
</Grid>
<Grid item xs={12} lg={6}>
<Stack>
<Typography>Email</Typography>
<RHFTextField name="email" onBlur={handleBlur} />
</Stack>
</Grid>
</Grid>
</Box>
</FormProvider>
);
}

+ 100
- 0
src/pages/dashboard/login-user/店舗/一覧/TableBox.tsx 查看文件

@@ -0,0 +1,100 @@
import {
Box,
Table,
TableBody,
TableCell,
TableContainer,
TablePagination,
TableRow,
} from "@mui/material";
import { 店舗ログインユーザ } from "api/login-user";
import TableHeadCustom, {
HeadLabelProps,
} from "components/table/TableHeadCustom";
import useAuth from "hooks/useAuth";
import useSnackbarCustom from "hooks/useSnackbarCustom";
import { UseTableReturn } from "hooks/useTable";

type CommonProps = {
table: UseTableReturn<店舗ログインユーザ>;
};
export default function TableBox({ table }: CommonProps) {
const TABLE_HEAD: HeadLabelProps[] = [
{ id: "name", label: "名前", align: "left", needSort: false },
{ id: "email", label: "Email", align: "left", needSort: false },
{ id: "shop_name", label: "店舗名", align: "left", needSort: false },
];
const {
order,
page,
sort,
rowsPerPage,
fetched,
fillteredRow,
isNotFound,
dataLength,
//
onSort,
onChangePage,
onChangeRowsPerPage,
//
setRowData,
//
ROWS_PER_PAGES,
} = table;

return (
<>
<TableContainer>
<Table sx={{ minWidth: 800 }} size="small">
<TableHeadCustom
order={order}
orderBy={sort}
headLabel={TABLE_HEAD}
rowCount={1}
numSelected={0}
onSort={onSort}
/>

<TableBody>
{fillteredRow.map((row, index) => (
<Row data={row} key={index} />
))}
</TableBody>
</Table>
</TableContainer>

<Box sx={{ position: "relative" }}>
<TablePagination
rowsPerPageOptions={ROWS_PER_PAGES}
component="div"
count={dataLength}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={onChangePage}
onRowsPerPageChange={onChangeRowsPerPage}
/>
</Box>
</>
);
}

type RowProps = {
data: 店舗ログインユーザ;
};
function Row({ data }: RowProps) {
const { switchShopRole } = useAuth();
const { info } = useSnackbarCustom();
const handleClick = () => {
switchShopRole(data.id);
info("成り代わり開始しました");
};

return (
<TableRow hover sx={{ cursor: "pointer" }} onClick={handleClick}>
<TableCell>{data.name}</TableCell>
<TableCell>{data.email}</TableCell>
<TableCell>{data.shop_name}</TableCell>
</TableRow>
);
}

+ 38
- 0
src/pages/dashboard/login-user/店舗/一覧/index.tsx 查看文件

@@ -0,0 +1,38 @@
import { Box } from "@mui/material";
import { 店舗ログインユーザ } from "api/login-user";
import { SearchConditionContextProvider } from "contexts/SearchConditionContext";
import useDashboard from "hooks/useDashBoard";
import useTable from "hooks/useTable";
import { PageID, TabID } from "pages";
import { useEffect } from "react";
import SearchBox from "./SearchBox";
import TableBox from "./TableBox";

export default function Main() {
const { setHeaderTitle, setTabs } = useDashboard(
PageID.ログインユーザ_店舗一覧,
TabID.NONE
);

useEffect(() => {
setHeaderTitle("ログインユーザ一覧");
setTabs(null);
}, []);

return (
<SearchConditionContextProvider>
<Page />
</SearchConditionContextProvider>
);
}

function Page() {
const table = useTable<店舗ログインユーザ>();

return (
<Box>
<SearchBox table={table} />
<TableBox table={table} />
</Box>
);
}

+ 149
- 0
src/pages/dashboard/login-user/店舗/新規登録/index.tsx 查看文件

@@ -0,0 +1,149 @@
import { yupResolver } from "@hookform/resolvers/yup";
import { Box, Button, Stack, Typography } from "@mui/material";
import { 店舗ログインユーザ新規登録 } from "api/login-user";
import { 店舗, 店舗一覧取得 } from "api/shop";
import {
FormProvider,
RHFAutoComplete,
RHFTextField,
} from "components/hook-form";
import {
AutoCompleteOption,
AutoCompleteOptionType,
getValue,
} from "components/hook-form/RHFAutoComplete";
import StackRow from "components/stack/StackRow";
import useAPICall from "hooks/useAPICall";
import useDashboard from "hooks/useDashBoard";
import useNavigateCustom from "hooks/useNavigateCustom";
import useSnackbarCustom from "hooks/useSnackbarCustom";
import { PageID, TabID } from "pages";
import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import { getPath } from "routes/path";
import { object, string } from "yup";

type FormProps = {
name: string;
email: string;
password: string;
password_retype: string;
shop_id: AutoCompleteOptionType;
};

export default function Main() {
const { setHeaderTitle, setTabs } = useDashboard(
PageID.ログインユーザ_店舗新規登録,
TabID.NONE
);

const { success, error } = useSnackbarCustom();
const { navigateWhenChanged } = useNavigateCustom();

const [shops, setShops] = useState<店舗[]>([]);

const shopOptions: AutoCompleteOption[] = useMemo(() => {
return shops.map((data) => {
return {
label: data.name,
value: data.shop_id,
};
});
}, [shops]);

const form = useForm<FormProps>({
defaultValues: {
name: "",
email: "",
password: "",
password_retype: "",
shop_id: "",
},
resolver: yupResolver(
object().shape({
name: string().required("必須項目です"),
email: string().required("必須項目です"),
password: string().required("必須項目です"),
password_retype: string()
.required("必須項目です")
.test("retype", "入力が一致しません", function (value) {
return this.parent.password === value;
}),
shop_id: object().required("必須項目です"),
})
),
});

const { callAPI: call店舗ログインユーザ新規登録 } = useAPICall({
apiMethod: 店舗ログインユーザ新規登録,
form,
backDrop: true,
onSuccess: ({ data }, sendData) => {
success("登録しました");
navigateWhenChanged(
getPath(PageID.ログインユーザ_店舗一覧),
new URLSearchParams({ email: sendData.email })
);
},
onFailed: () => {
error("失敗しました");
},
});

const { callAPI: call店舗一覧取得 } = useAPICall({
apiMethod: 店舗一覧取得,
onSuccess: ({ data }) => {
setShops(data.list);
},
});

const handleSubmit = (data: FormProps) => {
call店舗ログインユーザ新規登録({
...data,
shop_id: getValue(data.shop_id),
});
};

useEffect(() => {
setHeaderTitle("ログインユーザ登録");
setTabs(null);

call店舗一覧取得({});
}, []);

return (
<FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}>
<Box>
<Stack>
<Box>
<Typography>名称</Typography>
<RHFTextField name="name" />
</Box>
<Box>
<Typography>Email</Typography>
<RHFTextField type="email" name="email" />
</Box>
<Box>
<Typography>パスワード</Typography>
<RHFTextField type="password" name="password" />
</Box>
<Box>
<Typography>パスワード(再入力)</Typography>
<RHFTextField type="password" name="password_retype" />
</Box>
<Box>
<Typography>店舗</Typography>
<RHFAutoComplete
name="shop_id"
options={shopOptions}
size="small"
/>
</Box>
<StackRow>
<Button type="submit">登録</Button>
</StackRow>
</Stack>
</Box>
</FormProvider>
);
}

+ 2
- 5
src/pages/dashboard/login-user/顧客ログインユーザ一覧/SearchBox.tsx 查看文件

@@ -1,9 +1,6 @@
import { Box, Grid, Stack, Typography } from "@mui/material";
import { Dictionary } from "@types";
import {
運営会社ログインユーザ,
顧客ログインユーザ一覧取得,
} from "api/login-user";
import { 顧客ログインユーザ, 顧客ログインユーザ一覧取得 } from "api/login-user";
import { FormProvider, RHFTextField } from "components/hook-form";
import useAPICall from "hooks/useAPICall";
import useSearchConditionContext from "hooks/useSearchConditionContext";
@@ -18,7 +15,7 @@ type FormProps = {
};

type CommonProps = {
table: UseTableReturn<運営会社ログインユーザ>;
table: UseTableReturn<顧客ログインユーザ>;
};
export default function SearchBox({ table }: CommonProps) {
const [lastSendSearchCondition, setLastSendSearchCondition] =


+ 3
- 3
src/pages/dashboard/login-user/顧客ログインユーザ一覧/TableBox.tsx 查看文件

@@ -7,7 +7,7 @@ import {
TablePagination,
TableRow,
} from "@mui/material";
import { 運営会社ログインユーザ } from "api/login-user";
import { 顧客ログインユーザ } from "api/login-user";
import TableHeadCustom, {
HeadLabelProps,
} from "components/table/TableHeadCustom";
@@ -16,7 +16,7 @@ import useSnackbarCustom from "hooks/useSnackbarCustom";
import { UseTableReturn } from "hooks/useTable";

type CommonProps = {
table: UseTableReturn<運営会社ログインユーザ>;
table: UseTableReturn<顧客ログインユーザ>;
};
export default function TableBox({ table }: CommonProps) {
const TABLE_HEAD: HeadLabelProps[] = [
@@ -80,7 +80,7 @@ export default function TableBox({ table }: CommonProps) {
}

type RowProps = {
data: 運営会社ログインユーザ;
data: 顧客ログインユーザ;
};
function Row({ data }: RowProps) {
const { switchCustomerRole } = useAuth();


+ 2
- 2
src/pages/dashboard/login-user/顧客ログインユーザ一覧/index.tsx 查看文件

@@ -1,5 +1,5 @@
import { Box } from "@mui/material";
import { 運営会社ログインユーザ } from "api/login-user";
import { 顧客ログインユーザ } from "api/login-user";
import { SearchConditionContextProvider } from "contexts/SearchConditionContext";
import useDashboard from "hooks/useDashBoard";
import useTable from "hooks/useTable";
@@ -27,7 +27,7 @@ export default function 顧客一覧() {
}

function Page() {
const table = useTable<運営会社ログインユーザ>();
const table = useTable<顧客ログインユーザ>();

return (
<Box>


+ 90
- 13
src/pages/dashboard/qr-service/サービス券発行用QRコード.tsx 查看文件

@@ -1,9 +1,18 @@
import { Box, Button, Paper, Stack } from "@mui/material";
import { HasChildren } from "@types";
import {
QRサービス券取得用トークンリフレッシュ,
QRサービス券取得用トークン取得,
} from "api/qr-service";
import useAPICall from "hooks/useAPICall";
import useAuth from "hooks/useAuth";
import useDashboard from "hooks/useDashBoard";
import useNavigateCustom from "hooks/useNavigateCustom";
import { useDialog } from "hooks/useDialog";
import useSnackbarCustom from "hooks/useSnackbarCustom";
import { PageID, TabID } from "pages";
import QRCode from "qrcode";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { getFullPath, getPath } from "routes/path";

export default function サービス券発行用QRコード() {
const { setHeaderTitle, setTabs } = useDashboard(
@@ -12,23 +21,53 @@ export default function サービス券発行用QRコード() {
);
const size = 200;

const url = "http://localhost:8080/dashboard/qr/generate";
const { error } = useSnackbarCustom();
const [token, setToken] = useState("");
const [qr, setQr] = useState("");

const { navigateWhenChanged } = useNavigateCustom();
const { callAPI: callQRサービス券取得用トークン取得 } = useAPICall({
apiMethod: QRサービス券取得用トークン取得,
backDrop: true,
onSuccess: ({ data }) => {
setToken(data.token);
},
onFailed: () => {
error("QR表示失敗しました");
},
});

const [qr, setQr] = useState("");
const url = useMemo(() => {
if (!token) return "";
return getFullPath(PageID.QRサービス券発行申請, {
query: {
token,
},
});
}, [token]);

const fetch = () => {
callQRサービス券取得用トークン取得({});
};

useEffect(() => {
QRCode.toDataURL(url, {
errorCorrectionLevel: "H",
}).then((data: string) => {
setQr(data);
});
}, []);
if (url) {
console.log({ url });
QRCode.toDataURL(url, {
errorCorrectionLevel: "H",
}).then((data: string) => {
setQr(data);
});
}
}, [url]);

useEffect(() => {
setHeaderTitle("サービス券発行用QRコード");
}, [setHeaderTitle, setTabs]);

useEffect(() => {
fetch();
}, []);

return (
<Box>
<Stack spacing={2}>
@@ -38,8 +77,7 @@ export default function サービス券発行用QRコード() {
{!!qr && <img src={qr} width={size} height={size}></img>}
</Box>
<Box mx="auto">
<Button variant="contained">印刷用</Button>
<Button variant="contained">QRコード変更</Button>
<RefreshButton fetch={fetch}>QRコードリフレッシュ</RefreshButton>
</Box>
</Stack>
</Paper>
@@ -47,3 +85,42 @@ export default function サービス券発行用QRコード() {
</Box>
);
}

type RefreshButtonProps = {
fetch: VoidFunction;
} & HasChildren;
function RefreshButton({ fetch }: RefreshButtonProps) {
const {} = useAuth();
const { success, error } = useSnackbarCustom();
const { callAPI: callQRサービス券取得用トークンリフレッシュ } = useAPICall({
apiMethod: QRサービス券取得用トークンリフレッシュ,
onSuccess: () => {
success("リフレッシュしました");
fetch();
},
onFailed: () => {
error("失敗しました");
},
});

const { element, open, isAgree } = useDialog({
message: "リフレッシュすると以前のQRコードが使えなくなります",
});

const handleClick = () => {
open();
};

useEffect(() => {
if (isAgree) {
callQRサービス券取得用トークンリフレッシュ({});
}
}, [isAgree]);

return (
<>
{element}
<Button onClick={handleClick}>QRコードリフレッシュ</Button>
</>
);
}

+ 5
- 1
src/pages/dashboard/shop/店舗詳細/QR取得設定/index.tsx 查看文件

@@ -14,7 +14,11 @@ function Page() {
const { shop, acquisitionSetting, certificationSetting } =
useContext(店舗詳細Context);

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



+ 1
- 1
src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場一覧/index.tsx 查看文件

@@ -18,7 +18,7 @@ export default function Page() {

const 駐車場ごと設定: 駐車場ごと設定 = useMemo(() => {
const ret: 駐車場ごと設定 = {};
certificationSetting.forEach((ele) => {
certificationSetting?.forEach((ele) => {
if (has(ret, ele.parking_management_code)) {
ret[ele.parking_management_code].push(ele);
} else {


+ 1
- 0
src/pages/dashboard/shop/店舗詳細/QR認証設定/駐車場追加.tsx 查看文件

@@ -59,6 +59,7 @@ export default function 駐車場追加() {
});

const options: AutoCompleteOption[] = useMemo(() => {
if (certificationSetting === undefined) return [];
return parkings
.filter(
(p) =>


+ 1
- 1
src/pages/qr-service/QRサービス券発行申請.tsx 查看文件

@@ -56,7 +56,7 @@ export default function QRサービス券発行申請() {
<Box>
<Stack sx={{ p: 2 }}>
<Box mx="auto">
<Typography>取得に失敗しました。店舗へお問合せ下さい。</Typography>
<Typography>無効なURLです。店舗へお問合せ下さい。</Typography>
</Box>
</Stack>
</Box>


+ 6
- 3
src/routes/path.ts 查看文件

@@ -77,14 +77,14 @@ const PATHS = {
[makePathKey(PageID.LOGOUT)]: "/logout",
[makePathKey(PageID.成り代わり終了)]: "/role/switch/end",

[makePathKey(PageID.QRサービス券発行申請)]: "qr-service/acquitision/:token",
[makePathKey(PageID.QRサービス券発行申請)]: "/qr-service/acquitision/:token",

// ダッシュボード----------------
...PATHS_DASHBOARD,

// その他
[makePathKey(PageID.PAGE_403)]: "403",
[makePathKey(PageID.PAGE_404)]: "404",
[makePathKey(PageID.PAGE_403)]: "/403",
[makePathKey(PageID.PAGE_404)]: "/404",
};

export type PathOption = {
@@ -112,6 +112,9 @@ export function getPath(key: PathKey, option?: PathOption) {

return path;
}
export function getFullPath(key: PathKey, option?: PathOption) {
return window.location.origin + getPath(key, option);
}

export function getListPagePath(key: PathKey, page: number): string {
return getPath(key, { page });


+ 27
- 8
src/routes/sub/dashboard.tsx 查看文件

@@ -50,6 +50,12 @@ export default function DashboardRoutes(): RouteObject[] {
() => import("pages/dashboard/login-user/顧客ログインユーザ新規登録")
)
);
const 店舗ログインユーザ一覧 = Loadable(
lazy(() => import("pages/dashboard/login-user/店舗/一覧"))
);
const 店舗ログインユーザ新規登録 = Loadable(
lazy(() => import("pages/dashboard/login-user/店舗/新規登録"))
);
const 店舗新規登録 = Loadable(
lazy(() => import("pages/dashboard/shop/店舗新規登録"))
);
@@ -108,14 +114,20 @@ export default function DashboardRoutes(): RouteObject[] {
path: getPath(PageID.ログインユーザ_顧客新規登録),
},
},
// {
// pageId: PageID.ログインユーザ_店舗一覧,
// element: <顧客ログインユーザ一覧 />,
// },
// {
// pageId: PageID.ログインユーザ_店舗新規登録,
// element: <顧客ログインユーザ新規登録 />,
// },
{
pageId: PageID.ログインユーザ_店舗一覧,
ele: {
element: <店舗ログインユーザ一覧 />,
path: getPath(PageID.ログインユーザ_店舗一覧),
},
},
{
pageId: PageID.ログインユーザ_店舗新規登録,
ele: {
element: <店舗ログインユーザ新規登録 />,
path: getPath(PageID.ログインユーザ_店舗新規登録),
},
},
{
pageId: PageID.店舗新規登録,
ele: {
@@ -191,6 +203,13 @@ export default function DashboardRoutes(): RouteObject[] {
],
},
},
{
pageId: PageID.サービス券発行用QRコード,
ele: {
element: <サービス券発行用QRコード />,
path: getPath(PageID.サービス券発行用QRコード),
},
},
];

return allChildren


Loading…
取消
儲存