본문 바로가기
Tutorial/youtube2023

06. 나만의 유튜브 사이트 만들기 : 메인 콘텐츠 만들기

by @webstoryboy 2023. 9. 1.
Tutorial/Portfolio

나만의 유튜브 사이트 만들기

by @webs 2023. 09. 01.
06
나만의 유튜브 사이트 만들기 : 메인 콘텐츠 만들기
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. 이번에는 메인페이지의 메인 컨텐츠를 만들어 보겠습니다. 메인에는 오늘의 추천영상, 개발자 소개 및 영상 소개를 보여주는 부분입니다. 그럼 한번 시작해보겠습니다.😝

인덱스

  • 1. 셋팅하기
    • 1_1. Node.js 설치
    • 1_2. Vscode 설치
    • 1_3. React.js 설치
    • 1_4. 폴더 정리하기
    • 1_5. 필요한 파일 설치하기
  • 2. CSS 셋팅하기
    • 2_1. SCSS 설정하기
    • 2_2. style.scss 설정하기
    • 2_3. fonts.scss 설정하기
    • 2_4. vars.scss 설정하기
    • 2_5. reset.scss 설정하기
    • 2_6. mixin.scss 설정하기
    • 2_7. common.scss 설정하기
  • 3. 페이지 및 컴퍼넌트 만들기
    • 3_1. 페이지 만들기
    • 3_2. 컴퍼넌트 만들기
  • 4. 섹션 컴퍼넌트 만들기
    • 4_1. Main 컨퍼넌트 만들기
    • 4_2. Header 컨퍼넌트 만들기
    • 4_3. Header 컨퍼넌트 데이터화 하기
    • 4_4. Footer 컨퍼넌트 만들기
  • 5. 페이지 SEO 작업
    • 5_1. App.js 재구성
    • 5_2. main 컴퍼넌트 재구성
    • 5_3. 모든 페이지 재구성
  • 6. 메인 콘텐츠 만들기
    • 6_1. 검색 컴퍼넌트 작업
    • 6_2. 오늘의 영상 컴퍼넌트 작업
    • 6_3. 오늘의 영상 페이지 작업

6. 메인 콘텐츠 만들기

6_1. 검색 컴퍼넌트 작업

검색 영역 역시 모든 페이지에 들어가기 때문에 main 컴퍼넌트에 넣어주겠습니다. main 태그 안에 추가 하였습니다. import를 추가하여 연동까지 완료했습니다.

import React from 'react'
import { Helmet, HelmetProvider } from 'react-helmet-async'

import Header from './Header'
import Footer from './Footer'
import Search from './Search'

const Main = ( props ) => {
    return (
        <HelmetProvider>
            <Helmet 
                titleTemplate="%s | Webs Youtube" 
                defaultTitle="Webs Youtube" 
                defer={false}
            >
                {props.title && <title>{props.title}</title>}
                <meta name="description" content={props.description} />
            </Helmet>

            <Header />
            <main id="main" role="main">
                <Search />
                {props.children}
            </main>
            <Footer />
        </HelmetProvider>
    )
}

export default Main

search.jsx 컴퍼넌트는 다음과 같이 작업했습니다.

import React from 'react'

const Search = () => {
    return (
        <div id='search'>
            <div className='search__inner'>
                <label htmlFor='searchInput'>
                    <span className='ir'>검색</span>
                </label>
                <input 
                    type='search' 
                    id='searchInput' 
                    placeholder='검색어를 입력해주세요' 
                    autoComplete='off' 
                    className='search__input' 
                />
            </div>
        </div>
    )
}

export default Search

_search.scss 는 다음과 같이 작업했습니다. 새로 추가된 scss는 sytle.scss 에 추가하여야 합니다.

