Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[장용한] Sprint11 #317

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@tanstack/react-query": "^5.52.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.104",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"axios": "^1.7.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.25.1",
Expand Down
46 changes: 46 additions & 0 deletions src/API/AuthAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import axios from "axios";

interface valuetype {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valueType 보다 어떤 value인지 좀 더 명확하게 해주시면 좋을 것 같아요 !

email: string;
nickname?: string;
password: string;
passwordConfirmation?: string;
}

const apiUrl = process.env.REACT_APP_API_BASE_URL as string;

export const postAuthSignIn = async (body: valuetype) => {
try {
const res = await axios.post(`${apiUrl}/auth/signIn`, body, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 부분은 axios instance로 미리 설정 할 수 있겠죠 !

headers: {
"Content-Type": "application/json",
},
});
return res.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("Axios error:", error.response?.data);
} else {
console.error("Unknown error:", error);
}
throw error;
}
};

export const postAuthSignUp = async (body: valuetype) => {
try {
const res = await axios.post(`${apiUrl}/auth/signUp`, body, {
headers: {
"Content-Type": "application/json",
},
});
return res.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("Axios error:", error.response?.data);
} else {
console.error("Unknown error:", error);
}
throw error;
}
};
9 changes: 5 additions & 4 deletions src/API/CommentsAPI.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
interface comment {
images: string;
nickname: string;
id: number;
name: string;
content: string;
createdAt: string;
images: string;
nickname: string;
updatedAt: number;
}

