style: refactor layout and enhance card UI in WeeklyManager

- Updated `WeeklyManagerPage` layout to use a `<main>` tag for better semantic structure.
- Refined `ManagerWeeklySummary` component to display narrative and metrics side by side, improving visual organization.
- Enhanced `AchievementCard` and `ChallengeCard` styles for better color differentiation and user experience.
- Adjusted spacing and grid layouts for improved responsiveness and clarity in the UI.
This commit is contained in:
Julien Froidefond
2025-09-29 22:04:38 +02:00
parent bff4f394ac
commit dc46232dd7
4 changed files with 143 additions and 109 deletions

View File

@@ -19,15 +19,13 @@ export default async function WeeklyManagerPage() {
<div className="min-h-screen bg-[var(--background)]"> <div className="min-h-screen bg-[var(--background)]">
<Header /> <Header />
<div className="container mx-auto px-4 py-8"> <main className="container mx-auto px-6 py-8">
<div className="max-w-6xl mx-auto">
<WeeklyManagerPageClient <WeeklyManagerPageClient
initialSummary={summary} initialSummary={summary}
initialTasks={initialTasks} initialTasks={initialTasks}
initialTags={initialTags} initialTags={initialTags}
/> />
</div> </main>
</div>
</div> </div>
); );
} }

View File

