Skip to content

Commit

Permalink
Merge pull request #39 from Step3-kakao-tech-campus/develop
Browse files Browse the repository at this point in the history
[5주차] : 개발 사항 Merge(develop → master)
  • Loading branch information
rktdnjs authored Oct 8, 2023
2 parents 3e12a55 + 4e75bd2 commit 87d54ad
Show file tree
Hide file tree
Showing 42 changed files with 833 additions and 42 deletions.
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

0 comments on commit 87d54ad

Please sign in to comment.