interface commentList {
interface commentResponse {
list: comment[];
nextCursor: number;
}

export async function getComments(
productId = 9,
limit = 5
): Promise<commentList> {
): Promise<commentResponse> {
const path = `/products/${productId}/comments?`;
const query = `limit=${limit}`;
const response = await fetch(
Expand Down
4 changes: 2 additions & 2 deletions src/API/ItemAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ interface Produect {
tags: string;
}

interface ProduectList {
interface ProduectResponse {
list: Produect[];
}

export async function getProducts(
pageSize = 10,
orderBy = "recent"
): Promise<ProduectList> {
): Promise<ProduectResponse> {
const query = `pageSize=${pageSize}&orderBy=${orderBy}`;
const response = await fetch(
`https://panda-market-api.vercel.app/products?${query}`
Expand Down
14 changes: 10 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,30 @@ import HomePage from "./pages/HomePage/HomePage.tsx";
import AddItemPage from "./pages/AddItemPage/AddItemPage.tsx";
import MarketPage from "./pages/MarketPage/MarketPage.tsx";
import ProductDetail from "./pages/MarketPage/components/ProductDetail.tsx";
import LoginPage from "./pages/LoginPage/LoginPage.tsx";
import SignUp from "./pages/LoginPage/Signup.tsx";

import { ItemProvider } from "../src/context/ItemContext.tsx";
import { ProductProvider } from "./context/ProductContext.tsx";
import CommunityFeedPage from "./pages/CommunityFeedPage/CommunityFeedPage.tsx";

function App() {
return (
<ItemProvider>
<ProductProvider>
<BrowserRouter>
<div>
<Header />
<Routes>
<Route index element={<HomePage />} />
<Route path="items" element={<MarketPage />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/items" element={<MarketPage />} />
<Route path="/additem" element={<AddItemPage />} />
<Route path="/community" element={<CommunityFeedPage />} />
<Route path="/product/:id" element={<ProductDetail />} />
</Routes>
</div>
</BrowserRouter>
</ItemProvider>
</ProductProvider>
);
}

Expand Down
2 changes: 2 additions & 0 deletions src/Layout/Header.css → src/Layout/Header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
list-style-type: none;
font-size: 18px;
font-weight: 700;
text-decoration-line: none;
color: #000000;
}

@media (max-width: 768px) {
Expand Down
80 changes: 53 additions & 27 deletions src/Layout/Header.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts

nextjs layout을 이용해서 조건부 렌더링보다는 nextjs 스러운 방식으로 Header를 구성해보시는게 어떨 까요?

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Logo from "../images/logo/logo.svg";
import "./Header.css";
import { NavLink, useLocation } from "react-router-dom";
import style from "./Header.module.css";
import { Link, NavLink, useLocation } from "react-router-dom";
import loginIMage from "../images/logo/ic_profile.svg";

interface GetLinkStyleProps {
isActive: boolean;
Expand All @@ -16,31 +17,56 @@ export function getLinkStyle({ isActive }: GetLinkStyleProps) {
const Header = () => {
const location = useLocation();

return (
<header className="mainHeader">
<div className="leftHeader">
<img className="headerLogo" src={Logo} alt="판다마켓로고" />
<nav>
<ul className="headusedmarket">
<li className="usedmarket">자유게시판</li>
<li className="usedmarket">
<NavLink
to="/items"
style={({ isActive }) =>
location.pathname === "/additem" || isActive
? { color: "#3692ff", textDecoration: "none" }
: {}
}
>
중고마켓
</NavLink>
</li>
</ul>
</nav>
</div>
<div className="loginbutton">로그인</div>
</header>
);
const isLogIn = localStorage.getItem("accessToken");

switch (location.pathname) {
case "/login":
case "/signup":
return null;

default:
return (
<header className={style.mainHeader}>
<div className={style.leftHeader}>
<Link to={"/"}>
<img className={style.headerLogo} src={Logo} alt="판다마켓로고" />
</Link>
<nav>
<ul className={style.headusedmarket}>
<NavLink
className={style.usedmarket}
to="/community"
style={({ isActive }) =>
isActive ? { color: "#3692ff", textDecoration: "none" } : {}
}
>
<li>자유게시판</li>
</NavLink>

<NavLink
className={style.usedmarket}
to="/items"
style={({ isActive }) =>
location.pathname === "/additem" || isActive
? { color: "#3692ff", textDecoration: "none" }
: {}
}
>
<li>중고마켓</li>
</NavLink>
</ul>
</nav>
</div>
{isLogIn ? (
<img src={loginIMage} alt="로그인이미지" />
) : (
<Link to="/login" className={style.loginbutton}>
로그인
</Link>
)}
</header>
);
}
};

export default Header;
14 changes: 9 additions & 5 deletions src/Layout/UI/FileInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ function FileInput({ name, value, onChange }: FileInputProps) {
const inputRef = useRef<HTMLInputElement>(null);

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const nextValue = e.target.files ? e.target.files[0] : null;
const nextValue =
e.target.files && e.target.files.length > 0 ? e.target.files[0] : null;
onChange(name, nextValue);
};

Expand All @@ -40,18 +41,21 @@ function FileInput({ name, value, onChange }: FileInputProps) {

return (
<div className="fileInput-container">
<img src={preview} alt="" className="inputImage" />
<input
id="imgFile"
type="file"
accept="image/png, image/jpeg"
onChange={handleChange}
ref={inputRef}
/>

{value && (
<button onClick={handleClearClick} className="button">
<img src={xbutton} alt="취소버튼" />
</button>
<>
<button onClick={handleClearClick} className="button">
<img src={xbutton} alt="취소버튼" />
</button>
<img src={preview} alt="" className="inputImage" />
</>
)}
</div>
);
Expand Down
12 changes: 8 additions & 4 deletions src/context/ItemContext.tsx → src/context/ProductContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ interface Product {
tags: string;
}

interface ItemProviderPropt {
interface ProductProviderPropt {
children: ReactNode;
}

export const ItemContext = createContext<Product[]>([]);
export const ProductContext = createContext<Product[]>([]);

export const ItemProvider: React.FC<ItemProviderPropt> = ({ children }) => {
export const ProductProvider: React.FC<ProductProviderPropt> = ({
children,
}) => {
const [itemList, setItemList] = useState<Product[]>([]);

useEffect(() => {
Expand All @@ -34,6 +36,8 @@ export const ItemProvider: React.FC<ItemProviderPropt> = ({ children }) => {
}, []);

return (
<ItemContext.Provider value={itemList}>{children}</ItemContext.Provider>
<ProductContext.Provider value={itemList}>
{children}
</ProductContext.Provider>
);
};
Binary file added src/images/icons/PropertyDefault.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/PropertyVariant.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/google_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/ic_facebook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/ic_instagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/ic_twitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/ic_youtube.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/icons/kakao_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/Img_home_bottom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/Img_home_top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/home1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/home2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/home3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/logo1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/logo2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/logo3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/메타태그이미지.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/image/판다마켓.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading