Skip to content
Merged
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
62 changes: 47 additions & 15 deletions src/components/layout/AppLayout.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
flex: 0 0 208px;
display: flex;
flex-direction: column;
padding: 28px 20px;
padding: 28px 20px 22px;
overflow-y: auto;
background: var(--brand-dark);
color: var(--fowoco-white);
Expand All @@ -44,34 +44,50 @@
}

.brand {
margin: 0 0 4px 4px;
height: 32px;
margin: 0 0 0 4px;
font-size: 20px;
font-weight: 700;
line-height: 28px;
}

.kicker {
margin: 0 0 24px 4px;
height: 19px;
margin: 20px 0 19px 4px;
font-size: 11px;
font-weight: 500;
line-height: 19px;
color: var(--fowoco-teal-100);
}

.nav {
display: flex;
flex-direction: column;
gap: 4px;
gap: 8px;
}

.navLink {
padding: 10px 16px;
position: relative;
display: flex;
align-items: center;
gap: 12px;
height: 44px;
padding: 0 16px;
border-radius: var(--fowoco-radius-6);
font-size: 14px;
color: var(--fowoco-teal-100);
text-decoration: none;
transition: background-color var(--fowoco-motion-fast) var(--fowoco-easing-standard),
transition:
background-color var(--fowoco-motion-fast) var(--fowoco-easing-standard),
color var(--fowoco-motion-fast) var(--fowoco-easing-standard);
}

.navIcon {
width: 18px;
height: 18px;
flex: 0 0 18px;
}

.navLink:hover {
background: rgba(255, 255, 255, 0.06);
color: var(--fowoco-white);
Expand All @@ -83,15 +99,25 @@
font-weight: 500;
}

.navLinkActive::before {
position: absolute;
top: 10px;
bottom: 10px;
left: 0;
width: 3px;
border-radius: 2px;
background: var(--brand-primary);
content: '';
}

.sidebarFooter {
margin-top: auto;
display: flex;
flex-direction: column;
gap: 2px;
}

