Nextjs와 tailwind-css를 사용하여 YouTube 클론을 만들어 봅시다(2부).

마지막 부분에서는 YouTube 클론의 초기 설정을 만들었습니다. 다음은 에 대한 링크입니다.

마지막 부분에서는 사이드바를 만들었고, 이 부분에서는 tailwind-css를 사용하여 헤더를 빌드하고 모바일 반응형으로 만드는 방법을 알아봅니다.

function Header() {

    // useState to control user input
    const [InputValue, setInputValue] = useState('');
    const [notification, setnotification] = useState(2);

    // Don't forget to import useRouter
    const router = useRouter();

    useEffect(() =>{
        // Set a random number for the notification
        setnotification(Math.floor(Math.random() * 10));
    }, [])

  return (
    <div className='flex items-center justify-between border-b-2 fixed top-0 left-0 right-0 z-20 bg-white'>
        {/* tailwind css hamburger menu */}
        <div className='flex cursor-pointer justify-between h-[1.2rem] w-[1.5rem] flex-col ml-2 group md:ml-7'
        >
            <div className='border-r-1 h-[2px] bg-gray-700 group-hover:bg-gray-500'></div>
            <div className='border-r-1 h-[2px] bg-gray-700 group-hover:bg-gray-500'></div>
            <div className='border-r-1 h-[2px] bg-gray-700 group-hover:bg-gray-500'></div>
        </div>
        {/* Header / Youtubelogo */}
        <div className='flex items-center justify-center relative ml-1 pt-1 hover:text-gray-800'>
            <BsYoutube className='text-4xl text-red-600 pr-1'/>
            <Link href="/" ><h2 className='text-2xl text-black-600 font-bold tracking-tighter'>MeTube</h2></Link>
            <span className='absolute -right-2 -top-0.5 pl-4 opacity-50 text-[15px]'>IN</span>
        </div>
        {/* Query field */}
        <div className='flex items-center justify-center focus:outline-none focus:bg-gray-300'>
            <div className='flex items-center justify-center bg-gray-200 rounded-lg mr-2 my-2'>
                <input type='text' placeholder='Search'
                className='bg-gray-200 rounded-lg px-4 py-2 w-20 text-gray-800 md:w-[20em] focus:outline-none lg:w-[35em]'
                value={InputValue}
                onChange={(e) =>{
                    setInputValue(e.target.value)
                }}
                onKeyDown={(e) =>{
                    if (e.key === 'Enter'){
                        router.push(`/?query=${InputValue.toLowerCase()}`);
                    }
                }}

                />
                <BsSearch className='mr-3' />
            </div>
                <BsMicFill className='text-2xl mr-3 hidden md:block' />                
        </div>
        {/* Avatar from react-avatar */}
        <div className='flex items-center justify-between'>
            <BsCameraVideo className='hidden md:block text-3xl mr-7'  data-tip='Add a new Video' />
            <div className='relative mr-3 md:mr-7'>
                <BsBell className='text-2xl md:text-3xl' data-tip="Notifications"/>
                <span className='absolute -top-3 -right-1 w-4 h-4 text-center flex items-center justify-center rounded-full bg-red-600 p-3 text-[12px] text-white '>{notification}</span>
            </div>
            <div className='mr-5 md:mr-7 ' data-tip='Your account'><Avatar name='Sadeed' size={35} round={true}/></div>
        </div>
        <ReactTooltip backgroundColor='#403e3f' isCapture/>
    </div>
  )
}


이제 헤더 파일이 완료되었으므로 본문 부분을 살펴보겠습니다.

function Body() {
  return (
    <div className="col-span-6 relative min-h-screen z-0">
        <Navbar />
        <VideoPlayer />
    </div>
  )
}


Navbar 구성 요소에서:

import React, {useEffect} from 'react'
import {Genres} from './Data/Genre'
import { useRouter } from 'next/router';


function Navbar() {
  const router = useRouter();

  return (
    <div className='flex overflow-x-scroll items-center gap-6 scrollbar-hide w-screen border-b-2 mb-2 pb-4'>
        {Genres && Genres.map((item, index) => {
            return <button key={index} className='border-[#0000001a] border-2 rounded-[16px] bg-[#0000000d] pl-2 pr-2 pt-1 pb-1 cursor-pointer last:mr-24 hover:bg-gray-200 active:bg-gray-900 active:text-white'
            onClick={() =>{
              router.push(`/?query=${item.toLowerCase()}`);
            }}
            >{item}</button>  
        })}

    </div>
  )
}


다음은 모든 데이터가 포함된 장르 파일입니다.

export const Genres = ['Gaming', 'Music', 'Movies', 'Books', 'Comics', 'Anime', 'Education', 'Sports','Science', 'Technology', 'Food', 'Travel', 'Health', 'Fashion', 'Finance', 'Politics', 'Art'];


지금까지 UI가 거의 완료되었습니다. 이제 다음 부분에서는 본문 구성 요소에 대해 작업하고 데이터를 가져오고 모든 비디오를 표시하는 방법을 배웁니다.

좋은 웹페이지 즐겨찾기