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)
    }