@@ -4,7 +4,6 @@ import { useState } from 'react';
import { ManagerSummary } from '@/services/analytics/manager-summary'; import { ManagerSummary } from '@/services/analytics/manager-summary';
import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Card, CardHeader, CardContent } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
import { MetricCard } from '@/components/ui/MetricCard';
import { Tabs, TabItem } from '@/components/ui/Tabs'; import { Tabs, TabItem } from '@/components/ui/Tabs';
import { AchievementCard } from '@/components/ui/AchievementCard'; import { AchievementCard } from '@/components/ui/AchievementCard';
import { ChallengeCard } from '@/components/ui/ChallengeCard'; import { ChallengeCard } from '@/components/ui/ChallengeCard';
@@ -73,8 +72,10 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
{/* Vue Executive / Narrative */} {/* Vue Executive / Narrative */}
{activeView === 'narrative' && ( {activeView === 'narrative' && (
<div className="space-y-6"> <div className="space-y-6">
{/* Section principale : Résumé + Métriques côte à côte */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Résumé narratif */} {/* Résumé narratif */}
<Card> <Card variant="elevated">
<CardHeader> <CardHeader>
<h2 className="text-lg font-semibold flex items-center gap-2"> <h2 className="text-lg font-semibold flex items-center gap-2">
📊 Résumé de la semaine 📊 Résumé de la semaine
@@ -83,66 +84,68 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
<CardContent className="space-y-4"> <CardContent className="space-y-4">
<div className="outline-card-blue p-4"> <div className="outline-card-blue p-4">
<h3 className="font-medium mb-2">🎯 Points clés accomplis</h3> <h3 className="font-medium mb-2">🎯 Points clés accomplis</h3>
<p>{summary.narrative.weekHighlight}</p> <p className="text-sm text-[var(--muted-foreground)]">{summary.narrative.weekHighlight}</p>
</div> </div>
<div className="outline-card-yellow p-4"> <div className="outline-card-orange p-4">
<h3 className="font-medium mb-2"> Défis traités</h3> <h3 className="font-medium mb-2"> Défis traités</h3>
<p>{summary.narrative.mainChallenges}</p> <p className="text-sm text-[var(--muted-foreground)]">{summary.narrative.mainChallenges}</p>
</div> </div>
<div className="outline-card-green p-4"> <div className="outline-card-green p-4">
<h3 className="font-medium mb-2">🔮 Focus 7 prochains jours</h3> <h3 className="font-medium mb-2">🔮 Focus 7 prochains jours</h3>
<p>{summary.narrative.nextWeekFocus}</p> <p className="text-sm text-[var(--muted-foreground)]">{summary.narrative.nextWeekFocus}</p>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
{/* Métriques rapides */} {/* Métriques rapides */}
<Card> <Card variant="elevated">
<CardHeader> <CardHeader>
<h2 className="text-lg font-semibold">📈 Métriques en bref</h2> <h2 className="text-lg font-semibold">📈 Métriques en bref</h2>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4"> <div className="grid grid-cols-2 gap-4">
<MetricCard <div className="outline-metric-blue">
title="Tâches complétées" <div className="text-2xl font-bold mb-1">{summary.metrics.totalTasksCompleted}</div>
value={summary.metrics.totalTasksCompleted} <div className="text-xs font-medium mb-1">Tâches complétées</div>
subtitle={`dont ${summary.metrics.highPriorityTasksCompleted} priorité haute`} <div className="text-xs text-[var(--muted-foreground)]">dont {summary.metrics.highPriorityTasksCompleted} priorité haute</div>
color="primary" </div>
/>
<MetricCard <div className="outline-metric-green">
title="Todos complétés" <div className="text-2xl font-bold mb-1">{summary.metrics.totalCheckboxesCompleted}</div>
value={summary.metrics.totalCheckboxesCompleted} <div className="text-xs font-medium mb-1">Todos complétés</div>
subtitle={`dont ${summary.metrics.meetingCheckboxesCompleted} meetings`} <div className="text-xs text-[var(--muted-foreground)]">dont {summary.metrics.meetingCheckboxesCompleted} meetings</div>
color="success" </div>
/>
<MetricCard <div className="outline-metric-orange">
title="Items à fort impact" <div className="text-2xl font-bold mb-1">{summary.keyAccomplishments.filter(a => a.impact === 'high').length}</div>
value={summary.keyAccomplishments.filter(a => a.impact === 'high').length} <div className="text-xs font-medium mb-1">Items à fort impact</div>
subtitle={`/ ${summary.keyAccomplishments.length} accomplissements`} <div className="text-xs text-[var(--muted-foreground)]">/ {summary.keyAccomplishments.length} accomplissements</div>
color="warning" </div>
/>
<MetricCard <div className="outline-metric-gray">
title="Priorités critiques" <div className="text-2xl font-bold mb-1">{summary.upcomingChallenges.filter(c => c.priority === 'high').length}</div>
value={summary.upcomingChallenges.filter(c => c.priority === 'high').length} <div className="text-xs font-medium mb-1">Priorités critiques</div>
subtitle={`/ ${summary.upcomingChallenges.length} enjeux`} <div className="text-xs text-[var(--muted-foreground)]">/ {summary.upcomingChallenges.length} enjeux</div>
color="destructive" </div>
/>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
</div>
{/* Top accomplissements */} {/* Top accomplissements */}
<Card> <Card variant="elevated">
<CardHeader> <CardHeader className="pb-4" style={{
<h2 className="text-lg font-semibold">🏆 Top accomplissements</h2> borderBottom: '1px solid',
borderBottomColor: 'color-mix(in srgb, var(--success) 10%, var(--border))'
}}>
<h2 className="text-lg font-semibold flex items-center gap-2" style={{ color: 'var(--success)' }}>
🏆 Top accomplissements
</h2>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{summary.keyAccomplishments.length === 0 ? ( {summary.keyAccomplishments.length === 0 ? (
<div className="col-span-3 text-center py-8 text-[var(--muted-foreground)]"> <div className="col-span-3 text-center py-8 text-[var(--muted-foreground)]">
<p>Aucun accomplissement significatif trouvé cette semaine.</p> <p>Aucun accomplissement significatif trouvé cette semaine.</p>
@@ -165,12 +168,17 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
</Card> </Card>
{/* Top challenges */} {/* Top challenges */}
<Card> <Card variant="elevated">
<CardHeader> <CardHeader className="pb-4" style={{
<h2 className="text-lg font-semibold">🎯 Top enjeux à venir</h2> borderBottom: '1px solid',
borderBottomColor: 'color-mix(in srgb, var(--destructive) 10%, var(--border))'
}}>
<h2 className="text-lg font-semibold flex items-center gap-2" style={{ color: 'var(--destructive)' }}>
🎯 Top enjeux à venir
</h2>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{summary.upcomingChallenges.length === 0 ? ( {summary.upcomingChallenges.length === 0 ? (
<div className="col-span-3 text-center py-8 text-[var(--muted-foreground)]"> <div className="col-span-3 text-center py-8 text-[var(--muted-foreground)]">
<p>Aucun enjeu prioritaire trouvé.</p> <p>Aucun enjeu prioritaire trouvé.</p>
@@ -196,14 +204,25 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
{/* Vue détaillée des accomplissements */} {/* Vue détaillée des accomplissements */}
{activeView === 'accomplishments' && ( {activeView === 'accomplishments' && (
<Card> <Card variant="elevated">
<CardHeader> <CardHeader>
<h2 className="text-lg font-semibold"> Accomplissements des 7 derniers jours</h2> <h2 className="text-lg font-semibold"> Accomplissements des 7 derniers jours</h2>
<p className="text-sm text-[var(--muted-foreground)]"> <p className="text-sm text-[var(--muted-foreground)]">
{summary.keyAccomplishments.length} accomplissements significatifs {summary.metrics.totalTasksCompleted} tâches {summary.metrics.totalCheckboxesCompleted} todos complétés {summary.keyAccomplishments.length} accomplissements significatifs {summary.metrics.totalTasksCompleted} tâches {summary.metrics.totalCheckboxesCompleted} todos complétés
</p> </p>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="space-y-6">
{summary.keyAccomplishments.length === 0 ? (
<div className="p-8 text-center rounded-xl border-2" style={{
backgroundColor: 'color-mix(in srgb, var(--muted) 15%, transparent)',
borderColor: 'color-mix(in srgb, var(--muted) 40%, var(--border))',
color: 'var(--muted-foreground)'
}}>
<div className="text-4xl mb-4">📭</div>
<p className="text-lg mb-2">Aucun accomplissement significatif trouvé cette semaine.</p>
<p className="text-sm">Ajoutez des tâches avec priorité haute/medium ou des meetings.</p>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{summary.keyAccomplishments.map((accomplishment, index) => ( {summary.keyAccomplishments.map((accomplishment, index) => (
<AchievementCard <AchievementCard
@@ -216,20 +235,32 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
/> />
))} ))}
</div> </div>
)}
</CardContent> </CardContent>
</Card> </Card>
)} )}
{/* Vue détaillée des challenges */} {/* Vue détaillée des challenges */}
{activeView === 'challenges' && ( {activeView === 'challenges' && (
<Card> <Card variant="elevated">
<CardHeader> <CardHeader>
<h2 className="text-lg font-semibold">🎯 Enjeux et défis à venir</h2> <h2 className="text-lg font-semibold">🎯 Enjeux et défis à venir</h2>
<p className="text-sm text-[var(--muted-foreground)]"> <p className="text-sm text-[var(--muted-foreground)]">
{summary.upcomingChallenges.length} défis identifiés {summary.upcomingChallenges.filter(c => c.priority === 'high').length} priorité haute {summary.upcomingChallenges.filter(c => c.blockers.length > 0).length} avec blockers {summary.upcomingChallenges.length} défis identifiés {summary.upcomingChallenges.filter(c => c.priority === 'high').length} priorité haute {summary.upcomingChallenges.filter(c => c.blockers.length > 0).length} avec blockers
</p> </p>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="space-y-6">
{summary.upcomingChallenges.length === 0 ? (
<div className="p-8 text-center rounded-xl border-2" style={{
backgroundColor: 'color-mix(in srgb, var(--muted) 15%, transparent)',
borderColor: 'color-mix(in srgb, var(--muted) 40%, var(--border))',
color: 'var(--muted-foreground)'
}}>
<div className="text-4xl mb-4">🎯</div>
<p className="text-lg mb-2">Aucun enjeu prioritaire trouvé.</p>
<p className="text-sm">Ajoutez des tâches non complétées avec priorité haute/medium.</p>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{summary.upcomingChallenges.map((challenge, index) => ( {summary.upcomingChallenges.map((challenge, index) => (
<ChallengeCard <ChallengeCard
@@ -242,6 +273,7 @@ export default function ManagerWeeklySummary({ initialSummary }: ManagerWeeklySu
/> />
))} ))}
</div> </div>
)}
</CardContent> </CardContent>
</Card> </Card>
)} )}

View File

@@ -35,7 +35,9 @@ export function AchievementCard({
className = '' className = ''
}: AchievementCardProps) { }: AchievementCardProps) {
return ( return (
<div className={`relative bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`}> <div className={`relative border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`} style={{
backgroundColor: 'color-mix(in srgb, var(--success) 5%, var(--card))'
}}>
{/* Barre colorée gauche */} {/* Barre colorée gauche */}
<div className="absolute left-0 top-0 bottom-0 w-1 bg-green-500 rounded-l-lg"></div> <div className="absolute left-0 top-0 bottom-0 w-1 bg-green-500 rounded-l-lg"></div>

View File

@@ -35,7 +35,9 @@ export function ChallengeCard({
className = '' className = ''
}: ChallengeCardProps) { }: ChallengeCardProps) {
return ( return (
<div className={`relative bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`}> <div className={`relative border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`} style={{
backgroundColor: 'color-mix(in srgb, var(--destructive) 5%, var(--card))'
}}>
{/* Barre colorée gauche */} {/* Barre colorée gauche */}
<div className="absolute left-0 top-0 bottom-0 w-1 bg-orange-500 rounded-l-lg"></div> <div className="absolute left-0 top-0 bottom-0 w-1 bg-orange-500 rounded-l-lg"></div>