Skip to content

Commit 0ebd73a

Browse files
committed
feat: React 웹 셸과 bypass 실행 흐름 정비
1 parent fe44bc9 commit 0ebd73a

10 files changed

Lines changed: 1651 additions & 872 deletions

File tree

apps/api/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"version": "0.0.0",
55
"main": "dist/index.js",
66
"scripts": {
7-
"dev": "NODE_ENV=development pnpm exec tsx watch src/index.ts",
8-
"dev:bypass": "NODE_ENV=development INSTALL_MODE=bypass pnpm exec tsx watch src/index.ts",
7+
"dev": "pnpm exec tsx watch src/index.ts",
8+
"dev:bypass": "pnpm exec tsx watch src/index.ts",
99
"build": "tsc",
1010
"start": "node dist/index.js",
1111
"test": "vitest run",

apps/web/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
</head>
88
<body>
99
<div id="app"></div>
10-
<script type="module" src="/src/main.ts"></script>
10+
<script type="module" src="/src/main.tsx"></script>
1111
</body>
1212
</html>

apps/web/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@
44
"version": "0.0.0",
55
"scripts": {
66
"dev": "vite",
7-
"dev:bypass": "VITE_INSTALL_MODE=bypass vite",
7+
"dev:bypass": "vite",
88
"build": "tsc && vite build",
99
"preview": "vite preview",
1010
"test": "vitest run --passWithNoTests",
1111
"typecheck": "tsc --noEmit"
1212
},
1313
"devDependencies": {
14+
"@types/react": "^19.2.14",
15+
"@types/react-dom": "^19.2.3",
1416
"typescript": "^5.9.2",
1517
"vite": "^5.4.19",
1618
"vitest": "^2.1.9"
19+
},
20+
"dependencies": {
21+
"react": "^19.2.4",
22+
"react-dom": "^19.2.4"
1723
}
1824
}

