Skip to content

Commit fe03737

Browse files
authored
Feat(frontend): implement and connect main page (#98)
* Feat(frontend): implement and connect main page * Feat(frontend): implement and connect main page
1 parent 480e950 commit fe03737

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+22377
-31
lines changed

frontend/spec-trackr-app/package-lock.json

Lines changed: 784 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/spec-trackr-app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"bootstrap": "^5.3.6",
1313
"gh-pages": "^6.3.0",
1414
"lucide-react": "^0.513.0",
15+
"next": "^15.3.3",
1516
"react": "^19.1.0",
1617
"react-bootstrap": "^2.10.10",
1718
"react-dom": "^19.1.0",

frontend/spec-trackr-app/src/App.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,3 @@
1-
// import logo from './logo.svg';
2-
// import './App.css';
3-
4-
// function App() {
5-
// return (
6-
// <div className="App">
7-
// <header className="App-header">
8-
// <img src={logo} className="App-logo" alt="logo" />
9-
// <p>
10-
// Edit <code>src/App.js</code> and save to reload.
11-
// </p>
12-
// <a
13-
// className="App-link"
14-
// href="https://reactjs.org"
15-
// target="_blank"
16-
// rel="noopener noreferrer"
17-
// >
18-
// Learn React
19-
// </a>
20-
// </header>
21-
// </div>
22-
// );
23-
// }
24-
25-
// export default App;
26-
271
import React, { useState } from "react";
282
import ComSp from "./com_sp"; // Desktop-1
293
import SpCom from "./sp_com"; // Desktop-2

frontend/spec-trackr-app/src/com_sp.jsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { useState, useEffect } from "react";
2+
import { FaArrowLeft } from "react-icons/fa";
23
import axios from "axios";
34
import {
45
Card,
@@ -31,7 +32,7 @@ const ComSp = ({ onSpecTabClick }) => {
3132
const [companyOptions, setCompanyOptions] = useState([]);
3233
const [positionOptions, setPositionOptions] = useState([]);
3334
const [rawOptions, setRawOptions] = useState([]);
34-
const [activeTab, setActiveTab] = useState("");
35+
const [activeTab, setActiveTab] = useState("채용공고 검색");
3536
const [jobPostingResults, setJobPostingResults] = useState([]);
3637
const [companySearchTerm, setCompanySearchTerm] = useState(""); // 회사 검색어
3738

@@ -133,6 +134,23 @@ const ComSp = ({ onSpecTabClick }) => {
133134
// --- 렌더링 ---
134135
return (
135136
<Container className="mb-5">
137+
<div style={{
138+
position: "absolute",
139+
top: 24,
140+
left: 24,
141+
display: "flex",
142+
alignItems: "center",
143+
zIndex: 10
144+
}}>
145+
<Button
146+
variant="outline-dark"
147+
style={{ display: "flex", alignItems: "center", gap: 6, fontWeight: 500 }}
148+
onClick={() => { window.location.href = "http://localhost:3001"; }}
149+
>
150+
<FaArrowLeft style={{ fontSize: 18 }} />
151+
메인으로
152+
</Button>
153+
</div>
136154
{/* 상단 중앙 제목 */}
137155
<div className="text-center my-5">
138156
<h1 className="display-4 fw-bold mb-2" style={{ fontWeight: 700 }}>SpecTrackr</h1>

frontend/spec-trackr-app/src/sp_com.jsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,23 @@ const SpCom = ({ onCompanyTabClick }) => {
147147
// --- 렌더링 ---
148148
return (
149149
<Container className="mb-5">
150+
<div style={{
151+
position: "absolute",
152+
top: 24,
153+
left: 24,
154+
display: "flex",
155+
alignItems: "center",
156+
zIndex: 10
157+
}}>
158+
<Button
159+
variant="outline-dark"
160+
style={{ display: "flex", alignItems: "center", gap: 6, fontWeight: 500 }}
161+
onClick={() => { window.location.href = "http://localhost:3001"; }}
162+
>
163+
<FaArrowLeft style={{ fontSize: 18 }} />
164+
메인으로
165+
</Button>
166+
</div>
150167
{/* 상단 중앙 제목 */}
151168
<div className="text-center my-5">
152169
<h1 className="display-4 fw-bold mb-2" style={{ fontWeight: 700 }}>SpecTrackr</h1>
@@ -158,7 +175,7 @@ const SpCom = ({ onCompanyTabClick }) => {
158175
{/* 버튼: 100% 가로, 반반, 검정/흰색 */}
159176
<Row className="mb-4" style={{ marginLeft: 0, marginRight: 0 }}>
160177
<Col xs={6} className="p-0">
161-
<Button
178+
{/* <Button
162179
className="w-100 py-3 rounded-0 rounded-start"
163180
variant={activeTab === "채용공고 검색" ? "dark" : "outline-dark"}
164181
onClick={() => {
@@ -168,6 +185,17 @@ const SpCom = ({ onCompanyTabClick }) => {
168185
style={{ fontSize: "1.2rem", fontWeight: 500, borderRight: 0 }}
169186
>
170187
채용공고 검색
188+
</Button> */}
189+
<Button
190+
className="w-100 py-3 rounded-0 rounded-start"
191+
variant={activeTab === "채용공고 검색" ? "dark" : "outline-dark"}
192+
onClick={() => {
193+
setActiveTab("채용공고 검색");
194+
if (onCompanyTabClick) onCompanyTabClick();
195+
}}
196+
style={{ fontSize: "1.2rem", fontWeight: 500 }}
197+
>
198+
채용공고 검색
171199
</Button>
172200
</Col>
173201
<Col xs={6} className="p-0">
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
6+
# next.js
7+
/.next/
8+
/out/
9+
10+
# production
11+
/build
12+
13+
# debug
14+
npm-debug.log*
15+
yarn-debug.log*
16+
yarn-error.log*
17+
.pnpm-debug.log*
18+
19+
# env files
20+
.env*
21+
22+
# vercel
23+
.vercel
24+
25+
# typescript
26+
*.tsbuildinfo
27+
next-env.d.ts
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Loading() {
2+
return null
3+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"use client"
2+
3+
import { useState } from "react"
4+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
5+
import { Button } from "@/components/ui/button"
6+
import { ArrowLeft, Search, FileText } from "lucide-react"
7+
import { useRouter } from "next/navigation"
8+
import { ThemeProvider } from "@/components/theme-provider"
9+
import { ThemeToggle } from "@/components/theme-toggle"
10+
11+
export default function Dashboard() {
12+
return (
13+
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
14+
<DashboardPage />
15+
</ThemeProvider>
16+
)
17+
}
18+
19+
function DashboardPage() {
20+
const router = useRouter()
21+
const [activeTab, setActiveTab] = useState("job-search")
22+
23+
return (
24+
<div className="min-h-screen bg-slate-100 dark:bg-slate-900 text-slate-900 dark:text-white">
25+
<div className="container mx-auto px-4 py-8">
26+
<div className="flex justify-between items-center mb-6">
27+
<Button
28+
variant="ghost"
29+
onClick={() => router.push("/")}
30+
className="text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white"
31+
>
32+
<ArrowLeft className="mr-2 h-4 w-4" /> 메인으로 돌아가기
33+
</Button>
34+
<ThemeToggle />
35+
</div>
36+
37+
<h1 className="text-3xl font-bold mb-8">SpecTrackr 대시보드</h1>
38+
39+
<Tabs defaultValue="job-search" value={activeTab} onValueChange={setActiveTab} className="w-full">
40+
<TabsList className="grid w-full max-w-md grid-cols-2 mb-8">
41+
<TabsTrigger value="job-search" className="text-lg py-3">
42+
<Search className="mr-2 h-4 w-4" /> 채용공고 검색
43+
</TabsTrigger>
44+
<TabsTrigger value="spec-search" className="text-lg py-3">
45+
<FileText className="mr-2 h-4 w-4" /> 스펙 검색
46+
</TabsTrigger>
47+
</TabsList>
48+
49+
<TabsContent
50+
value="job-search"
51+
className="p-6 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"
52+
>
53+
<h2 className="text-2xl font-bold mb-4">채용공고 검색</h2>
54+
<p className="text-slate-600 dark:text-slate-300 mb-6">
55+
다양한 취업 사이트의 채용공고를 한 곳에서 확인하고 비교할 수 있습니다. 원하는 직무나 회사를 검색해보세요.
56+
</p>
57+
58+
{/* 여기에 채용공고 검색 기능 구현 */}
59+
<div className="p-12 text-center text-slate-500 dark:text-slate-400 border border-dashed border-slate-300 dark:border-slate-600 rounded-lg">
60+
채용공고 검색 기능이 여기에 구현됩니다.
61+
</div>
62+
</TabsContent>
63+
64+
<TabsContent
65+
value="spec-search"
66+
className="p-6 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"
67+
>
68+
<h2 className="text-2xl font-bold mb-4">스펙 검색</h2>
69+
<p className="text-slate-600 dark:text-slate-300 mb-6">
70+
실제 합격자 자소서와 스펙 사례를 기반으로 현실적인 준비 방법을 확인할 수 있습니다. 관심 있는 직무나 회사를
71+
검색해보세요.
72+
</p>
73+
74+
{/* 여기에 스펙 검색 기능 구현 */}
75+
<div className="p-12 text-center text-slate-500 dark:text-slate-400 border border-dashed border-slate-300 dark:border-slate-600 rounded-lg">
76+
스펙 검색 기능이 여기에 구현됩니다.
77+
</div>
78+
</TabsContent>
79+
</Tabs>
80+
</div>
81+
</div>
82+
)
83+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 100%;
8+
--foreground: 222.2 84% 4.9%;
9+
10+
--card: 0 0% 100%;
11+
--card-foreground: 222.2 84% 4.9%;
12+
13+
--popover: 0 0% 100%;
14+
--popover-foreground: 222.2 84% 4.9%;
15+
16+
--primary: 196 100% 50%;
17+
--primary-foreground: 210 40% 98%;
18+
19+
--secondary: 210 40% 96.1%;
20+
--secondary-foreground: 222.2 47.4% 11.2%;
21+
22+
--muted: 210 40% 96.1%;
23+
--muted-foreground: 215.4 16.3% 46.9%;
24+
25+
--accent: 210 40% 96.1%;
26+
--accent-foreground: 222.2 47.4% 11.2%;
27+
28+
--destructive: 0 84.2% 60.2%;
29+
--destructive-foreground: 210 40% 98%;
30+
31+
--border: 214.3 31.8% 91.4%;
32+
--input: 214.3 31.8% 91.4%;
33+
--ring: 196 100% 50%;
34+
35+
--radius: 0.5rem;
36+
}
37+
38+
.dark {
39+
--background: 222.2 84% 4.9%;
40+
--foreground: 210 40% 98%;
41+
42+
--card: 222.2 84% 4.9%;
43+
--card-foreground: 210 40% 98%;
44+
45+
--popover: 222.2 84% 4.9%;
46+
--popover-foreground: 210 40% 98%;
47+
48+
--primary: 196 100% 50%;
49+
--primary-foreground: 222.2 47.4% 11.2%;
50+
51+
--secondary: 217.2 32.6% 17.5%;
52+
--secondary-foreground: 210 40% 98%;
53+
54+
--muted: 217.2 32.6% 17.5%;
55+
--muted-foreground: 215 20.2% 65.1%;
56+
57+
--accent: 217.2 32.6% 17.5%;
58+
--accent-foreground: 210 40% 98%;
59+
60+
--destructive: 0 62.8% 30.6%;
61+
--destructive-foreground: 210 40% 98%;
62+
63+
--border: 217.2 32.6% 17.5%;
64+
--input: 217.2 32.6% 17.5%;
65+
--ring: 196 100% 50%;
66+
}
67+
68+
.light {
69+
--background: 0 0% 100%;
70+
--foreground: 222.2 84% 4.9%;
71+
72+
--card: 0 0% 100%;
73+
--card-foreground: 222.2 84% 4.9%;
74+
75+
--popover: 0 0% 100%;
76+
--popover-foreground: 222.2 84% 4.9%;
77+
78+
--primary: 196 100% 50%;
79+
--primary-foreground: 210 40% 98%;
80+
81+
--secondary: 210 40% 96.1%;
82+
--secondary-foreground: 222.2 47.4% 11.2%;
83+
84+
--muted: 210 40% 96.1%;
85+
--muted-foreground: 215.4 16.3% 46.9%;
86+
87+
--accent: 210 40% 96.1%;
88+
--accent-foreground: 222.2 47.4% 11.2%;
89+
90+
--destructive: 0 84.2% 60.2%;
91+
--destructive-foreground: 210 40% 98%;
92+
93+
--border: 214.3 31.8% 91.4%;
94+
--input: 214.3 31.8% 91.4%;
95+
--ring: 196 100% 50%;
96+
}
97+
}
98+
99+
@layer base {
100+
* {
101+
@apply border-border;
102+
}
103+
body {
104+
@apply bg-background text-foreground;
105+
}
106+
}
107+
108+
/* Custom scrollbar */
109+
::-webkit-scrollbar {
110+
width: 8px;
111+
}
112+
113+
::-webkit-scrollbar-track {
114+
background: rgba(15, 23, 42, 0.3);
115+
}
116+
117+
::-webkit-scrollbar-thumb {
118+
background: rgba(148, 163, 184, 0.5);
119+
border-radius: 4px;
120+
}
121+
122+
::-webkit-scrollbar-thumb:hover {
123+
background: rgba(148, 163, 184, 0.7);
124+
}
125+
126+
/* Gradient animations */
127+
@keyframes gradient-shift {
128+
0% {
129+
background-position: 0% 50%;
130+
}
131+
50% {
132+
background-position: 100% 50%;
133+
}
134+
100% {
135+
background-position: 0% 50%;
136+
}
137+
}
138+
139+
.animate-gradient {
140+
background-size: 200% 200%;
141+
animation: gradient-shift 5s ease infinite;
142+
}

0 commit comments

Comments
 (0)