Skip to content

uwksa.ca (Frontend)

UWKSA 메인 웹사이트(uwksa.ca)의 프론트엔드 프로젝트 문서입니다.


기술 스택

분류 기술
Framework React 18 + TypeScript
Build Tool Vite 6
UI 라이브러리 Radix UI + shadcn/ui
스타일링 Tailwind CSS
아이콘 Lucide React
애니메이션 Motion
테마 next-themes (다크/라이트 모드)
패키지 매니저 npm

개발 환경 설정

항목
개발 서버 포트 3000 (npm run dev 시 브라우저 자동 열림)
빌드 출력 build/
Path Alias @./src

Path Alias @

이 프로젝트는 @./src 폴더의 alias로 사용합니다. import 시 상대 경로 대신 @/를 사용하세요:

// Good
import { Button } from "@/components/ui/button";    // = src/components/ui/button
import { useLanguage } from "@/contexts/AppContext"; // = src/contexts/AppContext

// Bad - 깊은 상대 경로는 피하세요
import { Button } from "../../../components/ui/button";

프로젝트 구조

uwksa.ca/
├── src/
│   ├── App.tsx                    # 메인 앱 컴포넌트 (hash 라우팅 + lazy loading)
│   ├── main.tsx                   # 엔트리 포인트
│   ├── index.css                  # 글로벌 스타일
│   ├── components/                # 재사용 가능한 컴포넌트
│   │   ├── ui/                    # shadcn/ui 컴포넌트 (40개 이상)
│   │   ├── Header.tsx             # 네비게이션 헤더 (한/영 메뉴)
│   │   ├── Footer.tsx             # 푸터
│   │   ├── TeamSection.tsx        # 팀원 소개 섹션
│   │   ├── CursorMascot.tsx       # 마스코트 커서 효과
│   │   ├── ImageWithFallback.tsx  # 이미지 로딩 실패 시 폴백
│   │   └── ThemeToggle.tsx        # 다크/라이트 모드 토글
│   ├── pages/                     # 페이지 컴포넌트
│   │   ├── HomePage.tsx           # 메인 페이지 (이벤트 포함)
│   │   ├── MembershipPage.tsx     # 멤버십 + 제휴 식당
│   │   ├── EventsPage.tsx         # 이벤트 목록 (이벤트 포함)
│   │   ├── GalleryPage.tsx        # 갤러리
│   │   └── ContactPage.tsx        # 연락처
│   ├── contexts/                  # React Context
│   │   └── AppContext.tsx         # 언어/테마 상태 관리
│   ├── data/                      # 정적 데이터
│   │   ├── teamData.ts            # 팀원 정보 + 프로필 사진 매핑
│   │   └── socialLinks.ts         # 소셜 미디어 링크
│   ├── types/                     # TypeScript 타입 정의
│   ├── hooks/                     # 커스텀 React hooks
│   └── assets/                    # 이미지 등 정적 자산 (프로필 사진)
├── public/                        # 정적 파일
├── index.html                     # HTML 엔트리
├── package.json
├── vite.config.ts                 # Vite 설정 (path alias 포함)
└── .gitignore

상태 관리

src/contexts/AppContext.tsx에서 3가지 hook을 제공합니다:

Hook 반환값 설명
useApp() 전체 Context 언어 + 테마 전체 접근
useLanguage() { language, setLanguage, toggleLanguage } 언어 전환 ('ko' / 'en', 기본값 'ko', 새로고침 시 초기화)
useTheme() { isDark, setIsDark, toggleTheme } 다크/라이트 모드 (localStorage에 저장, 유지됨)

사용 예시:

import { useLanguage } from '@/contexts/AppContext';

export function MyComponent() {
  const { language } = useLanguage();

  return <p>{language === 'ko' ? '안녕하세요' : 'Hello'}</p>;
}

주요 특징

Hash 기반 라우팅

#/, #/membership, #/events, #/gallery, #/contact

다국어 지원

한국어(KO) / 영어(EN) 전환 가능. 다국어 텍스트는 LocalizedContent<T> 타입을 사용하여 관리합니다:

type LocalizedContent<T> = {
  ko: T;
  en: T;
};

이벤트 데이터는 예외

이벤트 데이터는 LocalizedContent 타입 대신 페이지 내부에서 content = { ko: { events: [...] }, en: { events: [...] } } 형태로 직접 정의합니다. 자세한 내용은 자주 하는 작업 - 이벤트 업데이트를 참고하세요.

다크/라이트 모드

시스템 설정 감지 + 수동 전환. localStorage에 저장되어 새로고침 후에도 유지됩니다.

Lazy Loading

React Suspense를 이용한 페이지별 코드 스플리팅. Named export + .then() 패턴을 사용합니다.


브랜드 색상

색상 코드 용도
UWKSA Gold #FDB813 Footer 배경, 로딩 스피너, 로고 등

관련 문서