Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .env
Empty file.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ dist-ssr

*storybook.log
storybook-static
.env
8 changes: 6 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<title>마이트랙</title>
</head>
<body>
<div id="root"></div>
Expand Down
48 changes: 47 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.6.2",
"vite-plugin-svgr": "^4.5.0",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.4",
"zustand": "^5.0.5"
},
"devDependencies": {
Expand Down
29 changes: 29 additions & 0 deletions public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

34 changes: 19 additions & 15 deletions src/app/index.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 전역 컨텍스트 및 상태 관리 설정 (라우팅, 인증 등)

import {
BrowserRouter,
BrowserRouter as Router,
Routes,
Route,
useLocation,
Expand All @@ -22,9 +22,9 @@ import TrackDataUploadModal from '../features/track-management/components/TrackD

function App() {
return (
<BrowserRouter>
<Router>
<AppContent />
</BrowserRouter>
</Router>
);
}

Expand All @@ -34,19 +34,23 @@ function AppContent() {
const shouldHideHeaderFooter = hiddenRoutes.includes(location.pathname);

return (
<div className="min-h-screen bg-blue-primary">
<div className="flex flex-col min-h-screen">
{!shouldHideHeaderFooter && <Header />}
<Routes>
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="/home" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/splash" element={<Splash />} />
<Route path="/track" element={<TrackInfo />} />
<Route path="/search" element={<Search />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/upload" element={<TrackDataUploadModal />} />
<Route path="*" element={<NotFound />} />
</Routes>
<main
className={`w-full flex-grow ${!shouldHideHeaderFooter ? 'pt-[60px]' : ''}`}
>
<Routes>
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="/home" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/splash" element={<Splash />} />
<Route path="/track" element={<TrackInfo />} />
<Route path="/search" element={<Search />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/upload" element={<UploadSection />} />
<Route path="*" element={<NotFound />} />
</Routes>
</main>
{!shouldHideHeaderFooter && <Footer />}
</div>
);
Expand Down
5 changes: 0 additions & 5 deletions src/assets/background.svg

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

function Button({
label,
onClick,
disabled,
variant = 'default',
isSelected = false,
}) {
const baseClasses = 'w-full rounded-lg py-3 font-bold transition';

const variantClasses = {
default: disabled ? 'bg-blue-light-3 text-white' : 'bg-blue-600 text-white',
file: 'border border-blue-400 text-blue-400 bg-white',
track: isSelected
? 'bg-blue-600 text-white border border-blue-600 rounded-full px-3 py-2'
: 'bg-white text-blue-500 border border-blue-300 rounded-full px-3 py-2',
};

return (
<button
onClick={onClick}
disabled={disabled}
className={`${baseClasses} ${variantClasses[variant]}`}
>
{label}
</button>
);
}

export default Button;
13 changes: 13 additions & 0 deletions src/components/Character.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Logo from '../assets/logo-character.svg?react';
import MyTrack from '../assets/mytrack.svg?react';

function Character() {
return (
<div className="flex flex-col items-center gap-2">
<Logo className="w-20 h-20 block" />
<MyTrack className="mb-4" />
</div>
);
}

export default Character;
41 changes: 41 additions & 0 deletions src/components/Input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useState } from 'react';
import { Eye, EyeOff, Search } from 'lucide-react';

function Input({ type = 'text', placeholder, value, onChange, error }) {
const [showPassword, setShowPassword] = useState(false);
const isPassword = type === 'password';
const isSearch = type === 'search';

return (
<div className="w-full">
<div className="relative">
<input
type={isPassword && !showPassword ? 'password' : 'text'}
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
className={`
w-full px-4 py-3 border rounded-md outline-none transition
border-[#DFDFDF] focus:outline-none focus:ring-0 focus:border-blue-light-1
`}
/>
{isPassword && (
<div
className="absolute right-3 top-3 cursor-pointer"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? <Eye size={20} /> : <EyeOff size={20} />}
</div>
)}
{isSearch && (
<div className="absolute right-3 top-3 pointer-events-none">
<Search size={20} />
</div>
)}
</div>
{error && <p className="text-sm text-red-500 mt-1">{error}</p>}
</div>
);
}

export default Input;
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const TrackCourseList = ({ activeTrack }) => {
if (!current) {
// 데이터가 없으면 업로드 안내 메시지 표시
return (
<div className="w-full text-white text-center mt-8">
<div className="w-full text-black text-center mt-8">
<p>업로드된 이력이 없습니다.</p>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import TrackIcon from '../../../assets/logo-character.svg?react'; // 일러스트 svg
import useUserStore from '../../../entities/user/model/useUserStore'; // 사용자 상태 관리 훅: 학생 이름을 전역 상태에서 읽어옴
import useUserStore from '../entities/user/model/useUserStore';

/**
* TrackIntroHeader: 트랙 안내 페이지의 히어로 섹션(일러스트 + 환영 헤드라인 + 소개 문단)
Expand All @@ -15,11 +14,6 @@ function TrackIntroHeader() {
return (
// 전체 컨테이너: 왼쪽 정렬, 좌우 패딩
<div className="text-left px-4">
{/* 일러스트 */}
<div className="w-24 h-24 mb-6">
<TrackIcon className="w-full h-full" />
</div>

{/* 제목 */}
<h1 className="text-2xl font-semibold text-blue-600 mb-6">
안녕하세요! {studentName}님
Expand Down
22 changes: 22 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
@import 'tailwindcss';

:root {
/* 웹페이지 전체에 적용될 기본 글꼴 목록 */
font-family:
-apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo',
'Pretendard Variable', Pretendard, Roboto, 'Noto Sans KR', 'Segoe UI',
'Malgun Gothic', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
sans-serif;
/* 기본 줄 간격 */
line-height: 1.5;
/* 기본 글자 두께 */
font-weight: 400;
background-color: #0259dd;
}

/* body {
margin: 0;
display: flex;
justify-content: center;
min-width: 320px;
min-height: 100vh;
} */

@theme {
--color-blue-primary: #0259dd;
--color-blue-light-1: #4084e8;
Expand Down
32 changes: 16 additions & 16 deletions src/pages/login/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,34 @@ function Login() {
<div
aria-hidden
className="
pointer-events-none absolute left-0 bottom-0
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/20
"
pointer-events-none absolute left-0 bottom-0
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/20
"
/>
<div
aria-hidden
className="
pointer-events-none absolute left-5 bottom-5
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/30
"
pointer-events-none absolute left-5 bottom-5
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/30
"
/>
<div
aria-hidden
className="
pointer-events-none absolute left-10 bottom-10
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/30
"
pointer-events-none absolute left-10 bottom-10
h-full w-full rounded-bl-[140px]
bg-blue-primary ring-2 ring-white/30
"
/>
<div
aria-hidden
className="
pointer-events-none absolute left-15 bottom-15
h-full w-full rounded-bl-[140px]
bg-white
"
pointer-events-none absolute left-15 bottom-15
h-full w-full rounded-bl-[140px]
bg-white
"
/>

<div className="relative z-20 w-full max-w-sm items-center justify-center flex flex-col gap-4 min-h-[600px] my-auto">
Expand Down
Loading
Loading