diff --git a/src/api/index.ts b/src/api/index.ts index dc8c4d4..d55b0ae 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -13,6 +13,8 @@ export const ApiId = { LOGIN: id++, LOGOUT: id++, + + SEASON_TICKET_CONTRACTS: id++, } as const; export type ApiId = (typeof ApiId)[keyof typeof ApiId]; diff --git a/src/api/season-ticket-contract.ts b/src/api/season-ticket-contract.ts new file mode 100644 index 0000000..65336d0 --- /dev/null +++ b/src/api/season-ticket-contract.ts @@ -0,0 +1,26 @@ +import { APICommonResponse, ApiId, HttpMethod, request } from "api"; +import { getUrl } from "./url"; + +export type SeasonTicketContract = { + season_ticekt_contract_record_no: string | null; + parking_name: string | null; + room_no: string | null; + season_ticket_seq_no: string | null; + vehicle_no: string | null; + vehicle_type: string | null; + contract_start_date: string | null; + contract_end_date: string | null; + revision: number; +}; + +type SeasonTicketContractsResponse = { + data: SeasonTicketContract[]; +} & APICommonResponse; + +export const getSeasonTicketContracts = async () => { + const res = await request({ + url: getUrl(ApiId.SEASON_TICKET_CONTRACTS), + method: HttpMethod.GET, + }); + return res; +}; diff --git a/src/api/url.ts b/src/api/url.ts index eabb178..0d1477c 100644 --- a/src/api/url.ts +++ b/src/api/url.ts @@ -6,6 +6,7 @@ const urls = { [A.ME]: "me", [A.LOGIN]: "login", [A.LOGOUT]: "logout", + [A.SEASON_TICKET_CONTRACTS]: "season-ticket-contracts", }; const prefixs = { diff --git a/src/contexts/dashboard/SeasonTicketContractContext.tsx b/src/contexts/dashboard/SeasonTicketContractContext.tsx new file mode 100644 index 0000000..f5a2d10 --- /dev/null +++ b/src/contexts/dashboard/SeasonTicketContractContext.tsx @@ -0,0 +1,84 @@ +import { HasChildren } from "@types"; +import { + SeasonTicketContract, + getSeasonTicketContracts, +} from "api/season-ticket-contract"; +import useAPICall from "hooks/useAPICall"; +import useAuth from "hooks/useAuth"; +import { + createContext, + useContext, + useEffect, + useLayoutEffect, + useState, +} from "react"; + +type ContextProps = { + initialized: boolean; + seasonTicketContracts: SeasonTicketContract[]; + selectedseasonTicketContract: SeasonTicketContract | null; + + fetch: VoidFunction; + select: (target: SeasonTicketContract | null) => void; +}; +export const SeasonTicketContractContext = createContext({ + initialized: false, + seasonTicketContracts: [], + selectedseasonTicketContract: null, + + fetch: () => {}, + select: (target: SeasonTicketContract | null) => {}, +}); + +type Props = HasChildren; +export function SeasonTicketContractContextProvider({ children }: Props) { + const { initialized, authenticated } = useAuth(); + const [fetchInitialized, setFetchInitialized] = useState(false); + + const [seasonTicketContracts, setSeasonTicketContracts] = useState< + SeasonTicketContract[] + >([]); + const [selectedseasonTicketContract, setSelectedseasonTicketContract] = + useState(null); + + const { callAPI: callGetSeasonTicketContracts } = useAPICall({ + apiMethod: getSeasonTicketContracts, + backDrop: true, + onSuccess: ({ data }) => { + setSeasonTicketContracts(data); + setFetchInitialized(true); + }, + onFailed: () => { + setSeasonTicketContracts([]); + setFetchInitialized(true); + }, + }); + + const fetch = () => { + callGetSeasonTicketContracts({}); + }; + + useEffect(() => { + if (authenticated) { + fetch(); + } + }, [authenticated]); + + return ( + + {children} + + ); +} + +export function useSeasonTicketContractContext() { + return useContext(SeasonTicketContractContext); +} diff --git a/src/layouts/dashbord/navigator.tsx b/src/layouts/dashbord/navigator.tsx index 1b82eb5..e975737 100644 --- a/src/layouts/dashbord/navigator.tsx +++ b/src/layouts/dashbord/navigator.tsx @@ -79,12 +79,12 @@ export default function Navigator(props: DrawerProps) { { label: "契約", icon: , - id: PageID.DASHBOARD_CONTRACT_LIST, + id: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST, }, { label: "新規利用申込", icon: , - id: PageID.DASHBOARD_CONTRACT_ENTRY, + id: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_ENTRY, }, { label: "領収証ダウンロード", diff --git a/src/pages/dashboard/contract/detail.tsx b/src/pages/dashboard/contract/detail.tsx index 6830119..41e1b21 100644 --- a/src/pages/dashboard/contract/detail.tsx +++ b/src/pages/dashboard/contract/detail.tsx @@ -9,33 +9,62 @@ import { TableRow, Typography, } from "@mui/material"; +import { useSeasonTicketContractContext } from "contexts/dashboard/SeasonTicketContractContext"; import useDashboard from "hooks/useDashBoard"; import useNavigateCustom from "hooks/useNavigateCustom"; import { PageID, TabID } from "pages"; import { useEffect } from "react"; +import { useParams } from "react-router-dom"; +import { getPath } from "routes/path"; export default function ContractDetail() { const { setHeaderTitle, setTabs } = useDashboard( - PageID.DASHBOARD_CONTRACT_DETAIL, + PageID.DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL, TabID.NONE ); - const { navigate } = useNavigateCustom(); + + const { id: paramId } = useParams(); + + const { + initialized, + selectedseasonTicketContract: seasonTicketContract, + seasonTicketContracts, + select, + } = useSeasonTicketContractContext(); + + const { navigate, navigateWhenChanged } = useNavigateCustom(); + + const moveToList = () => { + navigateWhenChanged(getPath(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST)); + }; useEffect(() => { setHeaderTitle("契約詳細"); setTabs(null); }, [setHeaderTitle, setTabs]); + + useEffect(() => { + if (initialized && !!paramId) { + const target = seasonTicketContracts.find((ele) => { + return ele.season_ticekt_contract_record_no === paramId; + }); + if (target) { + select(target); + } else { + select(null); + moveToList(); + } + } + }, [initialized]); + + if (!initialized || seasonTicketContract === null) { + return null; + } return ( - + - + 契約情報 @@ -43,15 +72,18 @@ export default function ContractDetail() { 駐車場名 - A駐車場 + {seasonTicketContract.parking_name} 区画 - 1-1 + {seasonTicketContract.room_no} 契約期間 - 2023/8/1-2024/7/31 + + {seasonTicketContract.contract_start_date}- + {seasonTicketContract.contract_end_date} + diff --git a/src/pages/dashboard/contract/entry.tsx b/src/pages/dashboard/contract/entry.tsx index 4c5ebf0..8c5b341 100644 --- a/src/pages/dashboard/contract/entry.tsx +++ b/src/pages/dashboard/contract/entry.tsx @@ -5,7 +5,7 @@ import { useEffect } from "react"; export default function ContractEntry() { const { setHeaderTitle, setTabs } = useDashboard( - PageID.DASHBOARD_CONTRACT_ENTRY, + PageID.DASHBOARD_SEASON_TICKET_CONTRACT_ENTRY, TabID.NONE ); @@ -17,11 +17,8 @@ export default function ContractEntry() { return ( 新規の申込は、こちらよりお願いします。 - - 京都・滋賀駐車場なび - - - 大阪・神戸・奈良駐車場なび + + 月極定期駐車場ナビ ); diff --git a/src/pages/dashboard/contract/list.tsx b/src/pages/dashboard/contract/list.tsx index 38b72a6..267a8b5 100644 --- a/src/pages/dashboard/contract/list.tsx +++ b/src/pages/dashboard/contract/list.tsx @@ -1,26 +1,44 @@ import { Box, Grid, Paper, Typography } from "@mui/material"; +import { SeasonTicketContract } from "api/season-ticket-contract"; +import { useSeasonTicketContractContext } from "contexts/dashboard/SeasonTicketContractContext"; import useDashboard from "hooks/useDashBoard"; import useNavigateCustom from "hooks/useNavigateCustom"; import { PageID, TabID } from "pages"; import { useEffect } from "react"; import { getPath } from "routes/path"; +function SeasonTicketContractCard({ data }: { data: SeasonTicketContract }) { + const { navigateWhenChanged } = useNavigateCustom(); + const handleClick = () => { + navigateWhenChanged( + getPath(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL, { + query: { + id: data.season_ticekt_contract_record_no ?? "", + }, + }) + ); + }; + return ( + + {data.parking_name} + 区画:{data.room_no} + + ); +} + export default function ContractList() { const { setHeaderTitle, setTabs } = useDashboard( - PageID.DASHBOARD_CONTRACT_LIST, + PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST, TabID.NONE ); - const { navigateWhenChanged } = useNavigateCustom(); + const { seasonTicketContracts } = useSeasonTicketContractContext(); - const items = [ - { parkingName: "A駐車場", position: "1" }, - { parkingName: "B駐車場", position: "1-1" }, - ]; + const { navigateWhenChanged } = useNavigateCustom(); const moveToDetail = () => { navigateWhenChanged( - getPath(PageID.DASHBOARD_CONTRACT_DETAIL, { + getPath(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL, { query: { id: "test-test", }, @@ -35,13 +53,10 @@ export default function ContractList() { return ( - {items.map((item, index) => { + {seasonTicketContracts.map((item, index) => { return ( - - {item.parkingName} - 区画:{item.position} - + ); })} diff --git a/src/pages/dashboard/user/detail.tsx b/src/pages/dashboard/user/detail.tsx index dadca53..999a88d 100644 --- a/src/pages/dashboard/user/detail.tsx +++ b/src/pages/dashboard/user/detail.tsx @@ -1,12 +1,11 @@ import { Button, Stack } from "@mui/material"; -import StackRow from "components/stack/StackRow"; import useDashboard from "hooks/useDashBoard"; import { PageID, TabID } from "pages"; import { useEffect } from "react"; export default function UserDetail() { const { setHeaderTitle, setTabs } = useDashboard( - PageID.DASHBOARD_CONTRACT_DETAIL, + PageID.DASHBOARD_USER_DETAIL, TabID.NONE ); diff --git a/src/pages/index.ts b/src/pages/index.ts index 0a21e80..6997749 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -7,9 +7,9 @@ export const PageID = { DASHBOARD_OVERVIEW: id++, - DASHBOARD_CONTRACT_ENTRY: id++, - DASHBOARD_CONTRACT_LIST: id++, - DASHBOARD_CONTRACT_DETAIL: id++, + DASHBOARD_SEASON_TICKET_CONTRACT_ENTRY: id++, + DASHBOARD_SEASON_TICKET_CONTRACT_LIST: id++, + DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL: id++, DASHBOARD_RECEIPT_DOWNLOAD: id++, diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 3e117ad..3b5acc6 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -41,7 +41,7 @@ export function Routes() { return useRoutes([ CommonRoutes(), AuthRoutes(), - DashboardRoutes(), + ...DashboardRoutes(), { path: "403", element: , diff --git a/src/routes/path.ts b/src/routes/path.ts index 2bdaa44..3b17e00 100644 --- a/src/routes/path.ts +++ b/src/routes/path.ts @@ -31,10 +31,11 @@ const getTabId = (key: PathKey): TabID => { const PATHS_DASHBOARD = { [makePathKey(PageID.DASHBOARD_OVERVIEW)]: "/dashboard", // --契約----------------------- - [makePathKey(PageID.DASHBOARD_CONTRACT_ENTRY)]: "/dashboard/contract/entry", - [makePathKey(PageID.DASHBOARD_CONTRACT_LIST)]: + [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_ENTRY)]: + "/dashboard/contract/entry", + [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST)]: "/dashboard/contract/list/:page", - [makePathKey(PageID.DASHBOARD_CONTRACT_DETAIL)]: + [makePathKey(PageID.DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL)]: "/dashboard/contract/detail/:id", [makePathKey(PageID.DASHBOARD_RECEIPT_DOWNLOAD)]: "/dashboard/receipt/download", diff --git a/src/routes/sub/dashboard.tsx b/src/routes/sub/dashboard.tsx index 51b68c6..aead618 100644 --- a/src/routes/sub/dashboard.tsx +++ b/src/routes/sub/dashboard.tsx @@ -1,3 +1,4 @@ +import { SeasonTicketContractContextProvider } from "contexts/dashboard/SeasonTicketContractContext"; import useAuth from "hooks/useAuth"; import DashboardLayout from "layouts/dashbord"; import { PageID } from "pages"; @@ -6,7 +7,7 @@ import { RouteObject } from "react-router-dom"; import { Loadable } from "routes"; import { getRoute } from "routes/path"; -export default function DashboardRoutes(): RouteObject { +export default function DashboardRoutes(): RouteObject[] { const { authenticated } = useAuth(); const children: RouteObject[] = useMemo(() => { @@ -16,12 +17,6 @@ export default function DashboardRoutes(): RouteObject { const ContractEntry = Loadable( lazy(() => import("pages/dashboard/contract/entry")) ); - const ContractList = Loadable( - lazy(() => import("pages/dashboard/contract/list")) - ); - const ContractDetail = Loadable( - lazy(() => import("pages/dashboard/contract/detail")) - ); const ReceiptDownload = Loadable( lazy(() => import("pages/dashboard/receipt/download")) ); @@ -36,17 +31,9 @@ export default function DashboardRoutes(): RouteObject { element: , }, { - pageId: PageID.DASHBOARD_CONTRACT_ENTRY, + pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_ENTRY, element: , }, - { - pageId: PageID.DASHBOARD_CONTRACT_LIST, - element: , - }, - { - pageId: PageID.DASHBOARD_CONTRACT_DETAIL, - element: , - }, { pageId: PageID.DASHBOARD_RECEIPT_DOWNLOAD, element: , @@ -66,8 +53,44 @@ export default function DashboardRoutes(): RouteObject { })); }, [authenticated]); - return { - element: , - children: children, - }; + const seasonTicketContractChildren: RouteObject[] = useMemo(() => { + if (!authenticated) return []; + + const ContractList = Loadable( + lazy(() => import("pages/dashboard/contract/list")) + ); + const ContractDetail = Loadable( + lazy(() => import("pages/dashboard/contract/detail")) + ); + + const allChildren = [ + { + pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_LIST, + element: , + }, + { + pageId: PageID.DASHBOARD_SEASON_TICKET_CONTRACT_DETAIL, + element: , + }, + ]; + return allChildren.map(({ pageId, ...others }) => ({ + ...others, + path: getRoute(pageId), + })); + }, [authenticated]); + + return [ + { + element: , + children: children, + }, + { + element: ( + + + + ), + children: seasonTicketContractChildren, + }, + ]; }