본문 바로가기
IT/javascript

[Next.js]차트와 대시보드 예제-홈화면

by 가능성1g 2024. 6. 30.
반응형

출처 : 레벨업 리액트 프로그래밍

 

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

 

여기까지 일단 동작함..

작성중...

반응형