Skip to content

Commit 4ac7087

Browse files
authored
Merge pull request #65 from grimza99/React-유선향-sprint7
[유선향]-sprint7
2 parents b5788a7 + 12d3a0a commit 4ac7087

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1270
-317
lines changed

package-lock.json

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"@testing-library/jest-dom": "^5.17.0",
77
"@testing-library/react": "^13.4.0",
88
"@testing-library/user-event": "^13.5.0",
9+
"axios": "^1.7.9",
910
"firebase": "^11.1.0",
1011
"lodash.throttle": "^4.1.1",
1112
"react": "^18.2.0",

src/Hooks/useAutoClose.jsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useState, useEffect, useRef } from "react";
2+
3+
export function useAutoClose(initialState) {
4+
const [isOpen, setIsOpen] = useState(initialState);
5+
const ref = useRef(null);
6+
7+
const handleOutsideClick = (e) => {
8+
if (ref.current && !ref.current.contains(e?.target)) {
9+
setIsOpen(false);
10+
}
11+
};
12+
13+
useEffect(() => {
14+
document.addEventListener("click", handleOutsideClick, true);
15+
return () => {
16+
document.removeEventListener("click", handleOutsideClick, true);
17+
};
18+
}, []);
19+
20+
return { ref, isOpen, setIsOpen };
21+
}

src/Hooks/useFormatting.jsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export function useFormatDate(data) {
2+
const date = new Date(data);
3+
const formattedDate = `${date.getFullYear()}.${String(
4+
date.getMonth() + 1
5+
).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}`;
6+
return formattedDate;
7+
}
8+
9+
export const useFormatPrice = (data, currency = "KRW") => {
10+
if (typeof data !== "number") return "가격 정보 없음";
11+
return data.toLocaleString("ko-KR", {
12+
style: "decimal",
13+
currency: currency,
14+
});
15+
};
16+
17+
export const useFormatUpDate = (timestamp) => {
18+
const now = new Date();
19+
const past = new Date(timestamp);
20+
const diff = (now - past) / 1000;
21+
22+
if (diff < 60) {
23+
return "1분전";
24+
} else if (diff < 3600) {
25+
return `${Math.floor(diff / 60)}분 전`; // 1시간 미만
26+
} else if (diff < 86400) {
27+
return `${Math.floor(diff / 3600)}시간 전`; // 24시간 미만
28+
} else if (diff < 30 * 86400) {
29+
return `${Math.floor(diff / 86400)}일 전`; // 30일 미만
30+
} else {
31+
return past.toISOString().split("T")[0]; // YYYY-MM-DD 형식 (한 달 이상 지난 경우)
32+
}
33+
};

src/Main.jsx

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { Route, BrowserRouter, Routes } from "react-router-dom";
2+
import { createGlobalStyle } from "styled-components";
3+
//
4+
import LandingPage from "./pages/LandingPage/LandingPage.jsx";
5+
import App from "./App.js";
6+
import HomePage from "./pages/HomePage/HomePage.jsx";
7+
import AddItem from "./pages/AddItem/AddItem.jsx";
8+
import Product from "./pages/ProductPage/Product.jsx";
9+
import Test from "./components/TestPage.jsx";
10+
//
11+
//
12+
const GlobalStyle = createGlobalStyle`
13+
* {
14+
box-sizing: border-box;
15+
}
16+
body {
17+
font-family: 'Pretendard', sans-serif;
18+
font-display: swap;
19+
margin: 0;
20+
padding: 0;
21+
}
22+
html {
23+
margin: 0;
24+
padding: 0;
25+
}
26+
a {
27+
text-decoration: none;
28+
color: #ffffff;
29+
}
30+
p{
31+
margin: 0px;
32+
}
33+
@font-face {
34+
font-family: 'Pretendard';
35+
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff2') format('woff2');
36+
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') format('woff');
37+
font-display: swap;
38+
font-weight: 400;
39+
font-style: normal;
40+
}
41+
42+
@font-face {
43+
font-family: "Pretendard";
44+
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Bold.woff2') format('woff2');
45+
src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Bold.woff') format('woff');
46+
font-display: swap;
47+
font-weight: 600;
48+
font-style: normal;
49+
}
50+
`;
51+
//
52+
function Main() {
53+
return (
54+
<>
55+
<GlobalStyle />
56+
<BrowserRouter>
57+
<Routes>
58+
<Route path="/" element={<LandingPage />} />
59+
<Route element={<App />}>
60+
<Route path="/test" element={<Test />} />
61+
<Route path="/items" element={<HomePage />} />
62+
<Route path="/items/:productId" element={<Product />} />
63+
<Route path="/additem" element={<AddItem />} />
64+
</Route>
65+
</Routes>
66+
</BrowserRouter>
67+
</>
68+
);
69+
}
70+
export default Main;

src/api/comment.api.jsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import axios from "axios";
2+
const BASE_URL = "https://panda-market-api.vercel.app";
3+
4+
export async function getProductComments(productId, limit = 3) {
5+
try {
6+
const res = await axios.get(
7+
`${BASE_URL}/products/${productId}/comments?limit=${limit}`
8+
);
9+
if (!res) {
10+
throw new Error("리뷰 불러오기 실패");
11+
}
12+
return res.data;
13+
} catch (error) {
14+
console.error(error);
15+
return null;
16+
}
17+
}

src/api.js renamed to src/api/product.api.jsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import axios from "axios";
12
const BASE_URL = "https://panda-market-api.vercel.app";
23

34
export async function getProducts({
@@ -28,3 +29,14 @@ export async function bestProducts({ device }) {
2829
const body = await response.json();
2930
return body;
3031
}
32+
33+
export async function getProductInfo(productId) {
34+
try {
35+
const response = await axios.get(`${BASE_URL}/products/${productId}`);
36+
if (!response) throw new Error("제품정보 get api 실패");
37+
return response.data;
38+
} catch (error) {
39+
console.error(error, "제품정보 api 실패");
40+
return null;
41+
}
42+
}

src/assets/btn_sort.svg

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/assets/favoriteLogo.svg

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)