208 lines
7.0 KiB
Vue
208 lines
7.0 KiB
Vue
<script setup lang="ts">
|
|
import { useCounterStore } from '~/stores/useCounterStore'
|
|
|
|
// SEO 메타 설정
|
|
useSeoMeta({
|
|
title: 'Nuxt 4 Starter Kit',
|
|
description: 'Nuxt 4, TypeScript, TailwindCSS v4, shadcn-vue 기반 스타터 킷',
|
|
})
|
|
|
|
const counter = useCounterStore()
|
|
|
|
// 기술 스택 목록
|
|
const techStack = [
|
|
{
|
|
icon: 'lucide:layers',
|
|
name: 'Nuxt 4',
|
|
description: 'Vue 기반 풀스택 프레임워크. app/ 디렉토리, 파일 기반 라우팅, SSR/SSG 지원.',
|
|
color: 'text-green-500',
|
|
bg: 'bg-green-500/10',
|
|
},
|
|
{
|
|
icon: 'lucide:code-2',
|
|
name: 'TypeScript',
|
|
description: 'Strict 모드 타입 안전성. any 타입 금지, 컨텍스트별 별도 tsconfig.',
|
|
color: 'text-blue-500',
|
|
bg: 'bg-blue-500/10',
|
|
},
|
|
{
|
|
icon: 'lucide:palette',
|
|
name: 'TailwindCSS v4',
|
|
description: 'CSS-first 설정. config 파일 없이 @theme으로 커스터마이징.',
|
|
color: 'text-cyan-500',
|
|
bg: 'bg-cyan-500/10',
|
|
},
|
|
{
|
|
icon: 'lucide:component',
|
|
name: 'shadcn-vue',
|
|
description: '복사해서 소유하는 UI 컴포넌트. Radix Vue 기반, 완전한 커스터마이징 가능.',
|
|
color: 'text-purple-500',
|
|
bg: 'bg-purple-500/10',
|
|
},
|
|
{
|
|
icon: 'lucide:database',
|
|
name: 'Pinia',
|
|
description: 'Vue 공식 상태 관리. Composition API 스타일, TypeScript 완벽 지원.',
|
|
color: 'text-yellow-500',
|
|
bg: 'bg-yellow-500/10',
|
|
},
|
|
{
|
|
icon: 'lucide:moon',
|
|
name: '다크 모드',
|
|
description: '@nuxtjs/color-mode로 다크/라이트 모드 전환. shadcn CSS 변수 연동.',
|
|
color: 'text-slate-500',
|
|
bg: 'bg-slate-500/10',
|
|
},
|
|
] as const
|
|
|
|
// 버튼 variant 목록
|
|
const buttonVariants = ['default', 'secondary', 'outline', 'ghost', 'destructive', 'link'] as const
|
|
</script>
|
|
|
|
<template>
|
|
<div class="container mx-auto px-4">
|
|
<!-- 히어로 섹션 -->
|
|
<section class="text-center py-20 mb-8">
|
|
<div class="flex flex-wrap items-center justify-center gap-2 mb-6">
|
|
<Badge>Nuxt 4</Badge>
|
|
<Badge variant="secondary">TypeScript</Badge>
|
|
<Badge variant="secondary">TailwindCSS v4</Badge>
|
|
<Badge variant="outline">shadcn-vue</Badge>
|
|
</div>
|
|
|
|
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight mb-6">
|
|
Nuxt 4 Starter Kit
|
|
</h1>
|
|
|
|
<p class="text-lg sm:text-xl text-muted-foreground max-w-2xl mx-auto mb-10">
|
|
최신 기술 스택으로 빠르게 웹 개발을 시작하세요.
|
|
<br class="hidden sm:block" />
|
|
Nuxt 4 + TypeScript + TailwindCSS v4 + shadcn-vue
|
|
</p>
|
|
|
|
<div class="flex flex-wrap gap-3 justify-center">
|
|
<Button size="lg">
|
|
<Icon name="lucide:rocket" class="w-4 h-4 mr-2" />
|
|
시작하기
|
|
</Button>
|
|
<Button variant="outline" size="lg">
|
|
<Icon name="lucide:book-open" class="w-4 h-4 mr-2" />
|
|
문서 보기
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 기술 스택 섹션 -->
|
|
<section class="mb-16">
|
|
<h2 class="text-2xl font-semibold text-center mb-2">기술 스택</h2>
|
|
<p class="text-muted-foreground text-center mb-8">프로덕션 레디 기술 스택으로 구성</p>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<Card
|
|
v-for="tech in techStack"
|
|
:key="tech.name"
|
|
class="p-6 hover:shadow-md transition-shadow"
|
|
>
|
|
<CardHeader class="p-0 mb-4 flex-row items-center gap-3">
|
|
<div :class="['p-2 rounded-lg', tech.bg]">
|
|
<Icon :name="tech.icon" :class="['w-5 h-5', tech.color]" />
|
|
</div>
|
|
<CardTitle class="text-base">{{ tech.name }}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="p-0">
|
|
<p class="text-sm text-muted-foreground">{{ tech.description }}</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 컴포넌트 쇼케이스 -->
|
|
<section class="mb-16">
|
|
<h2 class="text-2xl font-semibold text-center mb-2">컴포넌트 쇼케이스</h2>
|
|
<p class="text-muted-foreground text-center mb-8">shadcn-vue 기본 컴포넌트 예시</p>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<!-- 버튼 variants -->
|
|
<Card class="p-6">
|
|
<CardHeader class="p-0 mb-4">
|
|
<CardTitle>Button Variants</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="p-0">
|
|
<div class="flex flex-wrap gap-2">
|
|
<Button
|
|
v-for="variant in buttonVariants"
|
|
:key="variant"
|
|
:variant="variant"
|
|
size="sm"
|
|
>
|
|
{{ variant }}
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<!-- Badge variants -->
|
|
<Card class="p-6">
|
|
<CardHeader class="p-0 mb-4">
|
|
<CardTitle>Badge Variants</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="p-0">
|
|
<div class="flex flex-wrap gap-2">
|
|
<Badge>default</Badge>
|
|
<Badge variant="secondary">secondary</Badge>
|
|
<Badge variant="outline">outline</Badge>
|
|
<Badge variant="destructive">destructive</Badge>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Pinia 카운터 데모 -->
|
|
<section class="mb-16">
|
|
<h2 class="text-2xl font-semibold text-center mb-2">Pinia 상태 관리</h2>
|
|
<p class="text-muted-foreground text-center mb-8">useCounterStore 예시</p>
|
|
|
|
<div class="flex justify-center">
|
|
<Card class="p-8 text-center w-full max-w-sm">
|
|
<CardHeader class="p-0 mb-6">
|
|
<CardTitle>카운터</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="p-0 mb-6">
|
|
<p class="text-6xl font-bold tabular-nums">{{ counter.count }}</p>
|
|
</CardContent>
|
|
<CardFooter class="p-0 flex justify-center gap-2">
|
|
<Button
|
|
variant="outline"
|
|
size="icon"
|
|
@click="counter.decrement"
|
|
:disabled="counter.count <= 0"
|
|
>
|
|
<Icon name="lucide:minus" class="w-4 h-4" />
|
|
</Button>
|
|
<Button variant="outline" @click="counter.reset">초기화</Button>
|
|
<Button size="icon" @click="counter.increment">
|
|
<Icon name="lucide:plus" class="w-4 h-4" />
|
|
</Button>
|
|
</CardFooter>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- 다음 단계 안내 -->
|
|
<section class="mb-16">
|
|
<Card class="p-8 bg-muted/50">
|
|
<CardHeader class="p-0 mb-4">
|
|
<CardTitle class="text-xl text-center">새 컴포넌트 추가하기</CardTitle>
|
|
</CardHeader>
|
|
<CardContent class="p-0 text-center">
|
|
<p class="text-muted-foreground mb-4">shadcn-vue CLI로 컴포넌트를 추가하세요</p>
|
|
<code class="bg-background border rounded-md px-4 py-2 text-sm font-mono">
|
|
npx shadcn-vue@latest add [component]
|
|
</code>
|
|
</CardContent>
|
|
</Card>
|
|
</section>
|
|
</div>
|
|
</template>
|