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

[5주차] : 개발 사항 Merge(develop → master) #39

Merged
merged 59 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
ee29d6d
[feat]: 공고 작성 페이지 라우터 지정
baegyeong Sep 30, 2023
5a0e791
Merge branch 'feature/input' into feature/post-write-page
baegyeong Sep 30, 2023
eb01a97
[feat] : LoginNav.jsx 구현
rktdnjs Oct 4, 2023
5b071e1
[feat] : 매칭 여부에 따른 조건부 렌더링 구현
rktdnjs Oct 4, 2023
f7959da
[conf] : tailwind-scrollbar-hide 플러그인 추가
rktdnjs Oct 5, 2023
f4375dc
[feat] : 매칭 여부에 따른 매칭완료 문구 렌더링 구현
rktdnjs Oct 5, 2023
e4d39a3
[style] : Link 태그 static 속성 제거
rktdnjs Oct 5, 2023
32f5f66
[fix]: 버튼 컴포넌트로 변경
baegyeong Oct 5, 2023
66eb4c6
Merge branch 'develop' of https://github.com/Step3-kakao-tech-campus/…
baegyeong Oct 5, 2023
fab8910
Merge branch 'feature/start-post-page' into feature/post-write-page
baegyeong Oct 5, 2023
185d604
[feat]: 메인, 로그인 페이지 외에서 사용하는 nav바 컴포넌트
baegyeong Oct 5, 2023
2442642
[feat]: Line 컴포넌트 구현
baegyeong Oct 7, 2023
a4e35c3
[feat]: 동그라미 버튼 구현
baegyeong Oct 7, 2023
36f9bc5
[feat]: 공고 작성 상단의 navigate 컴포넌트 구현
baegyeong Oct 7, 2023
b07a2c7
[feat]: 공고 작성 하단의 navigate 컴포넌트 구현
baegyeong Oct 7, 2023
a0633a5
[feat] : 메인페이지 구현
kimdanbin Oct 7, 2023
99f2e32
[feat] : 로그인 로직 추가 & 에러 페이지 추가
rktdnjs Oct 7, 2023
1dbfd31
[feat] : LoginNav 컴포넌트 뒤로가기 기능 보완
rktdnjs Oct 7, 2023
b2271b1
[fix]: Input 컴포넌트 width를 prop으로 받기
baegyeong Oct 7, 2023
8abc77d
[fix]: 현재 위치에 따라 색상 다르게 지정
baegyeong Oct 7, 2023
0649a9b
[fix]: onClick 함수를 prop으로 변경
baegyeong Oct 7, 2023
9bb98c4
[fix]: naviate prop에 따라 조건부 렌더링
baegyeong Oct 7, 2023
04f1b5a
[feat]: 작성 페이지에 따라 컴포넌트 생성
baegyeong Oct 7, 2023
2ea6032
[fix]: 작성 폼에 따라 렌더링 되는 컴포넌트 분기
baegyeong Oct 7, 2023
9de7bf1
[feat] : ArticleNav 컴포넌트 구현
rktdnjs Oct 7, 2023
9e10738
[fix]: width 속성 따로 지정
baegyeong Oct 7, 2023
a251eb3
[feat] : 상세페이지로 넘어가는 부분 수정
kimdanbin Oct 7, 2023
1af472f
[fix]: 버튼 넓이, 높이를 상수로 지정
baegyeong Oct 7, 2023
0d10d37
[fix]: 버튼 레이아웃 하단에 정렬
baegyeong Oct 7, 2023
2a1ed26
[style]: 입력폼 margin 지정
baegyeong Oct 7, 2023
6a5ab3a
[style]: 상단 navigate margin 지정
baegyeong Oct 7, 2023
88cd064
[feat] : import부분 수정
kimdanbin Oct 7, 2023
b6ff70f
[feat] : 공고상세페이지 구현
kimdanbin Oct 7, 2023
d60fea0
[feat] : 공고 현황 페이지 레이아웃 구성 & 공고글 렌더링 로직 구현
rktdnjs Oct 7, 2023
41bfdde
[style] : 공고 현황 페이지 좌우 스크롤 적용 및 CSS 수정
rktdnjs Oct 7, 2023
13bf214
[style]: width 등 스타일 변경
baegyeong Oct 7, 2023
699ebaa
[feat]: 여러 줄 입력을 위한 TextArea 컴포넌트 구현
baegyeong Oct 7, 2023
fb8f0f0
[feat]: 아이템 추가, 삭제 버튼 구현
baegyeong Oct 7, 2023
9fa4c1b
[feat]: plus 및 minus 버튼을 molecules 단위의 컴포넌트로 구현
baegyeong Oct 7, 2023
3464422
[fix]: 숫자값 max, min 값 설정
baegyeong Oct 7, 2023
068a8e5
[fix]: input 컴포넌트 추가/삭제를 위한 로직 구현
baegyeong Oct 7, 2023
884bb3d
[fix]: 요청사항 입력을 위해 TextArea 컴포넌트로 수정
baegyeong Oct 7, 2023
b7bd4bc
[fix]: overflow 시 스크롤 위한 속성 지정
baegyeong Oct 7, 2023
24fc830
[fix]: 시간 input max값 변경
baegyeong Oct 7, 2023
8b71567
Merge pull request #23 from rktdnjs/feature/login-nav
rktdnjs Oct 8, 2023
4617317
Merge pull request #25 from rktdnjs/feature/card
rktdnjs Oct 8, 2023
c34770a
Merge pull request #26 from baegyeong/feature/start-post-page
rktdnjs Oct 8, 2023
892eafc
Merge pull request #28 from kimdanbin/feature/home-page
rktdnjs Oct 8, 2023
a97dc6b
Merge branch 'weekly-5' into feature/login-page
rktdnjs Oct 8, 2023
27f4409
Merge pull request #31 from rktdnjs/feature/login-page
rktdnjs Oct 8, 2023
8fe4fdd
Merge branch 'weekly-5' into feature/post-navigate
rktdnjs Oct 8, 2023
0ffe963
Merge pull request #32 from baegyeong/feature/post-navigate
rktdnjs Oct 8, 2023
9658fdb
Merge branch 'weekly-5' into feature/article-page
rktdnjs Oct 8, 2023
7f1cb51
Merge pull request #33 from rktdnjs/feature/article-page
rktdnjs Oct 8, 2023
f3c142a
Merge pull request #35 from kimdanbin/feature/detail-post-page
rktdnjs Oct 8, 2023
9f6f5b8
Merge pull request #36 from baegyeong/feature/post-write-page
rktdnjs Oct 8, 2023
7874706
[refactor] : 5주차 개발 사항 코드 Merge 및 일부 리팩토링
rktdnjs Oct 8, 2023
7a4e816
Merge pull request #37 from rktdnjs/develop
rktdnjs Oct 8, 2023
4e75bd2
Merge pull request #38 from Step3-kakao-tech-campus/weekly-5
rktdnjs Oct 8, 2023
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
21 changes: 21 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 @@ -17,7 +17,9 @@
"react-scripts": "5.0.1",
"react-toastify": "^9.1.3",
"redux": "^4.2.1",
"shortid": "^2.2.16",
"sweetalert2": "^11.7.28",
"tailwind-scrollbar-hide": "^1.1.7",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand Down
15 changes: 13 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import KakaoOuathPage from './pages/KakaoOuathPage';
import StartPostPage from './pages/StartPostPage';
import MyPage from './pages/MyPage';
import PostListPage from './pages/PostListPage';
import PostDetailPage from './pages/PostDetailPage';
import PostWriteIntroPage from './pages/PostWriteIntroPage';
import PostWritePage from './pages/PostWritePage';
import ErrorPage from './pages/ErrorPage';

