feat: refactor Daily components and enhance UI integration
- Replaced `DailyCalendar` with a new `Calendar` component for improved functionality and consistency. - Introduced `AlertBanner` to replace `DeadlineReminder`, providing a more flexible way to display urgent tasks. - Updated `DailyAddForm` to use new options for task types, enhancing user experience when adding tasks. - Removed unused state and components, streamlining the DailyPageClient for better performance and maintainability. - Enhanced `DailySection` to utilize new `CheckboxItem` format for better integration with the UI. - Cleaned up imports and improved overall structure for better readability.
This commit is contained in:
@@ -4,15 +4,111 @@
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
import { Alert, AlertTitle, AlertDescription } from '@/components/ui/Alert';
|
||||
import { Alert as ShadcnAlert, AlertTitle, AlertDescription } from '@/components/ui/Alert';
|
||||
import { Input } from '@/components/ui/Input';
|
||||
import { StyledCard } from '@/components/ui/StyledCard';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';
|
||||
import { StatCard, ProgressBar, ActionCard, TaskCard, MetricCard, ToggleButton, SearchInput, ControlPanel, ControlSection, ControlGroup, FilterSummary, FilterChip, ColumnHeader, EmptyState, DropZone } from '@/components/ui';
|
||||
import { StatCard, ProgressBar, ActionCard, TaskCard, MetricCard, ToggleButton, SearchInput, ControlPanel, ControlSection, ControlGroup, FilterSummary, FilterChip, ColumnHeader, EmptyState, DropZone, Tabs, PriorityBadge, AchievementCard, ChallengeCard } from '@/components/ui';
|
||||
import { CheckboxItem, CheckboxItemData } from '@/components/ui/CheckboxItem';
|
||||
import { Calendar } from '@/components/ui/Calendar';
|
||||
import { DailyAddForm } from '@/components/ui/DailyAddForm';
|
||||
import { AlertBanner, AlertItem } from '@/components/ui/AlertBanner';
|
||||
import { CollapsibleSection, CollapsibleItem } from '@/components/ui/CollapsibleSection';
|
||||
import { Header } from '@/components/ui/Header';
|
||||
import { TabItem } from '@/components/ui/Tabs';
|
||||
import { AchievementData } from '@/components/ui/AchievementCard';
|
||||
import { ChallengeData } from '@/components/ui/ChallengeCard';
|
||||
|
||||
export function UIShowcaseClient() {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [checkboxItems, setCheckboxItems] = useState<CheckboxItemData[]>([
|
||||
{ id: '1', text: 'Tâche complétée', isChecked: true, type: 'task' },
|
||||
{ id: '2', text: 'Réunion importante', isChecked: false, type: 'meeting' },
|
||||
{ id: '3', text: 'Tâche en cours', isChecked: false, type: 'task' }
|
||||
]);
|
||||
const [alertItems] = useState<AlertItem[]>([
|
||||
{ id: '1', title: 'Tâche critique', icon: '🔴', urgency: 'critical', metadata: 'Dans 1 jour' },
|
||||
{ id: '2', title: 'Réunion urgente', icon: '🟠', urgency: 'high', metadata: 'Dans 2 jours' },
|
||||
{ id: '3', title: 'Rappel', icon: '🟡', urgency: 'medium', metadata: 'Dans 5 jours' }
|
||||
]);
|
||||
const [collapsibleItems] = useState<CollapsibleItem[]>([
|
||||
{
|
||||
id: '1',
|
||||
title: 'Tâche en attente',
|
||||
subtitle: '15 Jan 2024',
|
||||
metadata: 'Il y a 2 jours',
|
||||
isChecked: false,
|
||||
icon: '📋',
|
||||
actions: [
|
||||
{ label: 'Déplacer', icon: '📅', onClick: () => console.log('Move'), variant: 'primary' },
|
||||
{ label: 'Supprimer', icon: '🗑️', onClick: () => console.log('Delete'), variant: 'destructive' }
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
// Données pour les composants Weekly Manager
|
||||
const [activeTab, setActiveTab] = useState('tab1');
|
||||
const tabItems: TabItem[] = [
|
||||
{ id: 'tab1', label: 'Vue Executive', icon: '📝' },
|
||||
{ id: 'tab2', label: 'Accomplissements', icon: '✅', count: 5 },
|
||||
{ id: 'tab3', label: 'Enjeux', icon: '🎯', count: 3 },
|
||||
{ id: 'tab4', label: 'Métriques', icon: '📊' }
|
||||
];
|
||||
|
||||
const sampleAchievements: AchievementData[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Refactoring de la page Daily',
|
||||
description: 'Migration vers les composants UI génériques',
|
||||
impact: 'high',
|
||||
completedAt: new Date(),
|
||||
tags: ['refactoring', 'ui'],
|
||||
todosCount: 8
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Implémentation du système de thèmes',
|
||||
description: 'Ajout de 10 nouveaux thèmes avec CSS variables',
|
||||
impact: 'medium',
|
||||
completedAt: new Date(Date.now() - 86400000),
|
||||
tags: ['themes', 'css'],
|
||||
todosCount: 3
|
||||
}
|
||||
];
|
||||
|
||||
const sampleChallenges: ChallengeData[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Migration vers Next.js 15',
|
||||
description: 'Mise à jour majeure avec nouvelles fonctionnalités',
|
||||
priority: 'high',
|
||||
deadline: new Date(Date.now() + 7 * 86400000),
|
||||
tags: ['migration', 'nextjs'],
|
||||
todosCount: 12,
|
||||
blockers: ['Tests à mettre à jour']
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Optimisation des performances',
|
||||
description: 'Réduction du temps de chargement',
|
||||
priority: 'medium',
|
||||
deadline: new Date(Date.now() + 14 * 86400000),
|
||||
tags: ['performance', 'optimization'],
|
||||
todosCount: 5
|
||||
}
|
||||
];
|
||||
|
||||
const sampleTags = [
|
||||
{ id: '1', name: 'refactoring', color: '#3b82f6', usage: 5 },
|
||||
{ id: '2', name: 'ui', color: '#10b981', usage: 8 },
|
||||
{ id: '3', name: 'themes', color: '#8b5cf6', usage: 3 },
|
||||
{ id: '4', name: 'css', color: '#f59e0b', usage: 4 },
|
||||
{ id: '5', name: 'migration', color: '#ef4444', usage: 2 },
|
||||
{ id: '6', name: 'nextjs', color: '#06b6d4', usage: 3 },
|
||||
{ id: '7', name: 'performance', color: '#84cc16', usage: 6 },
|
||||
{ id: '8', name: 'optimization', color: '#f97316', usage: 2 }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--background)]">
|
||||
@@ -93,40 +189,40 @@ export function UIShowcaseClient() {
|
||||
</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<Alert variant="default">
|
||||
<ShadcnAlert variant="default">
|
||||
<AlertTitle>Information</AlertTitle>
|
||||
<AlertDescription>
|
||||
Ceci est une alerte par défaut avec des informations importantes.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<Alert variant="success">
|
||||
<ShadcnAlert variant="success">
|
||||
<AlertTitle>Succès</AlertTitle>
|
||||
<AlertDescription>
|
||||
Opération terminée avec succès ! Toutes les données ont été sauvegardées.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<Alert variant="destructive">
|
||||
<ShadcnAlert variant="destructive">
|
||||
<AlertTitle>Erreur</AlertTitle>
|
||||
<AlertDescription>
|
||||
Une erreur s'est produite lors du traitement de votre demande.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<Alert variant="warning">
|
||||
<ShadcnAlert variant="warning">
|
||||
<AlertTitle>Attention</AlertTitle>
|
||||
<AlertDescription>
|
||||
Veuillez vérifier vos informations avant de continuer.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<Alert variant="info">
|
||||
<ShadcnAlert variant="info">
|
||||
<AlertTitle>Conseil</AlertTitle>
|
||||
<AlertDescription>
|
||||
Astuce : Vous pouvez utiliser les raccourcis clavier pour naviguer plus rapidement.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -322,19 +418,19 @@ export function UIShowcaseClient() {
|
||||
<CardTitle>Notifications</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<Alert variant="success">
|
||||
<ShadcnAlert variant="success">
|
||||
<AlertTitle>Bienvenue !</AlertTitle>
|
||||
<AlertDescription>
|
||||
Votre compte a été créé avec succès.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<Alert variant="warning">
|
||||
<ShadcnAlert variant="warning">
|
||||
<AlertTitle>Mise à jour disponible</AlertTitle>
|
||||
<AlertDescription>
|
||||
Une nouvelle version de l'application est disponible.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</ShadcnAlert>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button size="sm">Voir les détails</Button>
|
||||
@@ -985,6 +1081,247 @@ export function UIShowcaseClient() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Daily Components Section */}
|
||||
<section className="space-y-8">
|
||||
<h2 className="text-2xl font-mono font-semibold text-[var(--foreground)] border-b border-[var(--border)] pb-3">
|
||||
Daily Components
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
{/* CheckboxItem */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">CheckboxItem</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
CheckboxItem - Élément de liste avec checkbox
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{checkboxItems.map((item) => (
|
||||
<CheckboxItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
onToggle={async (id) => {
|
||||
setCheckboxItems(prev =>
|
||||
prev.map(item =>
|
||||
item.id === id ? { ...item, isChecked: !item.isChecked } : item
|
||||
)
|
||||
);
|
||||
}}
|
||||
onUpdate={async (id, text) => {
|
||||
setCheckboxItems(prev =>
|
||||
prev.map(item =>
|
||||
item.id === id ? { ...item, text } : item
|
||||
)
|
||||
);
|
||||
}}
|
||||
onDelete={async (id) => {
|
||||
setCheckboxItems(prev => prev.filter(item => item.id !== id));
|
||||
}}
|
||||
saving={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Calendar */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">Calendar</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
Calendar - Calendrier avec dates marquées
|
||||
</div>
|
||||
<div className="max-w-sm">
|
||||
<Calendar
|
||||
currentDate={selectedDate}
|
||||
onDateSelect={setSelectedDate}
|
||||
markedDates={['2024-01-15', '2024-01-20', '2024-01-25']}
|
||||
showTodayButton={true}
|
||||
showLegend={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AddForm */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">DailyAddForm</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
DailyAddForm - Formulaire d'ajout avec options
|
||||
</div>
|
||||
<div className="max-w-md">
|
||||
<DailyAddForm
|
||||
onAdd={async (text, option) => {
|
||||
console.log('Adding:', text, option);
|
||||
const newItem: CheckboxItemData = {
|
||||
id: Date.now().toString(),
|
||||
text,
|
||||
isChecked: false,
|
||||
type: option as 'task' | 'meeting'
|
||||
};
|
||||
setCheckboxItems(prev => [...prev, newItem]);
|
||||
}}
|
||||
placeholder="Ajouter une tâche..."
|
||||
options={[
|
||||
{ value: 'task', label: 'Tâche', icon: '✅', color: 'green' },
|
||||
{ value: 'meeting', label: 'Réunion', icon: '🗓️', color: 'blue' }
|
||||
]}
|
||||
defaultOption="task"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Alert */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">Alert</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
Alert - Alerte avec éléments urgents
|
||||
</div>
|
||||
<div className="max-w-md">
|
||||
<AlertBanner
|
||||
title="Tâches urgentes"
|
||||
items={alertItems}
|
||||
icon="⚠️"
|
||||
variant="warning"
|
||||
onItemClick={(item) => console.log('Clicked:', item)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CollapsibleSection */}
|
||||
<div className="space-y-6 lg:col-span-2">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">CollapsibleSection</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
CollapsibleSection - Section repliable avec éléments
|
||||
</div>
|
||||
<div className="max-w-2xl">
|
||||
<CollapsibleSection
|
||||
title="Tâches en attente"
|
||||
items={collapsibleItems}
|
||||
icon="📋"
|
||||
defaultCollapsed={false}
|
||||
loading={false}
|
||||
emptyMessage="Aucune tâche en attente"
|
||||
onRefresh={() => console.log('Refresh')}
|
||||
onItemToggle={(id) => console.log('Toggle:', id)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Weekly Manager Components Section */}
|
||||
<section className="space-y-8">
|
||||
<h2 className="text-2xl font-mono font-semibold text-[var(--foreground)] border-b border-[var(--border)] pb-3">
|
||||
Weekly Manager Components
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
{/* Tabs */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">Tabs</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
Tabs - Navigation par onglets
|
||||
</div>
|
||||
<Tabs
|
||||
items={tabItems}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
/>
|
||||
<div className="text-xs text-[var(--muted-foreground)]">
|
||||
Onglet actif: {activeTab}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PriorityBadge */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">PriorityBadge</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
PriorityBadge - Badge de priorité
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<PriorityBadge priority="high" />
|
||||
<PriorityBadge priority="medium" />
|
||||
<PriorityBadge priority="low" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
{/* AchievementCard */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">AchievementCard</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
AchievementCard - Carte d'accomplissement
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{sampleAchievements.map((achievement, index) => (
|
||||
<AchievementCard
|
||||
key={achievement.id}
|
||||
achievement={achievement}
|
||||
availableTags={sampleTags}
|
||||
index={index}
|
||||
showDescription={true}
|
||||
maxTags={2}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ChallengeCard */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-lg font-medium text-[var(--foreground)]">ChallengeCard</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-mono text-[var(--muted-foreground)] bg-[var(--card)] px-2 py-1 rounded">
|
||||
ChallengeCard - Carte de défi
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{sampleChallenges.map((challenge, index) => (
|
||||
<ChallengeCard
|
||||
key={challenge.id}
|
||||
challenge={challenge}
|
||||
availableTags={sampleTags}
|
||||
index={index}
|
||||
showDescription={true}
|
||||
maxTags={2}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="text-center pt-8 border-t border-[var(--border)]">
|
||||
<p className="text-[var(--muted-foreground)]">
|
||||
|
||||
Reference in New Issue
Block a user