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

[배진한] Sprint6 #106

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b18bea8
FE sprint6 폴더 복사 완료.
Jin-coding-333 Nov 2, 2024
1158054
default 이미지 추가
Jin-coding-333 Nov 2, 2024
60663f2
ItemsPage 좋아요순 기능 제거
Jin-coding-333 Nov 2, 2024
d5edfb1
ItemsPage 디폴트 이미지 추가
Jin-coding-333 Nov 2, 2024
cdaa889
리액트 프론트 엔드 sprint6 제출용
Jin-coding-333 Nov 3, 2024
e640883
.gitignore 파일 루트 위치로 이동.
Jin-coding-333 Nov 4, 2024
dc93760
AddItemspage 이름 RegisterItempage로 바꾸고 페이지 내 컴포넌트화 준비 완료
Jin-coding-333 Nov 5, 2024
8abd02f
ProdNameInputBox와 ProdDescriptionInputBox 컴포넌트화 마침
Jin-coding-333 Nov 5, 2024
d0a5435
모든 input box padding 값 약간 바꿈
Jin-coding-333 Nov 5, 2024
e529c9b
RegisterItemPage 내 컴포넌트화 마침
Jin-coding-333 Nov 5, 2024
aba7054
post용 api 생성 및 getproduct용 api.js 파일 이름 변경, 내 mongoDB에 post한 데이터 들어간 …
Jin-coding-333 Nov 5, 2024
613f1e4
RegisterItemPage, input value 값 하나의 state로 관리, 그대로 post 값으로 넣음.
Jin-coding-333 Nov 5, 2024
ae1e1f3
RegisterItemPage, 상품명 심화 요구 사항 완료
Jin-coding-333 Nov 5, 2024
cfb9281
RegisterItemPage, 상품 소개 validation 완료
Jin-coding-333 Nov 5, 2024
fef668b
RegisterPage, price 인풋 박스 validation 완료
Jin-coding-333 Nov 5, 2024
69d3100
태그 생성 시키고 그 값들을 post하는 것 빼고는 웬만한 것은 다함.
Jin-coding-333 Nov 5, 2024
c3e1cf4
태그 길이에 따른 regisetButton 활성화 여부 반영
Jin-coding-333 Nov 6, 2024
4a21f72
멘토링 수정 사항 반영
Jin-coding-333 Nov 9, 2024
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
428 changes: 428 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

18,282 changes: 18,282 additions & 0 deletions sprint6/package-lock.json

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions sprint6/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "sprint5",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.27.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
15 changes: 15 additions & 0 deletions sprint6/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="ko">

<head>
<meta charset="utf-8" />
<link rel="icon" href="../src/img/icons/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>중고마켓</title>
</head>

<body>
<div id="root" class="dk"></div>
</body>

</html>
25 changes: 25 additions & 0 deletions sprint6/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions sprint6/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
23 changes: 23 additions & 0 deletions sprint6/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import ItemsPage from './pages/ItemsPage/index.jsx';
import HomePage from './pages/HomePage/index.jsx';
import LoginPage from './pages/LoginPage/index.jsx';
import RegisterItemPage from './pages/RegisterItemPage/index.jsx';
import ItemDetailPage from './pages/ItemDetailPage/index.jsx';

function App() {
return (
<BrowserRouter >
<Routes>
<Route path='/' element={<HomePage />} />
<Route path='/items' element={<ItemsPage />} />
<Route path='/login' element={<LoginPage />} />
<Route path='/register' element={<RegisterItemPage />} />
<Route path='/itemDetail' element={<ItemDetailPage />} />
{/* <Route path='/community' element={<CommunityFeedPage />} /> */}
</Routes>
</BrowserRouter>
);
}

export default App;
3 changes: 3 additions & 0 deletions sprint6/src/api/endpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const url = new URL('https://panda-market-api.vercel.app/products');
// export const url = new URL('http://localhost:8000/products');
export const postUrl = 'http://localhost:8000/products';
Copy link
Collaborator

Choose a reason for hiding this comment

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

로컬 전용으로 만드셨네요, 좋습니다. 그런데 이걸 배포해야 할때는 어떻게 해야할까요? 한번 생각해보세요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아 배포 할 때 제 백엔드 서버를 배포했다면 그 url을 적용 시켜야 할 것 같습니다.
localhost는 배포를 해도 다른 컴퓨터에서 응답을 안 하겠네요

Copy link
Collaborator

Choose a reason for hiding this comment

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

맞습니다. 우선 그 부분 인지하고 있으시다면 문제 없겠습니다.

복잡하실테니 대표적으로 두가지 경우를 미리 알려드릴게요

  1. 백엔드주소가 바뀔 때마다 저 값을 수동으로 바꿔 배포하기
  2. 환경변수에 넣고, 빌드시에 빌드 런타임인 node.js가 process.env를 읽어서 저 값을 채우게 하기
    이렇게 하는 방법들이 있습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

네 일단 확인만 하고 넘어가겠습니다.

16 changes: 16 additions & 0 deletions sprint6/src/api/getProductsApi.js
orlein marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { url } from './endpoint.js';