import './global.css';

function App() {
Expand All @@ -12,7 +18,12 @@ function App() {
<Route path="/" element={<HomePage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/login/kakao" element={<KakaoOuathPage />} />
<Route path="/start-post" element={<StartPostPage />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/post" element={<PostListPage />} />
<Route path="/post/:id" element={<PostDetailPage />} />
<Route path="/post-write-intro" element={<PostWriteIntroPage />} />
<Route path="/post-write" element={<PostWritePage />} />
<Route path="/*" element={<ErrorPage />} />
</Routes>
</BrowserRouter>
);
Expand Down
Empty file removed src/apis/.keep
Empty file.
80 changes: 80 additions & 0 deletions src/apis/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import axios from 'axios';
import Swal from 'sweetalert2';
import { useNavigate } from 'react-router-dom';

const navigate = useNavigate();

// 프론트에서 API를 활용하기 위한 기본 axios 인스턴스
const instance = axios.create({
baseURL: process.env.REACT_APP_API_URL, // production level 에서는 env에서 baseURL을 넣어주어야함(보안 관련)
timeout: 1000, // 타임아웃이 없으면 무한정 wait가 걸려버릴 수 있음
headers: {
'Content-Type': 'application/json', // 서버단에서 JSON 형태를 많이써서, 프론트단에서 쏴줄 때 이러한 형태로 많이 쓴다(헤더 기본 설정)
},
});

// request - 요청
// 아래와 같이 설정해주면 axios 요청시 자동으로 header에 토큰을 넣어서 보내준다.
// 백엔드에서 받아온 JWT Access Token을 request header에 담아서 보내주는 코드
instance.interceptors.request.use((config) => {
const token = localStorage.getItem('accessToken');
if (token) {
// eslint-disable-next-line no-param-reassign
config.headers.Authorization = `${token}`;
}
return config;
});

// response - 응답
// 백엔드로부터 오는 response를 중간에 처리해주는 미들웨어 역할
// 400번대 에러들에 대한 에러 핸들링
// 현재 Swal을 통해 보여주는 알림창의 내용 중 text에 해당하는 내용은 백엔드쪽에서 보내주는 내용에 따라 변경예정
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
// 401 error : 인증되지 않음 - 로그인 화면으로 이동
// token은 백엔드에서 유효하지 않다면 401(Unauthorized) Http code를 보내주기에, 로그인하도록 처리
if (error.response.status === 401) {
Swal.fire({
icon: 'error',
title: '로그인을 진행해주세요!',
text: error.response.data.error.message,
confirmButtonText: '확인',
}).then(() => {
navigate('/login');
// window.location.href = '/login';
});
return Promise.reject(error);
}

// 404 error : 지정한 리소스를 찾을 수 없음
// 에러 메시지를 띄워주고 & 잘못된 경로로 이동 시 ErrorPage로 이동
if (error.response.status === 404) {
Swal.fire({
icon: 'error',
title: '아이쿠! 에러가 발생했네요😅',
text: error.response.data.error.message,
confirmButtonText: '확인',
}).then(() => {
navigate('/errorPage');
// window.location.href = '/errorPage';
});
return Promise.reject(error);
}

// 401, 404 외의 다른 error에 대한 처리 및 에러 메시지 확인 가능
Swal.fire({
icon: 'error',
title: '내용을 다시 확인해 주세요!',
text: error.response.data.error.message,
confirmButtonText: '확인',
});
// 성공인지 실패인지 여부에 따라 resolve, reject 처리
// response를 제대로 받아도 만약 특정 데이터가 없을때 에러로 처리하고 싶다면 reject 처리
return Promise.reject(error);
},
);

export default instance;
Binary file added src/assets/images/postWrite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/components/atoms/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ const Button = ({
onClick,
disabled,
children,
margin,
width = 'w-64',
height = 'h-8',
bgColor = 'bg-blue-600',
bgColor = 'bg-blue',
textColor = 'text-white',
bdRadius = 'rounded-lg',
}) => {
Expand All @@ -16,7 +17,7 @@ const Button = ({
type={type || 'button'}
onClick={onClick}
disabled={disabled}
className={`${width} ${height} ${textColor} ${bgColor} ${bdRadius}`}
className={`${width} ${height} ${textColor} ${bgColor} ${bdRadius} ${margin}`}
>
{children}
</button>
Expand Down
26 changes: 20 additions & 6 deletions src/components/atoms/Card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,42 @@ const Card = ({
pickupLocation = '픽업 위치',
pickupTip = 3000,
deadline = 1696992289,
match = false,
to = './',
}) => {
const arrowColor = {
color: match ? '#555555' : '#8B8B8B',
};

return (
<Link to={to}>
<div className="w-80 h-20 rounded-xl border-[#8B8B8B] border my-4 py-2 px-3 flex justify-between">
<div
className={`w-80 h-20 rounded-xl border-[#8B8B8B] border m-auto my-[15px]
${match ? 'bg-[#000000]/50' : ''}`}
>
<Link to={match ? './' : to} className={`flex justify-between py-2 px-3 ${match ? 'cursor-default' : ''}`}>
<div>
<div className="flex items-center">
<MdOutlineLocationOn className="mr-1" style={{ color: '#0075FF' }} />
{orderLocation}
</div>
<BsArrowDown style={{ color: '8B8B8B' }} />
<BsArrowDown style={arrowColor} />
<div className="flex items-center">
<MdLocationPin className="mr-1" style={{ color: '#0075FF' }} />
{pickupLocation}
</div>
</div>
<div className="flex flex-col">
<div className="grid justify-items-end text-[1rem] font-bold">{`${comma(pickupTip)}원`}</div>
<div className="grid justify-items-end text-[0.5rem] text-[#FF0000]">{date(deadline)}</div>
<div
className={`grid justify-items-end text-[0.5rem]
${match ? 'text-[#000]' : 'text-[#FF0000]'} `}
>
{date(deadline)}
</div>
</div>
</div>
</Link>
</Link>
{match ? <div className="text-[#fff] relative bottom-[50px] left-[130px] font-medium">매칭완료</div> : ''}
</div>
);
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/atoms/Input.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const Input = ({ type, value, name, placeholder, ...inputProps }) => {
const Input = ({ type, value, name, placeholder, width = 'w-[18rem]', ...inputProps }) => {
return (
<input
type={type}
name={name}
value={value}
placeholder={placeholder}
{...inputProps}
className="w-[20rem] rounded-xl border-gray-300 border-2 px-5 py-2 text-sm block my-4"
className={`${width} rounded-lg border-gray-300 border-2 px-5 py-2 text-sm block my-2`}
/>
);
};
Expand Down
5 changes: 5 additions & 0 deletions src/components/atoms/Line.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Line = () => {
return <hr className="h-0.5 w-[15rem] bg-gray-400 border-0" />;
};

export default Line;
24 changes: 24 additions & 0 deletions src/components/atoms/LoginNav.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { BsArrowLeft } from 'react-icons/bs';
import { MdHome } from 'react-icons/md';
import { Link, useNavigate } from 'react-router-dom';

const LoginNav = () => {
const navigate = useNavigate();
const goPreviousPage = () => {
navigate(-1); // 바로 이전 페이지로 이동
};

return (
<div>
<div className="flex justify-between p-[25px] ">
<BsArrowLeft className="cursor-pointer" onClick={goPreviousPage} size={25} />
<Link to="/">
<MdHome size={25} />
</Link>
</div>
</div>
);
};

export default LoginNav;
7 changes: 7 additions & 0 deletions src/components/atoms/MinusBtn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PiMinus } from 'react-icons/pi';

const MinusBtn = ({ className, onClick }) => {
return <PiMinus onClick={onClick} className={`text-slate-400 cursor-pointer ${className}`} />;
};

export default MinusBtn;
6 changes: 3 additions & 3 deletions src/components/atoms/Nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import logo from '../../assets/images/logo.png';
const Nav = () => {
return (
<div>
<nav className="absolute h-16 p-5 mt-1 top-0 left-0 right-0 flex justify-between items-center">
<nav className="absolute h-16 p-5 top-0 left-0 right-0 flex justify-between items-center">
<Link to={'/'}>
<div>
<img src={logo} className="float-left" size={35} />
Expand All @@ -21,10 +21,10 @@ const Nav = () => {
</Link>
</nav>
<div className="absolute h-12 p-5 top-16 left-0 right-0 flex items-center">
<Link to={'/start-post'}>
<Link to={'/post-write-intro'}>
<div className="p-1">공고작성</div>
</Link>
<Link to={'/articles'}>
<Link to={'/post'}>
<div className="pl-3">공고현황</div>
</Link>
</div>
Expand Down
30 changes: 30 additions & 0 deletions src/components/atoms/OtherNav.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { BsArrowLeft } from 'react-icons/bs';
import { BiSolidUser } from 'react-icons/bi';
import { MdHome } from 'react-icons/md';
import { Link, useNavigate } from 'react-router-dom';

const OtherNav = ({ iconColor = '#000', bgColor = 'bg-[#FFF]' }) => {
const navigate = useNavigate();
const goPreviousPage = () => {
navigate(-1); // 바로 이전 페이지로 이동
};

return (
<div>
<div className={`flex justify-between p-[25px] ${bgColor}`}>
<BsArrowLeft className="cursor-pointer" onClick={goPreviousPage} size={25} color={iconColor} />
<div className="flex">
<Link className="mr-4" to="/">
<MdHome size={25} color={iconColor} />
</Link>
<Link to="/mypage">
<BiSolidUser size={25} color={iconColor} />
</Link>
</div>
</div>
</div>
);
};

export default OtherNav;
7 changes: 7 additions & 0 deletions src/components/atoms/PlusBtn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { BsPlusLg } from 'react-icons/bs';

const PlusBtn = ({ className, onClick }) => {
return <BsPlusLg size={20} onClick={onClick} className={`text-slate-400 cursor-pointer ${className}`} />;
};

export default PlusBtn;
4 changes: 2 additions & 2 deletions src/components/atoms/SelectInput.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import cafe from '../../constant/cafe';

const SelectInput = ({ type, value, name, placeholder, width = '20rem', sort = cafe, ...inputProps }) => {
const SelectInput = ({ type, value, name, placeholder, width = 'w-[18rem]', sort = cafe, ...inputProps }) => {
return (
<select
type={type}
name={name}
value={value}
placeholder={placeholder}
{...inputProps}
className={`w-[${width}] rounded-xl border-gray-300 border-2 px-5 py-2 text-sm block my-4`}
className={`${width} rounded-lg border-gray-300 border-2 px-5 py-2 text-sm block my-2`}
>
{sort.map((item) => (
<option key={item} value={item}>
Expand Down
14 changes: 14 additions & 0 deletions src/components/atoms/TextArea.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const TextArea = ({ placeholder, id, ...inputProps }) => {
return (
<textarea
type="text"
rows="3"
id={id}
className="w-[18rem] rounded-lg border-gray-300 border-2 px-5 py-2 text-sm block my-4"
placeholder={placeholder}
{...inputProps}
/>
);
};

export default TextArea;
Loading