.search__inner {
    padding: 17px 40px;
    width: 100%;
    position: relative;
    border-bottom: 1px solid #161616;
    height: 81px;

    label {
        position: absolute;
        left: 53px; 
        top: 28px;
        width: 24px;
        height: 24px;
        background-image: url(../../img/icon/search.svg);
        background-size: cover;
    }
    input {
        background-color: #111;
        border: 1px solid #161616;
        border-radius: 40px;
        font-size: 16px;
        padding: 14px 45px;
        width: 100%;
        color: #fff;
    }
}

6_2. 오늘의 영상 컴퍼넌트 작업

components 폴더에 contents 폴더를 만들고 Today.jsx 컴퍼넌트를 만들겠습니다.

Home.jsx는 다음과 같이 컴퍼넌트를 연동합니다.

import React from 'react'
import Main from '../components/section/Main'

import Today from '../components/contents/Today'

const Home = () => {
    return (
        <Main 
            title = '웹스토리보이 유튜브'
            description='웹스토리보이 유튜버에 오신 것을 환영합니다.'>
            
            <Today />
        </Main>
    )
}

export default Home

Today.jsx는 다음과 같이 작업합니다.

import React from 'react'

import { todayText } from '../data/today'
import { Link } from 'react-router-dom'

const today = () => {
    return (
        <section id='today'>
            <div className='today__inner'>
                <div className='today__thumb play__icon'>
                    <Link to={todayText[0].page}>
                        <img src={todayText[0].img} alt={todayText[0].title} />
                    </Link>
                </div>
                <div className='today__text'>
                    <span className='today'>today!</span>
                    <h3 className='title'>
                        <Link to={todayText[0].page}>{todayText[0].title}</Link>
                    </h3>
                    <p className='desc'>{todayText[0].desc}</p>
                    <div className='info'>
                        <span className='author'>
                            <Link to={`/channel/${todayText[0].author_id}`}>{todayText[0].author}</Link>
                        </span>
                        <span className='date'>{todayText[0].date}</span>
                    </div>
                </div>
            </div>
        </section>
    )
}

export default today

데이터는 data 폴더에 today.js에서 가져옵니다.

import todayView01 from "../assets/img/today/todayView01.jpg";
import todayView02 from "../assets/img/today/todayView02.jpg";
import todayView03 from "../assets/img/today/todayView03.jpg";
import todayView04 from "../assets/img/today/todayView04.jpg";
import todayView05 from "../assets/img/today/todayView05.jpg";
import todayView06 from "../assets/img/today/todayView06.jpg";
import todayView07 from "../assets/img/today/todayView07.jpg";
import todayView08 from "../assets/img/today/todayView08.jpg";

export const todayText = [
    {
        img: todayView01,
        title: "나만의 코딩 유튜브 사이트 만들기 프로젝트",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/youtube"
    },{
        img: todayView02,
        title: "Vite를 이용하여 포트폴리오 사이트 만들기",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/port"
    },{
        img: todayView03,
        title: "React.js를 이용하여 포트폴리오 사이트 만들기",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/port"
    },{
        img: todayView04,
        title: "Vue.js를 이용하여 포트폴리오 사이트 만들기",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/port"
    },{
        img: todayView05,
        title: "Next.js를 이용하여 포트폴리오 사이트 만들기",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/port"
    },{
        img: todayView06,
        title: "GSAP를 이용하여 창의적인 사이트 만들기",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/gsap"
    },{
        img: todayView07,
        title: "웹디자인 기능사는 이 영상으로 준비 끝",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/webd"
    },{
        img: todayView08,
        title: "디자인 부터 코딩까지 준비 완료",
        desc : "안녕하세요, 여러분! 오늘은 특별한 프로젝트를 소개해드리려고 합니다. 제가 '나만의 코딩 유튜브 사이트 만들기'라는 주제로 프로젝트를 진행하게 되었는데요, 이 프로젝트는 저의 열정인 코딩과 온라인 교육을 결합한 결과물입니다. 이 프로젝트의 주요 목표는 누구나 쉽게 접근하고 배울 수 있는 공간을 만드는 것입니다. 제가 여러 해 동안 프로그래밍을 공부하면서 느낀 점은 양질의 학습 자료와 개인의 진도에 맞는 커리큘럼이 얼마나 중요한지입니다. 그래서 이 사이트에서는 초보자부터 고급 수준까지 다양한 난이도와 주제의 온라인 강의를 제공할 계획입니다.",
        author : "webstoryboy",
        channelId: "UCsvQSv7EeCMHyYb9ENKAJZw",
        date: "2023.07.07",
        page: "/website"
    },
]

