refactor: base/layout/topbar CSS를 Tailwind로 전환
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
부모
6167a0ebd8
커밋
e9a41c6663
@ -5,10 +5,8 @@
|
||||
@source "../../../../packages/ui/src/**/*.{ts,tsx}";
|
||||
|
||||
@import "./styles/base.css";
|
||||
@import "./styles/layout.css";
|
||||
|
||||
/* Components */
|
||||
@import "./styles/components/topbar.css";
|
||||
/* Components (layout.css, topbar.css → inline Tailwind) */
|
||||
@import "./styles/components/panels.css";
|
||||
@import "./styles/components/toggles.css";
|
||||
@import "./styles/components/speed.css";
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
/* Google Fonts loaded via index.html <link> for optimal performance */
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* CSS variables are now defined in @wing/ui/theme/tokens.css */
|
||||
/* Google Fonts: loaded via index.html <link> */
|
||||
/* CSS Reset: handled by Tailwind preflight */
|
||||
/* CSS Variables: defined in @wing/ui/theme/tokens.css */
|
||||
|
||||
html,
|
||||
body {
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
.topbar {
|
||||
grid-column: 1/-1;
|
||||
background: var(--panel);
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
gap: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.topbar .logo {
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar .logo span {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.topbar .stats {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
margin-left: auto;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.topbar .stat {
|
||||
font-size: 10px;
|
||||
color: var(--muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.topbar .stat b {
|
||||
color: var(--text);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.topbar .time {
|
||||
font-size: 10px;
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-left: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.topbar-user__name {
|
||||
font-size: 10px;
|
||||
color: var(--text);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar-user__logout {
|
||||
font-size: 9px;
|
||||
color: var(--muted);
|
||||
background: none;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 3px;
|
||||
padding: 2px 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.topbar-user__logout:hover {
|
||||
color: var(--text);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
.app {
|
||||
display: grid;
|
||||
grid-template-columns: 310px 1fr;
|
||||
grid-template-rows: 44px 1fr;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: var(--panel);
|
||||
border-right: 1px solid var(--border);
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.map-area {
|
||||
position: relative;
|
||||
background: #010610;
|
||||
}
|
||||
|
||||
@media (max-width: 920px) {
|
||||
.app {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 44px 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@ -245,7 +245,7 @@ export function DashboardPage() {
|
||||
|
||||
// ── Render ──
|
||||
return (
|
||||
<div className="app">
|
||||
<div className="grid h-screen grid-cols-[310px_1fr] grid-rows-[44px_1fr] max-md:grid-cols-[1fr]">
|
||||
<Topbar
|
||||
total={legacyVesselsAll.length}
|
||||
fishing={fishingCount}
|
||||
@ -285,7 +285,7 @@ export function DashboardPage() {
|
||||
legacyIndex={legacyIndex}
|
||||
/>
|
||||
|
||||
<div className="map-area">
|
||||
<div className="relative bg-[#010610]">
|
||||
{showMapLoader ? (
|
||||
<div className="map-loader-overlay" role="status" aria-live="polite">
|
||||
<div className="map-loader-overlay__panel">
|
||||
|
||||
@ -94,7 +94,7 @@ export function DashboardSidebar({
|
||||
} = state;
|
||||
|
||||
return (
|
||||
<div className="sidebar">
|
||||
<div className="flex flex-col overflow-y-auto border-r border-wing-border bg-wing-surface max-md:hidden">
|
||||
<div className="sb">
|
||||
<div className="sb-t">업종 필터</div>
|
||||
<div className="tog">
|
||||
|
||||
@ -17,43 +17,52 @@ export function Topbar({ total, fishing, transit, pairLinks, alarms, pollingStat
|
||||
const statusColor =
|
||||
pollingStatus === "ready" ? "#22C55E" : pollingStatus === "loading" ? "#F59E0B" : pollingStatus === "error" ? "#EF4444" : "var(--muted)";
|
||||
return (
|
||||
<div className="topbar">
|
||||
<div className="logo" onClick={onLogoClick} style={{ cursor: onLogoClick ? "pointer" : undefined }} title={adminMode ? "ADMIN" : undefined}>
|
||||
🛰 <span>WING</span> 조업감시·선단연관 {adminMode ? <span style={{ fontSize: 10, color: "#F59E0B" }}>(ADMIN)</span> : null}
|
||||
<div className="col-span-full flex items-center gap-2.5 border-b border-wing-border bg-wing-surface px-3.5 z-[1000]">
|
||||
<div
|
||||
className="flex items-center gap-1.5 whitespace-nowrap text-sm font-extrabold"
|
||||
onClick={onLogoClick}
|
||||
style={{ cursor: onLogoClick ? "pointer" : undefined }}
|
||||
title={adminMode ? "ADMIN" : undefined}
|
||||
>
|
||||
🛰 <span className="text-wing-accent">WING</span> 조업감시·선단연관{" "}
|
||||
{adminMode ? <span className="text-[10px] text-wing-warning">(ADMIN)</span> : null}
|
||||
</div>
|
||||
<div className="stats">
|
||||
<div className="stat">
|
||||
<div className="ml-auto flex flex-wrap justify-end gap-3.5">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
DATA <b style={{ color: "#22C55E" }}>API</b>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
POLL{" "}
|
||||
<b style={{ color: statusColor }}>
|
||||
{pollingStatus.toUpperCase()}
|
||||
{lastFetchMinutes ? `(${lastFetchMinutes}m)` : ""}
|
||||
</b>
|
||||
</div>
|
||||
<div className="stat">
|
||||
전체 <b>{total}</b>척
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
전체 <b className="text-xs text-wing-text">{total}</b>척
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
조업 <b style={{ color: "#22C55E" }}>{fishing}</b>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
항해 <b style={{ color: "#3B82F6" }}>{transit}</b>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
쌍연결 <b style={{ color: "#F59E0B" }}>{pairLinks}</b>
|
||||
</div>
|
||||
<div className="stat">
|
||||
<div className="flex items-center gap-1 text-[10px] text-wing-muted">
|
||||
경고 <b style={{ color: "#EF4444" }}>{alarms}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div className="time">{clock}</div>
|
||||
<div className="ml-2.5 whitespace-nowrap text-[10px] font-semibold text-wing-accent">{clock}</div>
|
||||
{userName && (
|
||||
<div className="topbar-user">
|
||||
<span className="topbar-user__name">{userName}</span>
|
||||
<div className="ml-2.5 flex shrink-0 items-center gap-2">
|
||||
<span className="whitespace-nowrap text-[10px] font-medium text-wing-text">{userName}</span>
|
||||
{onLogout && (
|
||||
<button className="topbar-user__logout" onClick={onLogout}>
|
||||
<button
|
||||
className="cursor-pointer whitespace-nowrap rounded border border-wing-border bg-transparent px-1.5 py-0.5 text-[9px] text-wing-muted transition-all duration-150 hover:border-wing-accent hover:text-wing-text"
|
||||
onClick={onLogout}
|
||||
>
|
||||
로그아웃
|
||||
</button>
|
||||
)}
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user