apps/web/src/app.css

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
:root {
2+
color-scheme: light;
3+
--bg: #eef3ff;
4+
--bg-accent: #d9ecff;
5+
--surface: #ffffff;
6+
--text: #0f172a;
7+
--muted: #52607a;
8+
--primary: #1e40af;
9+
--primary-strong: #1d4ed8;
10+
--border: #d8e1f2;
11+
}
12+
13+
* {
14+
box-sizing: border-box;
15+
}
16+
17+
body {
18+
margin: 0;
19+
min-height: 100vh;
20+
font-family: "Pretendard", "Noto Sans KR", "Segoe UI", sans-serif;
21+
color: var(--text);
22+
background:
23+
radial-gradient(circle at 10% 15%, rgba(46, 116, 255, 0.18), transparent 38%),
24+
radial-gradient(circle at 82% 12%, rgba(16, 185, 129, 0.18), transparent 32%),
25+
linear-gradient(160deg, var(--bg), var(--bg-accent));
26+
}
27+
28+
.frame {
29+
max-width: 1100px;
30+
margin: 0 auto;
31+
padding: 24px 16px 40px;
32+
}
33+
34+
.topbar {
35+
display: flex;
36+
flex-wrap: wrap;
37+
justify-content: space-between;
38+
align-items: center;
39+
gap: 12px;
40+
background: rgba(255, 255, 255, 0.86);
41+
border: 1px solid var(--border);
42+
border-radius: 14px;
43+
padding: 12px 14px;
44+
backdrop-filter: blur(4px);
45+
}
46+
47+
.brand {
48+
font-weight: 700;
49+
letter-spacing: 0.02em;
50+
}
51+
52+
.badge {
53+
border-radius: 999px;
54+
padding: 5px 10px;
55+
font-size: 12px;
56+
font-weight: 700;
57+
}
58+
59+
.badge-danger {
60+
background: #ffe4e6;
61+
color: #9f1239;
62+
}
63+
64+
.badge-soft {
65+
background: #e8efff;
66+
color: #1e3a8a;
67+
}
68+
69+
.layout {
70+
margin-top: 16px;
71+
display: grid;
72+
gap: 16px;
73+
grid-template-columns: 220px 1fr;
74+
}
75+
76+
.nav {
77+
background: var(--surface);
78+
border: 1px solid var(--border);
79+
border-radius: 14px;
80+
padding: 12px;
81+
}
82+
83+
.nav-list {
84+
list-style: none;
85+
margin: 0;
86+
padding: 0;
87+
display: grid;
88+
gap: 6px;
89+
}
90+
91+
.nav-button {
92+
width: 100%;
93+
text-align: left;
94+
border: 1px solid transparent;
95+
background: transparent;
96+
border-radius: 10px;
97+
padding: 10px;
98+
cursor: pointer;
99+
font-size: 14px;
100+
color: var(--text);
101+
}
102+
103+
.nav-button[aria-current="page"] {
104+
background: #e4ecff;
105+
border-color: #bfd0ff;
106+
font-weight: 700;
107+
}
108+
109+
.panel {
110+
background: var(--surface);
111+
border: 1px solid var(--border);
112+
border-radius: 16px;
113+
padding: 20px;
114+
}
115+
116+
.title {
117+
margin: 0;
118+
font-size: 24px;
119+
}
120+
121+
.subtitle {
122+
margin-top: 8px;
123+
margin-bottom: 0;
124+
color: var(--muted);
125+
font-size: 14px;
126+
}
127+
128+
.stack {
129+
display: grid;
130+
gap: 12px;
131+
margin-top: 20px;
132+
}
133+
134+
.grid {
135+
display: grid;
136+
gap: 12px;
137+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
138+
}
139+
140+
.field {
141+
display: grid;
142+
gap: 6px;
143+
}
144+
145+
.field > span {
146+
font-size: 13px;
147+
color: var(--muted);
148+
}
149+
150+
.input,
151+
.select {
152+
width: 100%;
153+
border: 1px solid #c7d4ef;
154+
border-radius: 10px;
155+
padding: 9px 10px;
156+
font-size: 14px;
157+
}
158+
159+
.actions {
160+
display: flex;
161+
flex-wrap: wrap;
162+
gap: 8px;
163+
}
164+
165+
.button {
166+
border: none;
167+
border-radius: 10px;
168+
padding: 9px 13px;
169+
font-weight: 700;
170+
cursor: pointer;
171+
background: #e5ebfb;
172+
color: #122042;
173+
}
174+
175+
.button-primary {
176+
background: var(--primary);
177+
color: #ffffff;
178+
}
179+
180+
.button-primary:hover {
181+
background: var(--primary-strong);
182+
}
183+
184+
.button-danger {
185+
background: #fee2e2;
186+
color: #991b1b;
187+
}
188+
189+
.chip {
190+
border-radius: 999px;
191+
display: inline-flex;
192+
align-items: center;
193+
padding: 5px 10px;
194+
font-size: 12px;
195+
font-weight: 700;
196+
}
197+
198+
.chip-ready {
199+
background: #d1fae5;
200+
color: #065f46;
201+
}
202+
203+
.chip-loading {
204+
background: #dbeafe;
205+
color: #1e3a8a;
206+
}
207+
208+
.chip-empty {
209+
background: #fff7ed;
210+
color: #9a3412;
211+
}
212+
213+
.chip-error {
214+
background: #fee2e2;
215+
color: #991b1b;
216+
}
217+
218+
.status {
219+
border-radius: 12px;
220+
padding: 12px;
221+
border: 1px solid var(--border);
222+
}
223+
224+
.status h3 {
225+
margin: 0;
226+
font-size: 16px;
227+
}
228+
229+
.status p {
230+
margin: 8px 0 0;
231+
font-size: 14px;
232+
color: #334155;
233+
}
234+
235+
.status-ready {
236+
border-color: #86efac;
237+
background: #f0fdf4;
238+
}
239+
240+
.status-loading {
241+
border-color: #93c5fd;
242+
background: #eff6ff;
243+
}
244+
245+
.status-empty {
246+
border-color: #fdba74;
247+
background: #fff7ed;
248+
}
249+
250+
.status-error {
251+
border-color: #fda4af;
252+
background: #fff1f2;
253+
}
254+
255+
.notice {
256+
margin-top: 12px;
257+
font-size: 13px;
258+
color: #334155;
259+
}
260+
261+
@media (max-width: 900px) {
262+
.layout {
263+
grid-template-columns: 1fr;
264+
}
265+
}

apps/web/src/main.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)