diff --git a/package-lock.json b/package-lock.json index 7945a55..fc891c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@types/node": "^20.11.17", "@types/react-router-dom": "^5.3.3", + "axios": "^1.6.7", "chart.js": "^4.4.1", "date-fns": "^3.3.1", "react": "^18.2.0", @@ -1356,6 +1357,21 @@ "node": ">=8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1445,6 +1461,17 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1519,6 +1546,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1893,6 +1928,38 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2240,6 +2307,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -2446,6 +2532,11 @@ "node": ">= 0.8.0" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index a1b23a2..3fec6dc 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@types/node": "^20.11.17", "@types/react-router-dom": "^5.3.3", + "axios": "^1.6.7", "chart.js": "^4.4.1", "date-fns": "^3.3.1", "react": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index f871cc3..7b6d7c5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,7 +21,7 @@ function App() { } /> } /> } /> - } /> + } /> diff --git a/src/api/drivingAPIS.ts b/src/api/drivingAPIS.ts new file mode 100644 index 0000000..17f10b1 --- /dev/null +++ b/src/api/drivingAPIS.ts @@ -0,0 +1,28 @@ +import { axiosInstance } from "./instance"; + +export const drivingStartAPI = async () => { + try { + const response = await axiosInstance.post("/driving/start"); + return response.data; + } catch { + return null; + } +}; + +export const drivingEndAPI = async () => { + try { + const response = await axiosInstance.patch("/driving/end"); + return response.data; + } catch { + return null; + } +}; + +export const drivingEndReportAPI = async (reportId: number) => { + try { + const response = await axiosInstance.get(`/driving/end/${reportId}`); + return response.data; + } catch { + return null; + } +}; diff --git a/src/api/historyAPIS.ts b/src/api/historyAPIS.ts new file mode 100644 index 0000000..6bd6fe5 --- /dev/null +++ b/src/api/historyAPIS.ts @@ -0,0 +1,19 @@ +import { axiosInstance } from "./instance"; + +export const historyAPI = async () => { + try { + const response = await axiosInstance.get("/history"); + return response.data; + } catch { + return null; + } +}; + +export const historyDetailAPI = async (reportId: number) => { + try { + const response = await axiosInstance.get(`/history/${reportId}`); + return response.data; + } catch { + return null; + } +}; diff --git a/src/api/instance.ts b/src/api/instance.ts new file mode 100644 index 0000000..e1ef484 --- /dev/null +++ b/src/api/instance.ts @@ -0,0 +1,8 @@ +import axios from "axios"; + +export const axiosInstance = axios.create({ + baseURL: "http://13.209.80.41:8080", + headers: { + "Content-Type": "application/json", + }, +}); diff --git a/src/components/Drive/index.tsx b/src/components/Drive/index.tsx index 5e6a402..365542c 100644 --- a/src/components/Drive/index.tsx +++ b/src/components/Drive/index.tsx @@ -1,12 +1,17 @@ import styled from "styled-components"; import car_driving_img from "@assets/images/car_driving.gif"; import { useNavigate } from "react-router-dom"; +import { drivingEndAPI } from "@api/drivingAPIS"; export const Drive = () => { const navigate = useNavigate(); const handleClickArriveBtn = () => { - navigate("/end"); + const apiResponse = drivingEndAPI(); + apiResponse.then((res) => { + console.log(res); + navigate(`/end/${res.reportId}`); + }); }; return ( diff --git a/src/components/End/EndReport/EndReport.styles.ts b/src/components/End/EndReport/EndReport.styles.ts index 1c2706f..33a5faf 100644 --- a/src/components/End/EndReport/EndReport.styles.ts +++ b/src/components/End/EndReport/EndReport.styles.ts @@ -29,7 +29,7 @@ export const BasicInfos = styled.div` flex-direction: column; margin: 15px 0; - padding-bottom: 10px; + padding-bottom: 5px; `; export const BasicInfo = styled.div` diff --git a/src/components/End/EndReport/EndReport.tsx b/src/components/End/EndReport/EndReport.tsx index cd68ee4..86a73a5 100644 --- a/src/components/End/EndReport/EndReport.tsx +++ b/src/components/End/EndReport/EndReport.tsx @@ -1,6 +1,10 @@ import * as styles from "./EndReport.styles"; +import { DrivingEndType } from "src/types/driving"; -export const EndReport = () => { +interface EndReportProps { + data: DrivingEndType | undefined; +} +export const EndReport = ({ data }: EndReportProps) => { return ( @@ -8,41 +12,46 @@ export const EndReport = () => { - 운전 점수100점 + 운전 점수{data?.score}점 - 주행 거리12km + 주행 거리{data?.mileage}km - 주행 시간8:40 - 12:20 + 주행 시간 + {`${data?.departuredAt.slice(10, 16)} - ${data?.arrivedAt.slice( + 10, + 16 + )}`} + + + 코멘트{data?.scoreComment} 차량 외부 감지 항목 - - ∙ 감지 시나리오 1번
10번
-
- - ∙ 감지 시나리오 2번
10번
-
- - ∙ 감지 시나리오 3번
10번
-
+ {data?.externalSummaries.map((el) => { + return ( + + ∙ {el.scenarioName} +
{el.scenarioCount}번
+
+ ); + })}
차량 내부 감지 항목 - - ∙ 감지 시나리오 1번
10번
-
- - ∙ 감지 시나리오 2번
10번
-
- - ∙ 감지 시나리오 3번
10번
-
+ {data?.internalSummaries.map((el) => { + return ( + + ∙ {el.scenarioName} +
{el.scenarioCount}번
+
+ ); + })}
diff --git a/src/components/End/index.tsx b/src/components/End/index.tsx index b95e239..bd19148 100644 --- a/src/components/End/index.tsx +++ b/src/components/End/index.tsx @@ -1,11 +1,29 @@ import { Link } from "react-router-dom"; import styled from "styled-components"; import { EndReport } from "./EndReport/EndReport"; +import { drivingEndReportAPI } from "@api/drivingAPIS"; +import { useEffect, useState } from "react"; +import { DrivingEndType } from "src/types/driving"; +import { useParams } from "react-router-dom"; export const End = () => { + const [data, setData] = useState(); + + const params = useParams(); + + useEffect(() => { + const reportId = params.reportId; + if (reportId) { + const response = drivingEndReportAPI(Number(reportId)); + response.then((res) => { + setData(res); + }); + } + }, []); + return ( - + 주행 종료 diff --git a/src/components/Home/Comment.tsx b/src/components/Home/Comment.tsx new file mode 100644 index 0000000..76729ad --- /dev/null +++ b/src/components/Home/Comment.tsx @@ -0,0 +1,12 @@ +import styled from "styled-components"; + +export const Comment = () => { + return ; +}; + +const CommentContainer = styled.div` + width: 100%; + height: 100px; + margin-top: 6px; + background-color: white; +`; diff --git a/src/components/Home/Scores.tsx b/src/components/Home/Scores.tsx new file mode 100644 index 0000000..e1c166a --- /dev/null +++ b/src/components/Home/Scores.tsx @@ -0,0 +1,62 @@ +import styled from "styled-components"; +import ChangingProgressProvider from "@components/Report/Score/ChaingingProgressProvider"; +import { CircularProgressbar, buildStyles } from "react-circular-progressbar"; + +export const Scores = () => { + return ( + + 나의 운전 점수 + + + {" "} + + {(percentage) => ( + + )} + + + + + ); +}; + +const ScoresContainer = styled.div` + width: 100%; + height: 180px; + margin-top: 66px; + background-color: white; + + display: flex; + flex-direction: column; + align-items: center; +`; + +const ScoresHeader = styled.div` + width: 360px; + font-weight: 700; + font-size: 18px; + color: ${({ theme }) => theme.colors.blue600}; + margin: 20px 0; +`; + +const ScoreContents = styled.div` + width: 360px; + display: flex; + margin: 10px 0; +`; + +const ProgressbarContainer = styled.div` + width: 90px; + height: 90px; + font-weight: 600; +`; diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index 6309fdb..761ce23 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -1,14 +1,34 @@ import styled from "styled-components"; import { useNavigate } from "react-router-dom"; +import { drivingStartAPI } from "@api/drivingAPIS"; +import { PageHeader } from "@components/common/PageHeader"; +import { getDayName } from "@utils/datetime"; +import { Scores } from "./Scores"; +import { Comment } from "./Comment"; export const Home = () => { const navigate = useNavigate(); const handleClickDriveBtn = () => { - navigate("/driving"); + const apireturn = drivingStartAPI(); + apireturn.then(() => { + navigate("/driving"); + }); }; + const date = new Date(); + return ( + + 김모비님, 안녕하세요! + {`${date.getFullYear()}년 ${ + date.getMonth() + 1 + }월 ${date.getDay()}일 (${getDayName(date)})`} + + + + + 운전하기 ); @@ -20,6 +40,28 @@ const HomeContainer = styled.div` position: relative; `; +const SubHeader = styled.div` + width: 360px; + font-weight: 600; + font-size: 16px; + color: ${({ theme }) => theme.colors.gray9}; +`; + +const DateText = styled.div` + width: 360px; + font-size: 14px; + font-weight: 400; + color: ${({ theme }) => theme.colors.gray6}; + margin-top: 5px; +`; + +const Contents = styled.div` + display: flex; + flex-direction: column; + width: 100%; + height: 100%; +`; + const DrvieButton = styled.button` position: absolute; bottom: 100px; diff --git a/src/components/Note/DetailReport/index.tsx b/src/components/Note/DetailReport/index.tsx index 410a830..bcd70d8 100644 --- a/src/components/Note/DetailReport/index.tsx +++ b/src/components/Note/DetailReport/index.tsx @@ -1,35 +1,30 @@ import { useState, useEffect } from "react"; import { ReportDetailType } from "src/types/report"; import * as styles from "./Detail.styles"; +import { historyDetailAPI } from "@api/historyAPIS"; interface DetailReportProps { reportId: number; } -const data = [ - { - scenarioType: 1, - scenarioName: "차선 변경", - total: 1, - }, - { - scenarioType: 4, - scenarioName: "정면 주시 안함", - total: 12, - }, -]; +interface DetailHistoryType { + internalSummaries: ReportDetailType[]; + externalSummaries: ReportDetailType[]; +} + export const DetailReport = ({ reportId }: DetailReportProps) => { - const [deatils, setDetails] = useState([]); + const [deatils, setDetails] = useState(); - //TODO: API 연결 useEffect(() => { - console.log(reportId); - setDetails(data); + const response = historyDetailAPI(reportId); + response.then((res) => { + setDetails(res); + }); }, []); return ( <> 차량 외부 - {deatils.map((el) => { + {deatils?.externalSummaries.map((el) => { return ( {el.scenarioName} @@ -38,7 +33,7 @@ export const DetailReport = ({ reportId }: DetailReportProps) => { ); })} 차량 내부 - {deatils.map((el) => { + {deatils?.internalSummaries.map((el) => { return ( {el.scenarioName} diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx index b35d6b0..cd9ddc1 100644 --- a/src/components/Note/index.tsx +++ b/src/components/Note/index.tsx @@ -1,57 +1,25 @@ import { PageHeader } from "@components/common/PageHeader"; import { Report } from "./Report"; import styled from "styled-components"; +import { useEffect, useState } from "react"; +import { ReportHistoryType } from "src/types/report"; +import { historyAPI } from "@api/historyAPIS"; -const data = [ - { - reportId: 1, - departuredAt: "2023-07-23T18:51:16.007759", - arrivedAt: "2023-07-23T18:52:44.789957", - mileage: "5.1", - score: "62", - }, - { - reportId: 2, - departuredAt: "2023-10-23T18:51:16.007759", - arrivedAt: "2023-10-23T19:30:44.789957", - mileage: "5.1", - score: "71", - }, - { - reportId: 3, - departuredAt: "2023-07-23T18:51:16.007759", - arrivedAt: "2023-07-23T18:52:44.789957", - mileage: "5.1", - score: "62", - }, - { - reportId: 4, - departuredAt: "2023-10-23T18:51:16.007759", - arrivedAt: "2023-10-23T19:30:44.789957", - mileage: "5.1", - score: "71", - }, - { - reportId: 5, - departuredAt: "2023-07-23T18:51:16.007759", - arrivedAt: "2023-07-23T18:52:44.789957", - mileage: "5.1", - score: "62", - }, - { - reportId: 6, - departuredAt: "2023-10-23T18:51:16.007759", - arrivedAt: "2023-10-23T19:30:44.789957", - mileage: "5.1", - score: "71", - }, -]; export const Note = () => { + const [data, setData] = useState(); + + useEffect(() => { + const response = historyAPI(); + response.then((res) => { + setData(res); + }); + }, []); + return ( - {data.map((el) => { + {data?.map((el) => { return ; })} diff --git a/src/types/driving.ts b/src/types/driving.ts new file mode 100644 index 0000000..037c45e --- /dev/null +++ b/src/types/driving.ts @@ -0,0 +1,20 @@ +/** + * 주행 후 상세 기록 + * /driving/end/${reportID} + */ + +interface ScenarioType { + scenarioType: number; + scenarioName: string; + scenarioCount: number; +} +export interface DrivingEndType { + reportId: number; + departuredAt: string; + arrivedAt: string; + mileage: number; + score: number; + scoreComment: string; + internalSummaries: ScenarioType[]; + externalSummaries: ScenarioType[]; +} diff --git a/tsconfig.json b/tsconfig.json index 71629c8..e68b6f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,8 @@ "@styles/*": ["src/styles/*"], "@pages/*": ["src/pages/*"], "@components/*": ["src/components/*"], - "@utils/*": ["src/utils/*"] + "@utils/*": ["src/utils/*"], + "@api/*": ["src/api/*"] }, /* Bundler mode */