반응형
출처 : 레벨업 리액트 프로그래밍
1. 프로젝트 생성
create-next-app@latest levelup-dashboard
- 정상 확인
cd levelup-dashboard
npm run dev
2. 추가 라이브러리 설치
npm i @heroicons/react @tailwindcss/forms @tremor/react @vercel/postgres autoprefixer bcrypt clsx next-auth@beta use-debounce uuid zod
-개발용 추가 설치
npm i -D @types/bcrypt @types/uuid @vercel/style-guide dotenv eslint-config-prettier prettier prettier-plugin-tailwindcss
3. 파일 수정
/tailwind.config.ts
import type { Config } from "tailwindcss";
const plugin = require('tailwindcss/plugin')
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./ui/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {blue: {400: '#2589FE', 500: '#0070F3', 600: '#2F6FEB',},},
keyframes: {
shimmer: {
'0%': {transform: 'translateX(-100%)'},
'100%': {transform: 'translateX(100%'},
},
},
animation: { shimmer: 'shimmer 2s 1'},
backgroundImage: {
'gradient-shimmer': 'linear-gradient(to right, transparent, rgba(255,255,255, 0.6), transparent)',
},
},
},
plugins: [require('@tailwindcss/forms')],
};
export default config;
/ui/animations.tsx (신규)
export const shimmer = 'relative overflow-hidden before:absoulte before:inset-0 before:-translate-x-full before:animate-shimmer before:bg-gradient-shimmer before:from-transparent before:via-white/60 before:to-transparent';
/ui/fonts.ts (신규)
import { Noto_Sans_KR } from 'next/font/google'
export const notoSansKR = Noto_Sans_KR({
weight: ['400','600','900'],
style: 'normal',
display: 'swap',
subsets: ['latin'],
})
/app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { notoSansKR } from "@/ui/fonts";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: {template: '%s | Dashboard', default: 'Dashboard by Levelup Next.js'},
description: '레벨업 리액트 프로그래밍 with Next.js - 대시보드 프로젝트',
metadataBase: new URL('https://levelup-dashboard.vercel.app/'), //나중에 릴리즈하면 자기주소로 변경
};
export default function RootLayout({
children,
}:{
children: React.ReactNode;
}) {
return (
<html lang="ko">
{/*폰트 전역 적용*/}
<body className={`${notoSansKR.className} antialiased`}>{children}</body>
</html>
);
}
/ui/logo.tsx (신규)
책에는 ... 이라고 있는게 진짜로 줄임표였다. 원소스 보고 참조
import Link from "next/link";
import {ChartBarIcon } from '@heroicons/react/24/outline'
export default function LevelupLogo() {
return (
<Link href="/">
<div className="flex flex-row items-center text-white">
<ChartBarIcon className="w-4 h-4 mr-1 sm:w-8 sm:h-8 md:w-10 md:h-10 lg:w-12 lg:h-12 xl:w-14 xl:h-14" />
<p className="hidden sm:block md:text-xl lg:text-2xl xl:text-3xl hover:underline whitespace-nowrap">레벨업 <br />Dashboard</p>
<p className="block text-xl sm:hidden hover:underline whitespace-nowrap">레벨업 Dashboard</p>
</div>
</Link>
)
}
/app/page.tsx
홈화면. 첨부된 이미지 파일을 /public 에 붙여넣기 하면 보임
next 에서 Link 는 미리로딩을 가능하게 하고 이미지는 Image Next.js 껄 써야 최적화 되게 이미지를 쏴준다
import { shimmer } from "@/ui/animations";
import LevelupLogo from "@/ui/logo";
import { ArrowRightIcon, UserPlusIcon } from "@heroicons/react/24/outline";
import Link from "next/link";
import Image from 'next/image';
export default function Page() {
return (
<main className="flex flex-col min-h-screen p-4">
{/*min-h-screen === min-height: 100vh; */}
<div className={`${shimmer} relative overflow-hidden`}>
<div className="flex items-center h-20 p-2 bg-blue-500 rounded-lg">
<LevelupLogo/>
</div>
</div>
{/*gap --css gap rows or cols gap-4 === gap: 1rem; rem: 최상위폰트 상대비율 */}
<div className="flex flex-col gap-4 mt-4 grow md:flex-row">
<div className="flex flex-col justify-center gap-6 px-6 py-10 rounded-lg bg-gray-50 md:w-3/5 md:px-20">
<p className="text-xl text-gray-800 md:text-3xl md:leading-normal">
{/* sm, md, lg 미디어 크기에 따른 수정 */}
<strong>레벨업 대시보드에 오신 걸 환영합니다.</strong> <br/>
Next.js 웹 애플리케이션 성능을 분석하는 대시보드입니다.
</p>
{/* 로그인 / 회원가입 */}
<div className="flex gap-2">
<Link href="/login" className="flex items-center self-start gap-2 px-6 py-3 text-sm font-medium text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-400 md:text-base">
로그인 <ArrowRightIcon className="w-5 md:w-2 lg:w-6" />
</Link>
<Link href="/signup" className="flex items-center self-start gap-2 px-6 py-3 text-sm font-medium text-white transition-colors bg-blue-500 rounded-lg hover:bg-blue-400 md:text-base">
회원가입 <UserPlusIcon className="w-5 md:w-2 lg:w-6" />
</Link>
</div>
</div>
<div className="flex items-center justify-center p-6 md:w-4/5 md:px-70 md:py-12">
<Image
src="/hero-desktop.png"
width={1000}
height={760}
className="hidden md:block"
alt="Screenshots of the dashboard project showing desktop version"
/>
<Image
src="/hero-mobile.png"
width={560}
height={620}
className="block md:hidden"
alt="Screenshot of the dashboard project showing mobile version"
/>
</div>
</div>
</main>
)
}
여기까지 일단 동작함..
작성중...
반응형