.help,
.logout {
.help {
padding: 10px 16px;
background: none;
border: none;
Expand All @@ -101,11 +127,6 @@
cursor: pointer;
}

.logout {
color: var(--fowoco-white);
opacity: 0.85;
}

.main {
flex: 1;
display: flex;
Expand All @@ -124,7 +145,7 @@
.topBar {
display: flex;
align-items: center;
justify-content: flex-end;
justify-content: space-between;
gap: 12px;
flex-shrink: 0;
min-height: 64px;
Expand All @@ -133,16 +154,27 @@
border-bottom: 1px solid var(--border-default);
}

.topBarBack {
font-size: 13px;
color: var(--text-secondary);
text-decoration: none;
}

.topBarBack:hover {
color: var(--text-primary);
}

.topBarActions {
display: flex;
align-items: center;
gap: 16px;
margin-left: auto;
}

.content {
flex: 1;
min-height: 0;
padding: 32px;
padding: 32px 40px;
overflow-y: auto;
}

Expand Down
21 changes: 15 additions & 6 deletions src/components/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
import { NavLink, useNavigate } from 'react-router-dom'
import { Link, NavLink, useLocation, useNavigate } from 'react-router-dom'
import { OnboardingTour } from '../onboarding/OnboardingTour'
import { hasCompletedOnboarding, markOnboardingCompleted } from '../onboarding/onboardingStorage'
import { useAuthStore } from '../../store/authStore'
Expand All @@ -12,10 +12,12 @@ import { RouteTransition } from './RouteTransition'

export function AppLayout() {
const navigate = useNavigate()
const location = useLocation()
const user = useAuthStore((state) => state.user)
const logout = useAuthStore((state) => state.logout)
const [helpOpen, setHelpOpen] = useState(false)
const [tourOpen, setTourOpen] = useState(false)
const isTaskDetail = /^\/tasks\/[^/]+$/.test(location.pathname)

useEffect(() => {
if (!hasCompletedOnboarding()) setTourOpen(true)
Expand Down Expand Up @@ -51,7 +53,8 @@ export function AppLayout() {
`${styles.navLink} ${isActive ? styles.navLinkActive : ''}`
}
>
{item.label}
<img src={item.iconSrc} alt="" className={styles.navIcon} aria-hidden="true" />
<span>{item.label}</span>
</NavLink>
))}
</nav>
Expand All @@ -60,14 +63,16 @@ export function AppLayout() {
<button type="button" className={styles.help} onClick={() => setHelpOpen(true)}>
? 도움말
</button>
<button type="button" className={styles.logout} onClick={handleLogout}>
로그아웃
</button>
</div>
</aside>

<div className={styles.main}>
<header className={styles.topBar}>
{isTaskDetail && (
<Link to="/tasks" className={styles.topBarBack}>
← 업무함
</Link>
)}
<div className={styles.topBarActions}>
<HeaderActions user={user} onLogout={handleLogout} />
</div>
Expand All @@ -78,7 +83,11 @@ export function AppLayout() {
</main>
</div>

<HelpModal open={helpOpen} onClose={() => setHelpOpen(false)} onReplayTour={handleReplayTour} />
<HelpModal
open={helpOpen}
onClose={() => setHelpOpen(false)}
onReplayTour={handleReplayTour}
/>
<OnboardingTour open={tourOpen} onFinish={handleFinishTour} />
<ToastViewport />
</div>
Expand Down
39 changes: 23 additions & 16 deletions src/components/layout/HeaderActions/HeaderActions.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
background: var(--surface-subtle);
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
background: var(--surface-default);
border: 1px solid var(--border-default);
border-radius: var(--fowoco-radius-8);
cursor: pointer;
}

.bellIcon {
width: 18px;
height: 18px;
width: 20px;
height: 20px;
color: var(--brand-primary);
}

Expand All @@ -47,12 +47,13 @@
.profileButton {
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
width: 188px;
height: 40px;
padding: 0 10px 0 4px;
background: var(--surface-subtle);
border: none;
border-radius: var(--fowoco-radius-999);
padding: 6px 12px;
background: var(--surface-default);
border: 1px solid var(--border-default);
border-radius: var(--fowoco-radius-8);
cursor: pointer;
}

Expand All @@ -62,15 +63,21 @@
justify-content: center;
width: 28px;
height: 28px;
font-size: 12px;
font-weight: 700;
color: var(--fowoco-white);
background: var(--brand-primary);
flex: 0 0 28px;
font-size: 13px;
font-weight: 500;
color: var(--brand-primary);
background: var(--surface-subtle);
border-radius: 50%;
}

.profileLabel {
flex: 1;
min-width: 0;
overflow: hidden;
font-size: 13px;
text-align: left;
text-overflow: ellipsis;
color: var(--text-primary);
white-space: nowrap;
}
Expand Down
5 changes: 5 additions & 0 deletions src/components/layout/nav-icons/documents.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/components/layout/nav-icons/settings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/components/layout/nav-icons/today.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/components/layout/nav-icons/work.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/components/layout/nav-icons/workers.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 12 additions & 5 deletions src/components/layout/navItems.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import documentsIcon from './nav-icons/documents.svg'
import settingsIcon from './nav-icons/settings.svg'
import todayIcon from './nav-icons/today.svg'
import workIcon from './nav-icons/work.svg'
import workersIcon from './nav-icons/workers.svg'

export interface NavItem {
label: string
to: string
iconSrc: string
}

// Figma PWF v3 사이드바(Aside - SideNavBar, 05_Desktop Core Product 전 화면 공통)는 5개 메뉴만
// 정의한다. Agent/티켓 메뉴는 Figma에 없는 화면이라(#206) 링크만 제거하고 라우트는 유지한다.
// SettingsPage는 제거되어 "설정" 메뉴는 내 프로필 페이지로 연결된다.
export const NAV_ITEMS: NavItem[] = [
{ label: 'Today', to: '/dashboard' },
{ label: '업무함', to: '/tasks' },
{ label: '근로자', to: '/workers' },
{ label: '문서함', to: '/documents' },
{ label: '설정', to: '/profile' },
{ label: 'Today', to: '/dashboard', iconSrc: todayIcon },
{ label: '업무함', to: '/tasks', iconSrc: workIcon },
{ label: '근로자', to: '/workers', iconSrc: workersIcon },
{ label: '문서함', to: '/documents', iconSrc: documentsIcon },
{ label: '설정', to: '/profile', iconSrc: settingsIcon },
]
5 changes: 4 additions & 1 deletion src/components/mobile/MobileShell.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,21 @@

.title {
flex: 1;
margin: 0;
font-size: 16px;
font-weight: 500;
color: var(--text-primary);
}

.brand {
margin: 0;
font-size: 18px;
font-weight: 700;
color: var(--brand-primary);
}

.right {
margin-left: auto;
font-size: 12px;
font-weight: 500;
color: var(--text-secondary);
Expand All @@ -60,5 +63,5 @@
}

.content {
padding: 24px 20px 40px;
padding: 24px 20px 22px;
}
12 changes: 6 additions & 6 deletions src/components/mobile/MobileShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ export function MobileShell({ children, onBack, title, right, expired }: MobileS
</button>
)}
{title ? (
<p className={styles.title}>{title}</p>
) : (
<p className={styles.brand}>FOWOCO</p>
)}
{expired ? <span className={styles.expiredBadge}>만료</span> : right}
{title ? <p className={styles.title}>{title}</p> : <p className={styles.brand}>FOWOCO</p>}
{expired ? (
<span className={styles.expiredBadge}>만료</span>
) : right ? (
<span className={styles.right}>{right}</span>
) : null}
</header>
<main className={styles.content}>{children}</main>
</div>
Expand Down
Loading