_today.scss 파일을 추가하고 style.scss에 today.scss를 추가합니다.

.today__inner {
    display: flex;
    color: #fff;
    overflow: hidden;
    position: relative;
    margin-bottom: 50px;
    background-color: #111;

    .today__thumb {
        width: 40%;
    }
    .today__text {
        width: 60%;
        padding: 2rem;

        .today {
            background-color: #b70208;
            padding: 2px 50px;
            display: inline-block;
            border-radius: 40px;
            margin-bottom: 10px;
            text-transform: uppercase;
        }
        .title {
            font-size: 2rem;
            margin-bottom: 1rem;
            @include line-one;
        }
        .desc {
            margin-bottom: 1rem;
            @include line(4);
        }
        .info {
            .author {
                font-size: 1rem;
                margin-right: 10px;
                font-weight: 900;
                text-decoration: underline;
                text-underline-position: under;
                text-transform: uppercase;
            }
            .date {
                font-size: 14px;
            }
        }
    }
}
@media (max-width: 1700px){
    .today__inner {
        .today__thumb {
            width: 500px;
        }
        .today__text {
            width: calc(100% - 500px);
    
            .desc {
                margin-bottom: 1rem;
                @include line(2);
            }
        }
    }
}
@media (max-width: 1200px){
    .today__inner {
        flex-direction: column;

        .today__thumb {
            width: 100%;
        }
        .today__text { 
            width: 100%;

            .title {
                font-size: 24px;
            }

            .desc {
                display: none;
            }
        }
    }
}    

여기까지 잘 따라했다면 다음과 같이 나옵니다.

youtube2023

6_3. 오늘의 영상 페이지 작업

pages 폴더에 Today.jsx 페이지를 작업하겠습니다. 작업 소스는 동일합니다. 데이터를 불러와서 작업합니다.

import React from 'react'
import Main from '../components/section/Main'

import { todayText } from '../data/today'
import { Link } from 'react-router-dom'

const Today = () => {
    return (
        <Main 
            title = "추천 영상"
            description="오늘의 추천 유튜브 영상입니다.">
            
            <section id='todayPage'>
                <h2>🥰 오늘의 추천 영상입니다.</h2>

                {todayText.map((today, key) => (
                    <div className='today__inner' key={key}>
                        <div className='today__thumb play__icon'>
                            <Link to={today.page}>
                                <img src={today.img} alt={today.title} />
                            </Link>
                        </div>
                        <div className='today__text'>
                            <span className='today'>today!</span>
                            <h3 className='title'>
                                <Link to={today.page}>{today.title}</Link>
                            </h3>
                            <p className='desc'>{today.desc}</p>
                            <div className='info'>
                                <span className='author'>
                                    <Link to={`/channel/${today.channelId}`}>{today.author}</Link>
                                </span>
                                <span className='date'>{today.date}</span>
                            </div>
                        </div>
                    </div>
                ))}
            </section>
        </Main>
    )
}

export default Today

오늘의 영상 페이지는 다음과 같이 나옵니다.

youtube2023

마무리

메인 페이지의 추천 영상 부분과 추천 영상 페이지를 완료했습니다. 소스가 중복되는 부분이 있지만 다음 작업시에는 재활용을 통해 작업해보겠습니다.


예제 목록

댓글