diff --git a/components/HomePageClient.tsx b/components/HomePageClient.tsx index 4cf8711..d5a9517 100644 --- a/components/HomePageClient.tsx +++ b/components/HomePageClient.tsx @@ -3,7 +3,7 @@ import { Header } from '@/components/ui/Header'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; import { UserPreferencesProvider } from '@/contexts/UserPreferencesContext'; -import { Task, Tag, TaskStats, UserPreferences } from '@/lib/types'; +import { Task, Tag, UserPreferences } from '@/lib/types'; import { CreateTaskData } from '@/clients/tasks-client'; import { DashboardStats } from '@/components/dashboard/DashboardStats'; import { QuickActions } from '@/components/dashboard/QuickActions'; @@ -12,7 +12,6 @@ import { ProductivityAnalytics } from '@/components/dashboard/ProductivityAnalyt interface HomePageClientProps { initialTasks: Task[]; - initialStats: TaskStats; initialTags: (Tag & { usage: number })[]; initialPreferences: UserPreferences; } @@ -29,9 +28,8 @@ function HomePageContent() { return (
@@ -52,12 +50,11 @@ function HomePageContent() { ); } -export function HomePageClient({ initialTasks, initialStats, initialTags, initialPreferences }: HomePageClientProps) { +export function HomePageClient({ initialTasks, initialTags, initialPreferences }: HomePageClientProps) { return ( diff --git a/components/ui/Header.tsx b/components/ui/Header.tsx index 21cbe11..bef99a6 100644 --- a/components/ui/Header.tsx +++ b/components/ui/Header.tsx @@ -1,21 +1,20 @@ -import { Card, CardContent } from '@/components/ui/Card'; -import { TaskStats } from '@/lib/types'; import { useTheme } from '@/contexts/ThemeContext'; import { useJiraConfig } from '@/contexts/JiraConfigContext'; import { usePathname } from 'next/navigation'; import Link from 'next/link'; +import { useState } from 'react'; interface HeaderProps { title?: string; subtitle?: string; - stats?: TaskStats; syncing?: boolean; } -export function Header({ title = "TowerControl", subtitle = "Task Management", stats, syncing = false }: HeaderProps) { +export function Header({ title = "TowerControl", subtitle = "Task Management", syncing = false }: HeaderProps) { const { theme, toggleTheme } = useTheme(); const { isConfigured: isJiraConfigured, config: jiraConfig } = useJiraConfig(); const pathname = usePathname(); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); // Fonction pour déterminer si un lien est actif const isActiveLink = (href: string) => { @@ -25,7 +24,7 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s return pathname.startsWith(href); }; - // Fonction pour obtenir les classes CSS d'un lien + // Fonction pour obtenir les classes CSS d'un lien (desktop) const getLinkClasses = (href: string) => { const baseClasses = "font-mono text-sm uppercase tracking-wider transition-colors px-3 py-1.5 rounded-md"; @@ -36,11 +35,92 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s return `${baseClasses} text-[var(--muted-foreground)] hover:text-[var(--primary)] hover:bg-[var(--card-hover)]`; }; + // Fonction pour obtenir les classes CSS d'un lien (mobile) + const getMobileLinkClasses = (href: string) => { + const baseClasses = "font-mono text-sm uppercase tracking-wider transition-colors px-4 py-3 rounded-md block w-full text-left"; + + if (isActiveLink(href)) { + return `${baseClasses} text-[var(--primary)] bg-[var(--primary)]/10 border border-[var(--primary)]/30`; + } + + return `${baseClasses} text-[var(--muted-foreground)] hover:text-[var(--primary)] hover:bg-[var(--card-hover)]`; + }; + + // Liste des liens de navigation + const navLinks = [ + { href: '/', label: 'Dashboard' }, + { href: '/kanban', label: 'Kanban' }, + { href: '/daily', label: 'Daily' }, + { href: '/tags', label: 'Tags' }, + ...(isJiraConfigured ? [{ href: '/jira-dashboard', label: `Jira${jiraConfig?.projectKey ? ` (${jiraConfig.projectKey})` : ''}` }] : []), + { href: '/settings', label: 'Settings' } + ]; + return ( -
-
-
- {/* Titre tech avec glow */} +
+
+ {/* Layout mobile/tablette */} +
+
+ {/* Titre et status */} +
+
+
+

+ {title} +

+

+ {subtitle} +

+
+
+ + {/* Controls mobile/tablette */} +
+ {/* Theme Toggle */} + + + {/* Menu burger */} + +
+
+
+ + {/* Layout desktop - une seule ligne comme avant */} +
+ {/* Titre et status */}
- {/* Navigation */} -
- {/* Stats essentielles - seulement si stats disponibles */} - {stats && ( -
- - - - -
- )}
+
+ + {/* Menu mobile/tablette en overlay fixe */} + {mobileMenuOpen && ( + <> + {/* Backdrop pour fermer le menu */} +
setMobileMenuOpen(false)} + /> + {/* Menu */} +
+ +
+ + )}
); } -interface StatCardProps { - label: string; - value: number | string; - color: 'blue' | 'green' | 'yellow' | 'gray' | 'purple'; -} - -function StatCard({ label, value, color }: StatCardProps) { - - const textColors = { - blue: 'text-[var(--primary)]', - green: 'text-[var(--success)]', - yellow: 'text-[var(--accent)]', - gray: 'text-[var(--muted-foreground)]', - purple: 'text-[var(--accent)]' - }; - - return ( - - -
- {label} -
-
- {value} -
-
-
- ); -} diff --git a/components/ui/HeaderContainer.tsx b/components/ui/HeaderContainer.tsx index bd17b27..36534e0 100644 --- a/components/ui/HeaderContainer.tsx +++ b/components/ui/HeaderContainer.tsx @@ -6,30 +6,15 @@ import { useTasks } from '@/hooks/useTasks'; interface HeaderContainerProps { title: string; subtitle: string; - initialStats: { - total: number; - completed: number; - inProgress: number; - todo: number; - backlog: number; - cancelled: number; - freeze: number; - archived: number; - completionRate: number; - }; } -export function HeaderContainer({ title, subtitle, initialStats }: HeaderContainerProps) { - const { stats, syncing } = useTasks( - { limit: 1 }, // Juste pour les stats - { tasks: [], stats: { ...initialStats, backlog: 0, cancelled: 0, freeze: 0, archived: 0 } } - ); +export function HeaderContainer({ title, subtitle }: HeaderContainerProps) { + const { syncing } = useTasks(); return (
); diff --git a/hooks/useTasks.ts b/hooks/useTasks.ts index 424aa76..2762ffb 100644 --- a/hooks/useTasks.ts +++ b/hooks/useTasks.ts @@ -25,7 +25,7 @@ interface UseTasksActions { */ export function useTasks( initialFilters?: TaskFilters, - initialData?: { tasks: Task[]; stats: TaskStats } + initialData?: { tasks: Task[]; stats?: TaskStats } ): UseTasksState & UseTasksActions { const [state, setState] = useState({ tasks: initialData?.tasks || [], diff --git a/src/app/kanban/KanbanPageClient.tsx b/src/app/kanban/KanbanPageClient.tsx index cf008e5..3c39cd1 100644 --- a/src/app/kanban/KanbanPageClient.tsx +++ b/src/app/kanban/KanbanPageClient.tsx @@ -5,7 +5,7 @@ import { KanbanBoardContainer } from '@/components/kanban/BoardContainer'; import { Header } from '@/components/ui/Header'; import { TasksProvider, useTasksContext } from '@/contexts/TasksContext'; import { UserPreferencesProvider, useUserPreferences } from '@/contexts/UserPreferencesContext'; -import { Task, Tag, TaskStats, UserPreferences } from '@/lib/types'; +import { Task, Tag, UserPreferences } from '@/lib/types'; import { CreateTaskData } from '@/clients/tasks-client'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { Button } from '@/components/ui/Button'; @@ -14,13 +14,12 @@ import { FontSizeToggle } from '@/components/ui/FontSizeToggle'; interface KanbanPageClientProps { initialTasks: Task[]; - initialStats: TaskStats; initialTags: (Tag & { usage: number })[]; initialPreferences: UserPreferences; } function KanbanPageContent() { - const { stats, syncing, createTask, activeFiltersCount, kanbanFilters, setKanbanFilters } = useTasksContext(); + const { syncing, createTask, activeFiltersCount, kanbanFilters, setKanbanFilters } = useTasksContext(); const { preferences, updateViewPreferences } = useUserPreferences(); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); @@ -58,7 +57,6 @@ function KanbanPageContent() {
@@ -181,12 +179,11 @@ function KanbanPageContent() { ); } -export function KanbanPageClient({ initialTasks, initialStats, initialTags, initialPreferences }: KanbanPageClientProps) { +export function KanbanPageClient({ initialTasks, initialTags, initialPreferences }: KanbanPageClientProps) { return ( diff --git a/src/app/kanban/page.tsx b/src/app/kanban/page.tsx index 7a9e051..54be739 100644 --- a/src/app/kanban/page.tsx +++ b/src/app/kanban/page.tsx @@ -8,9 +8,8 @@ export const dynamic = 'force-dynamic'; export default async function KanbanPage() { // SSR - Récupération des données côté serveur - const [initialTasks, initialStats, initialTags, initialPreferences] = await Promise.all([ + const [initialTasks, initialTags, initialPreferences] = await Promise.all([ tasksService.getTasks(), - tasksService.getTaskStats(), tagsService.getTags(), userPreferencesService.getAllPreferences() ]); @@ -18,7 +17,6 @@ export default async function KanbanPage() { return ( diff --git a/src/app/page.tsx b/src/app/page.tsx index d795972..7e98180 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -8,9 +8,8 @@ export const dynamic = 'force-dynamic'; export default async function HomePage() { // SSR - Récupération des données côté serveur - const [initialTasks, initialStats, initialTags, initialPreferences] = await Promise.all([ + const [initialTasks, initialTags, initialPreferences] = await Promise.all([ tasksService.getTasks(), - tasksService.getTaskStats(), tagsService.getTags(), userPreferencesService.getAllPreferences() ]); @@ -18,7 +17,6 @@ export default async function HomePage() { return ( diff --git a/src/contexts/TasksContext.tsx b/src/contexts/TasksContext.tsx index c816c09..e1bd189 100644 --- a/src/contexts/TasksContext.tsx +++ b/src/contexts/TasksContext.tsx @@ -37,14 +37,13 @@ const TasksContext = createContext(null); interface TasksProviderProps { children: ReactNode; initialTasks: Task[]; - initialStats: TaskStats; initialTags?: (Tag & { usage: number })[]; } -export function TasksProvider({ children, initialTasks, initialStats, initialTags }: TasksProviderProps) { +export function TasksProvider({ children, initialTasks, initialTags }: TasksProviderProps) { const tasksState = useTasks( { limit: 20 }, - { tasks: initialTasks, stats: initialStats } + { tasks: initialTasks } ); const { tags, loading: tagsLoading, error: tagsError } = useTags(initialTags);