- 서버와 클라이언트에서 Dependencies 다운받기
$ npm install
dev.js
생성
// local에서 작업할 때
module.exports = {
mongoURI:'mongodb+srv://dltmddus1998:MSeungGuri21!@reactredux.4bos1.mongodb.net/myFirstDatabase?retryWrites=true&w=majority'
}
cluster
생성 및 연결- 클러스터 생성 후 데이터베이스 사용자명과 비밀번호를 설정하여
dev.js
에 다음과 같이 복붙하면 된다.
- 클러스터 생성 후 데이터베이스 사용자명과 비밀번호를 설정하여
$ brew install mongosh
$ mongosh "mongodb+srv://reactredux.4bos1.mongodb.net/myFirstDatabase" --username dltmddus1998x
Step1. 비어 있는 업로드 페이지 생성
import React from 'react'
function UploadProductPage() {
return (
<div>
UploadProductPage
</div>
)
}
export default UploadProductPage
Step2. 업로드 페이지 Route 만들기
import React, { Suspense } from 'react';
import { Route, Switch } from "react-router-dom";
import Auth from "../hoc/auth";
// pages for this product
import LandingPage from "./views/LandingPage/LandingPage.js";
import LoginPage from "./views/LoginPage/LoginPage.js";
import RegisterPage from "./views/RegisterPage/RegisterPage.js";
import NavBar from "./views/NavBar/NavBar";
import Footer from "./views/Footer/Footer";
import UploadProductPage from './views/UploadProductPage/UploadProductPage.js';
//null Anyone Can go inside
//true only logged in user can go inside
//false logged in user can't go inside
function App() {
return (
<Suspense fallback={(<div>Loading...</div>)}>
<NavBar />
<div style={{ paddingTop: '69px', minHeight: 'calc(100vh - 80px)' }}>
<Switch>
<Route exact path="/" component={Auth(LandingPage, null)} />
<Route exact path="/login" component={Auth(LoginPage, false)} />
<Route exact path="/register" component={Auth(RegisterPage, false)} />
<Route exact path="/product/upload" component={Auth(UploadProductPage, true)} />
{/* 업로드페이지는 로그인한 사람만 들어갈 수 있으므로 true
path --> /product/upload */}
</Switch>
</div>
<Footer />
</Suspense>
);
}
export default App;
Step3. 업로드 페이지 탭 만들기
/* eslint-disable jsx-a11y/anchor-is-valid */
import React from 'react';
import { Menu } from 'antd';
import axios from 'axios';
import { USER_SERVER } from '../../../Config';
import { withRouter } from 'react-router-dom';
import { useSelector } from "react-redux";
function RightMenu(props) {
const user = useSelector(state => state.user)
const logoutHandler = () => {
axios.get(`${USER_SERVER}/logout`).then(response => {
if (response.status === 200) {
props.history.push("/login");
} else {
alert('Log Out Failed')
}
});
};
// 로그 아웃되어 있는 상태
if (user.userData && !user.userData.isAuth) {
return (
<Menu mode={props.mode}>
<Menu.Item key="mail">
<a href="/login">Signin</a>
</Menu.Item>
<Menu.Item key="app">
<a href="/register">Signup</a>
</Menu.Item>
</Menu>
)
// 로그인 되어있는 상태
} else {
return (
<Menu mode={props.mode}>
{/* upload */}
<Menu.Item key="upload">
<a href="/product/upload">Upload</a>
</Menu.Item>
<Menu.Item key="logout">
<a onClick={logoutHandler}>Logout</a>
</Menu.Item>
</Menu>
)
}
}
export default withRouter(RightMenu);
Step4. Drop Zone을 제외한 Form을 만들기
antd
를 통해 css form을 가져와준다. (좀 더 보기 좋게 하기 위해서)
import React from 'react'
import { Typography, Button, Form, Input } from 'antd';
const { Title } = Typography;
const { TextArea } = Input;
function UploadProductPage() {
return (
<div style={{ maxWidth: '700px', margin: '2rem auto' }}>
<div style={{ textAlign: 'center', marginBottom: '2rem' }}>
<Title level={2}> 여행 상품 업로드 </Title>
</div>
<Form>
{/* DropZone */}
<br />
<br />
<label>이름</label>
<Input value="안녕" />
<br />
<br />
<label>설명</label>
<TextArea />
<br />
<br />
<label>가격</label>
<Input />
<br />
<br />
<select>
<option></option>
</select>
<br />
<br />
<Button>
확인
</Button>
</Form>
</div>
)
}
export default UploadProductPage
Step5. 모든 Input을 위한 onChange Function 만들기
onChange라는 이벤트를 통해서 input의 value 값이 변하도록 해준다.
import React, { useState } from 'react'
import { Typography, Button, Form, Input } from 'antd';
const { TextArea } = Input;
// select --> options
const Continents = [
{ key: 1, value: 'Africa' },
{ key: 2, value: 'Europe' },
{ key: 3, value: 'Asia' },
{ key: 4, value: 'North America' },
{ key: 5, value: 'South America' },
{ key: 6, value: 'Australia' },
{ key: 7, value: 'Antarctica' }
]
function UploadProductPage() {
// state 설정
const [Title, setTitle] = useState("");
const [Description, setDescription] = useState("");
const [Price, setPrice] = useState(0);
const [Continent, setContinent] = useState(1);
const [Images, setImages] = useState([]);
// eventhandler
const titleChangeHandler = (event) => {
// 타이핑을 할때마다 value를 바꿔준다
setTitle(event.currentTarget.value);
}
const descriptionChangeHandler = (event) => {
setDescription(event.currentTarget.value);
}
const priceChangeHandler = (event) => {
setPrice(event.currentTarget.value);
}
const continentChangeHandler = (event) => {
setContinent(event.currentTarget.value);
}
return (
<div style={{ maxWidth: '700px', margin: '2rem auto' }}>
<div style={{ textAlign: 'center', marginBottom: '2rem' }}>
<h2 level={2}> 여행 상품 업로드 </h2>
</div>
<Form>
{/* DropZone */}
<br />
<br />
<label>이름</label>
<Input onChange={titleChangeHandler} value={Title} />
<br />
<br />
<label>설명</label>
<TextArea onChange={descriptionChangeHandler} value={Description} />
<br />
<br />
<label>가격($)</label>
<Input type="number" onChange={priceChangeHandler} value={Price} />
<br />
<br />
<select onChange={continentChangeHandler} value={Continent}>
{/* map을 이용하여 option 표현 */}
{Continents.map(item => (
<option key={item.key} value={item.key}>
{item.value}
</option>
))}
</select>
<br />
<br />
<Button>
확인
</Button>
</Form>
</div>
)
}
export default UploadProductPage