feat: complete Scrum-manager MVP — dark-themed multi-user task manager
- Login with role-based auth (CTO/Manager/Employee) - Calendar view (month/week) with task chips and quick-add - Kanban board with status columns - Sortable list view with action menus - Task detail drawer with subtasks, comments, activity - Add task modal with validation - Dashboard with stats, workload, priority breakdown - Team tasks grouped by assignee - Reports page with recharts (bar, pie, line, horizontal bar) - Members page with invite modal - Search and assignee filter across views - ErrorBoundary for production error handling - Full dark design system via index.css
This commit is contained in:
56
src/NavBars.tsx
Normal file
56
src/NavBars.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { USERS } from './data';
|
||||
|
||||
|
||||
interface TopNavbarProps {
|
||||
title: string;
|
||||
filterUser: string | null;
|
||||
onFilterChange: (uid: string | null) => void;
|
||||
searchQuery: string;
|
||||
onSearch: (q: string) => void;
|
||||
onNewTask: () => void;
|
||||
}
|
||||
|
||||
export function TopNavbar({ title, filterUser, onFilterChange, searchQuery, onSearch, onNewTask }: TopNavbarProps) {
|
||||
return (
|
||||
<div className="top-navbar">
|
||||
<span className="navbar-title">{title}</span>
|
||||
<div className="navbar-search">
|
||||
<span className="navbar-search-icon">🔍</span>
|
||||
<input placeholder="Search tasks..." value={searchQuery} onChange={e => onSearch(e.target.value)} />
|
||||
</div>
|
||||
<div className="navbar-right">
|
||||
<div className="filter-chips">
|
||||
<span className={`filter-chip filter-chip-all ${!filterUser ? 'active' : ''}`} onClick={() => onFilterChange(null)}>All</span>
|
||||
{USERS.map(u => (
|
||||
<div key={u.id} className={`filter-chip ${filterUser === u.id ? 'active' : ''}`}
|
||||
style={{ background: u.color, borderColor: filterUser === u.id ? u.color : 'transparent' }}
|
||||
title={u.name} onClick={() => onFilterChange(u.id === filterUser ? null : u.id)}>
|
||||
{u.avatar}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button className="notif-btn">🔔<span className="notif-badge">3</span></button>
|
||||
<button className="new-task-btn" onClick={onNewTask}>+ New Task</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface BottomToggleBarProps {
|
||||
activeView: string;
|
||||
onViewChange: (v: string) => void;
|
||||
}
|
||||
|
||||
export function BottomToggleBar({ activeView, onViewChange }: BottomToggleBarProps) {
|
||||
return (
|
||||
<div className="bottom-bar">
|
||||
<div className="toggle-pill">
|
||||
{[{ id: 'calendar', icon: '📅', label: 'Calendar' }, { id: 'kanban', icon: '▦', label: 'Kanban' }, { id: 'list', icon: '☰', label: 'List' }].map(v => (
|
||||
<button key={v.id} className={`toggle-btn ${activeView === v.id ? 'active' : ''}`} onClick={() => onViewChange(v.id)}>
|
||||
{v.icon} {v.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user