async function getProducts(params = "") {
const query = new URLSearchParams(params).toString();
Copy link
Collaborator

Choose a reason for hiding this comment

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

new URLSearchParams(params) 인데, params의 기본 타입은 any[] 입니다. 그런데 한번 이 타입으로 실제로 실행해보시면, URLSearchParams의 constructor에는 [name, value] tuple이 iterable해야한다는 설명이 나옵니다.

TypeError [ERR_INVALID_TUPLE]: Each query pair must be an iterable [name, value] tuple

설명이 상당히 어려워보이지만, 간단합니다. 그저 [이름, 값] 들이 반복하여 들어가야한다는 겁니다. 예를 들어,
new URLSearchParams([['key1', 'hello'], ['key2', 'world']])
이렇게 되어야 정상이라는거죠. 그러면 이런식으로 쓰고 있을까요? 그렇지않습니다.

sprint6/src/pages/ItemsPage/index.jsx의 PRODS_LIST는 string입니다. 물론, string이 query로 파싱 가능한 형태이기 때문에 잘 동작은 합니다만, 그렇다면 getProducts의 parameter인 params에는 어떻게 설명이 되어야할까요?
제 답은, argument를 string으로 쓰고 있다면 string으로 초기화해둘 것 이 정답이라고 봅니다. TypeScript라면 다른 답이 있지만, JavaScript에서는 이게 최선의 답으로 보이네요.

jsdoc으로 예제를 몇개 달아두는것도 좋습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아래와 같이 하라고 하신 걸까요?
image

Copy link
Collaborator

Choose a reason for hiding this comment

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

params가 new URLSearchParams의 constructor로 들어가기 전에, 들어가도 되는지 체크하는 로직이 위에 있는게 최선이지만,
저는 차선책으로 params = '' 하시는 편을 고려했었습니다.
왜냐면 위에서는 params = [] 로 하셨기때문에, 이 해결책을 더 선호하시리라 생각한거죠...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

네 일단 차선책으로 수정 해 놓겠습니다!

// 파라미터를 자동으로 정리해서 인코딩

try {
const response = await fetch(`${url}?${query}`);
const data = await response.json();
return data
} catch (err) {
console.error('Fetch error:', err);
}
}

export default getProducts;
14 changes: 14 additions & 0 deletions sprint6/src/api/postProductApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from 'axios';
import { postUrl } from './endpoint.js';

const postProduct = async (surveyData) => {
if (typeof surveyData === 'object') {
const res = await axios.post(postUrl, surveyData);
return res.data;
} else {
console.error('Post error:');
return;
}
}

export default postProduct;
81 changes: 81 additions & 0 deletions sprint6/src/components/Footer/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
footer {
width: 100%;
height: 16rem;
background-color: #111827;
display: flex;
justify-content: center;
padding-top: 3.2rem;
}

#footerContent {
width: 152rem;
height: 2rem;
display: flex;
justify-content: space-between;
margin-left: 20rem;
margin-right: 20rem;
}

#copyright {
width: 12.2rem;
height: 1.9rem;
font-size: 1.6rem;
font-weight: 400;
line-height: 1.909rem;
display: flex;
text-align: center;
color: #9CA3AF;
}

#info {
width: 16.9rem;
height: 1.9rem;
gap: 3rem;
opacity: 0rem;
font-size: 1.6rem;
font-weight: 400;
line-height: 1.909rem;
text-align: center;
color: #E5E7EB;
display: flex;
justify-content: space-between;
}

#info a {
text-decoration: none;
color: #E5E7EB;
}
Comment on lines +10 to +47
Copy link
Collaborator

Choose a reason for hiding this comment

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

css에 id를 쓰셔야만 하는 이유가 있으셨을까요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

그렇게 큰 이유는 없습니다..ㅎ
미디어 쿼리를 처음 적용해보다 보니 원하지 않은 css 스타일이 중복하여 입혀지기도 하고
애를 먹으면서 그냥 선택을 명확하게 하려 하다보니 그렇게 됐던 것 같습니다.
웬만하면 클래스 선택자를 쓰는 게 좋다고 하셨었죠?
앞으로 참고하겠습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

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

id를 써야만 한다면 id가 있는 DOM은 유일해야만 합니다. 그런 이유가 있다면 쓸만합니다.
그래서 그 의도를 더 여쭤본거구요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아 네 다음부터는 인식해서 쓰겠습니다!


#socialIcons {
list-style: none;
padding-left: 0rem;
margin-left: 1.6rem;
display: flex;
justify-content: space-between;
}

#socialIcons img {
width: 2rem;
height: 2rem;
margin-right: 1.2rem;
filter: drop-shadow(0 0 0.75rem rgba(0, 0, 0, 15%));
}

@media (max-width: 474px) {

#copyright {
position: relative;
bottom: -40px;
}

#footerContent {
margin-left: 21px;
margin-right: 0rem;
}

#info {
width: 156.9px;
position: relative;
left: -127px;
}
}
29 changes: 29 additions & 0 deletions sprint6/src/components/Footer/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import faceBookImg from '../../img/social/ic_facebook.png';
import twitterImg from '../../img/social/ic_twitter.png';
import youtubeImg from '../../img/social/ic_youtube.png';
import instagramImg from '../../img/social/ic_instargram.png';
import './index.css';

function Footer() {
return (
<footer>
<div id="footerContent">
<div id="copyright">© Codeit 2024</div>

<div id="info">
<div><a href="/privacy">Privacy Policy</a></div>
<div id='faq'><a href="/faq">FAQ</a></div>
</div>

<div id="socialIcons">
<a href="https://www.facebook.com/?locale=ko_KR"><img src={faceBookImg} alt="Facebook" /></a>
<a href="https://x.com/?lang=ko"><img src={twitterImg} alt="Twitter" /></a>
<a href="https://www.youtube.com/"><img src={youtubeImg} alt="YouTube" /></a>
<a href="https://www.instagram.com/sem/campaign/emailsignup"><img src={instagramImg} alt="Instagram" /></a>
</div>
</div>
</footer>
)
}

export default Footer;
Loading