NODE.JS
Youtube 만들기 - 2) 비디오 업로드 Form 만들기 1
dodop
2021. 5. 14. 09:37
이와같은 비디오를 업로드하는 페이지 형식을 만들 것이다.
우선 client>components>views>VideoUploadPage>VideoUploadPage.js를 만든다
그 후 App.js에 route를 생성해준다.
여기서 null은 아무나 다 입장가능하고, false는 로그인한사람은 못들어가고, true는 로그인한사람만 들어갈 수 있다.
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";
//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="/video/upload" component={Auth(VideoUploadPage, true)} />
</Switch>
</div>
<Footer />
</Suspense>
);
}
export default App;
오른쪽 헤더부분에도 업로드버튼을 생성하자.
Navbar>sections>right menu.js로 들어간다
/* 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}>
<Menu.Item key="upload">
<a href="/video/upload">Video</a>
</Menu.Item>
<Menu.Item key="logout">
<a onClick={logoutHandler}>Logout</a>
</Menu.Item>
</Menu>
)
}
}
export default withRouter(RightMenu);
다시 videoupload페이지에서 다음과 같은 코드를 추가한다.
디자인은 antd에서 가져와서 사용한다.
import React, {useState} from 'react'
import {Typography, Button, Form, message, Input, Icon } from 'antd';
function VideoUploadPage(props) {
return (
<div style = {{ maxWidth : '700px', margin:'2rem auto'}}>
<div style={{textAlign:'center', marginBottom:'2rem'}}>
<Title level = {2}>Upload Video</Title>
</div>
<Form onSubmit={onSubmit}>
<div style={{display:'flex', justifyContent:'space-between'}}>
{/* Drop zone */}
{/* Thumbnail (thumbnailPath가 있을 때에만 작동 */}
</div>
<br/>
<br/>
<label >Title</label>
<Input
onChange = {onTitleChange}
value = {VideoTitle}
/>
<br/>
<br/>
<label >Description</label>
<TextArea
onChange = {onDescriptionChange}
value = {Description}
/>
<br/>
<br/>
<select onChange={onPrivateChange}>
))}
</select>
<br/>
<br/>
<select onChange={onCategoryChange}>
))}
</select>
<br/>
<br/>
<Button type="primary" size = "large" onClick={onSubmit}>
Submit
</Button>
</Form>
</div>
)
}
export default VideoUploadPage
우리는 동영상을 가져올 때 drop해서 가져올 수 있도록 react dropzone을 사용할 것이다.
이를 가져오기 위해서 client에 npm install react-dropzone --save를 한다.
그 후 코드에 dropzone 부분을 생성한다.
import Dropzone from 'react-dropzone';
{/* Drop zone */}
<Dropzone
onDrop = {onDrop}
multiple = {false} //한번에 올리는 파일 갯수
maxSize = {100000000}>
{({getRootProps, getInputProps})=>(
<div style={{ width:'300px', height:'240px', border:'1px solid lightray', display:'flex',
alignItems:'center', justifyContent:'center'}} {...getRootProps()}>
<Input {...getInputProps()}/>
<Icon type="plus" style = {{fontSize:'3rem'}}></Icon>
</div>
)}
</Dropzone>
그 이후 onChange function을 만들어 보자.
기능을 만들기 위해서 먼저 state을 정해주고 진행한다.
import React, {useState} from 'react'
const {TextArea} = Input;
const {Title} = Typography;
//map으로 묶어준다. (선택지)
const PrivateOptions = [
{value:0, label:"Private"},
{value:1, label:"Public"}
]
const CategoryOptions = [
{value:0, label: "Film & Animation"},
{value:1, label: "Autos & Vehicles"},
{value:2, label: "Music"},
{value:3, label: "Pets & Animals"}
]
function VideoUploadPage(props) {
const user = useSelector(state => state.user); //state에 담겨있는 user정보들 가지고 온다. (redux의 useselector)
const [VideoTitle, setVideoTitle] = useState("")//여기서 그냥 Title은 이미 아래서 쓰고 있기 때문에 VideoTitle로 해줬다.
const [Description, setDescription] = useState("")
const [Private, setPrivate] = useState(0) //private면 0, public 이면 1
const [Category, setCategory] = useState("Film & Animation")
const [FilePath, setFilePath] = useState("")
const [Duration, setDuration] = useState("")
//...
<label >Title</label>
<Input
onChange = {onTitleChange}
value = {VideoTitle}
/>
<br/>
<br/>
<label >Description</label>
<TextArea
onChange = {onDescriptionChange}
value = {Description}
/>
<br/>
<br/>
<select onChange={onPrivateChange}>
{PrivateOptions.map((item, index)=>(
<option key = {index} value={item.value}>{item.label}</option>//옵션을 사용할 떄는 항상 index를 넣어줘야 오류가 안난다.
))}
</select>
<br/>
<br/>
<select onChange={onCategoryChange}>
{CategoryOptions.map((item,index)=>(
<option key={index} value={item.value}>{item.label}</option>
))}
</select>
<br/>
<br/>
여기서 onChange는 타자를 칠 때마다 우리가 입력한 값으로 value가 변경 되도록 기능을 추가하는 것이다.
const onTitleChange = (e) =>{//무언가 입력할때마다 현재상태를 가져와서 target을 변경한다.
setVideoTitle(e.currentTarget.value)
}
const onDescriptionChange = (e) =>{
setDescription(e.currentTarget.value)
}
const onPrivateChange = (e) =>{
setPrivate(e.currentTarget.value) //option들도 선택하면 바뀌도록 설정한다.
}
const onCategoryChange = (e) =>{
setCategory(e.currentTarget.value)
}