feat: replace SVGs with lucide-react icons across components
- Updated ProfilePage, AuthButton, RecentTasks, WelcomeSection, DesktopControls, MobileControls, and various Kanban components to use lucide-react icons instead of SVGs for improved consistency and maintainability. - Icons replaced include Check, User, Mail, Calendar, Shield, Save, X, Loader2, Filter, Target, List, Grid3X3, ChevronDown, ChevronRight, Edit, Trash2, and Plus.
This commit is contained in:
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/Button'
|
|||||||
import { Input } from '@/components/ui/Input'
|
import { Input } from '@/components/ui/Input'
|
||||||
import { Header } from '@/components/ui/Header'
|
import { Header } from '@/components/ui/Header'
|
||||||
import { updateProfile, getProfile } from '@/actions/profile'
|
import { updateProfile, getProfile } from '@/actions/profile'
|
||||||
|
import { Check, User, Mail, Calendar, Shield, Save, X, Loader2 } from 'lucide-react'
|
||||||
|
|
||||||
interface UserProfile {
|
interface UserProfile {
|
||||||
id: string
|
id: string
|
||||||
@@ -155,16 +156,12 @@ export default function ProfilePage() {
|
|||||||
className="w-24 h-24 rounded-full object-cover border-4 border-[var(--primary)]/30 shadow-lg"
|
className="w-24 h-24 rounded-full object-cover border-4 border-[var(--primary)]/30 shadow-lg"
|
||||||
/>
|
/>
|
||||||
<div className="absolute -bottom-2 -right-2 w-8 h-8 bg-[var(--success)] rounded-full border-4 border-[var(--card)] flex items-center justify-center">
|
<div className="absolute -bottom-2 -right-2 w-8 h-8 bg-[var(--success)] rounded-full border-4 border-[var(--card)] flex items-center justify-center">
|
||||||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
|
<Check className="w-4 h-4 text-white" />
|
||||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-24 h-24 rounded-full bg-[var(--primary)]/20 border-4 border-[var(--primary)]/30 flex items-center justify-center">
|
<div className="w-24 h-24 rounded-full bg-[var(--primary)]/20 border-4 border-[var(--primary)]/30 flex items-center justify-center">
|
||||||
<svg className="w-12 h-12 text-[var(--primary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<User className="w-12 h-12 text-[var(--primary)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -182,9 +179,7 @@ export default function ProfilePage() {
|
|||||||
<span className="text-sm font-medium text-[var(--foreground)]">{profile.role}</span>
|
<span className="text-sm font-medium text-[var(--foreground)]">{profile.role}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 px-3 py-1 bg-[var(--card)] rounded-full border border-[var(--border)]">
|
<div className="flex items-center gap-2 px-3 py-1 bg-[var(--card)] rounded-full border border-[var(--border)]">
|
||||||
<svg className="w-4 h-4 text-[var(--muted-foreground)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Calendar className="w-4 h-4 text-[var(--muted-foreground)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
<span className="text-sm text-[var(--muted-foreground)]">
|
<span className="text-sm text-[var(--muted-foreground)]">
|
||||||
Membre depuis {new Date(profile.createdAt).toLocaleDateString('fr-FR')}
|
Membre depuis {new Date(profile.createdAt).toLocaleDateString('fr-FR')}
|
||||||
</span>
|
</span>
|
||||||
@@ -198,17 +193,13 @@ export default function ProfilePage() {
|
|||||||
{/* Informations générales */}
|
{/* Informations générales */}
|
||||||
<div className="bg-[var(--card)] rounded-xl p-6 border border-[var(--border)]">
|
<div className="bg-[var(--card)] rounded-xl p-6 border border-[var(--border)]">
|
||||||
<h2 className="text-xl font-mono font-bold text-[var(--foreground)] mb-6 flex items-center gap-2">
|
<h2 className="text-xl font-mono font-bold text-[var(--foreground)] mb-6 flex items-center gap-2">
|
||||||
<svg className="w-5 h-5 text-[var(--primary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<User className="w-5 h-5 text-[var(--primary)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
Informations générales
|
Informations générales
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
||||||
<svg className="w-5 h-5 text-[var(--muted-foreground)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Mail className="w-5 h-5 text-[var(--muted-foreground)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207" />
|
|
||||||
</svg>
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-[var(--foreground)] font-medium">{profile.email}</div>
|
<div className="text-[var(--foreground)] font-medium">{profile.email}</div>
|
||||||
<div className="text-xs text-[var(--muted-foreground)]">Email principal</div>
|
<div className="text-xs text-[var(--muted-foreground)]">Email principal</div>
|
||||||
@@ -216,9 +207,7 @@ export default function ProfilePage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
||||||
<svg className="w-5 h-5 text-[var(--muted-foreground)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Shield className="w-5 h-5 text-[var(--muted-foreground)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-[var(--foreground)] font-medium">{profile.role}</div>
|
<div className="text-[var(--foreground)] font-medium">{profile.role}</div>
|
||||||
<div className="text-xs text-[var(--muted-foreground)]">Rôle utilisateur</div>
|
<div className="text-xs text-[var(--muted-foreground)]">Rôle utilisateur</div>
|
||||||
@@ -227,9 +216,7 @@ export default function ProfilePage() {
|
|||||||
|
|
||||||
{profile.lastLoginAt && (
|
{profile.lastLoginAt && (
|
||||||
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
<div className="flex items-center gap-3 p-3 bg-[var(--input)] rounded-lg border border-[var(--border)]">
|
||||||
<svg className="w-5 h-5 text-[var(--muted-foreground)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Calendar className="w-5 h-5 text-[var(--muted-foreground)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<div>
|
<div>
|
||||||
<div className="text-[var(--foreground)] font-medium">
|
<div className="text-[var(--foreground)] font-medium">
|
||||||
{new Date(profile.lastLoginAt).toLocaleString('fr-FR')}
|
{new Date(profile.lastLoginAt).toLocaleString('fr-FR')}
|
||||||
@@ -244,9 +231,7 @@ export default function ProfilePage() {
|
|||||||
{/* Formulaire de modification */}
|
{/* Formulaire de modification */}
|
||||||
<div className="bg-[var(--card)] rounded-xl p-6 border border-[var(--border)]">
|
<div className="bg-[var(--card)] rounded-xl p-6 border border-[var(--border)]">
|
||||||
<h2 className="text-xl font-mono font-bold text-[var(--foreground)] mb-6 flex items-center gap-2">
|
<h2 className="text-xl font-mono font-bold text-[var(--foreground)] mb-6 flex items-center gap-2">
|
||||||
<svg className="w-5 h-5 text-[var(--primary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<User className="w-5 h-5 text-[var(--primary)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
|
||||||
</svg>
|
|
||||||
Modifier le profil
|
Modifier le profil
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -320,18 +305,14 @@ export default function ProfilePage() {
|
|||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<div className="flex items-center gap-2 p-3 bg-[var(--destructive)]/10 border border-[var(--destructive)]/30 rounded-lg">
|
<div className="flex items-center gap-2 p-3 bg-[var(--destructive)]/10 border border-[var(--destructive)]/30 rounded-lg">
|
||||||
<svg className="w-5 h-5 text-[var(--destructive)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<X className="w-5 h-5 text-[var(--destructive)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span className="text-[var(--destructive)] text-sm">{error}</span>
|
<span className="text-[var(--destructive)] text-sm">{error}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{success && (
|
{success && (
|
||||||
<div className="flex items-center gap-2 p-3 bg-[var(--success)]/10 border border-[var(--success)]/30 rounded-lg">
|
<div className="flex items-center gap-2 p-3 bg-[var(--success)]/10 border border-[var(--success)]/30 rounded-lg">
|
||||||
<svg className="w-5 h-5 text-[var(--success)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Check className="w-5 h-5 text-[var(--success)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span className="text-[var(--success)] text-sm">{success}</span>
|
<span className="text-[var(--success)] text-sm">{success}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -344,16 +325,12 @@ export default function ProfilePage() {
|
|||||||
>
|
>
|
||||||
{isPending ? (
|
{isPending ? (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<svg className="w-4 h-4 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
||||||
</svg>
|
|
||||||
Sauvegarde...
|
Sauvegarde...
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Save className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
||||||
</svg>
|
|
||||||
Sauvegarder les modifications
|
Sauvegarder les modifications
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { useSession, signOut } from 'next-auth/react'
|
import { useSession, signOut } from 'next-auth/react'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { Button } from '@/components/ui/Button'
|
import { Button } from '@/components/ui/Button'
|
||||||
|
import { User, LogOut } from 'lucide-react'
|
||||||
|
|
||||||
export function AuthButton() {
|
export function AuthButton() {
|
||||||
const { data: session, status } = useSession()
|
const { data: session, status } = useSession()
|
||||||
@@ -44,9 +45,7 @@ export function AuthButton() {
|
|||||||
className="w-10 h-10 rounded-full object-cover"
|
className="w-10 h-10 rounded-full object-cover"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<User className="w-6 h-6" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
||||||
</svg>
|
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
@@ -56,9 +55,7 @@ export function AuthButton() {
|
|||||||
className="p-1 h-auto"
|
className="p-1 h-auto"
|
||||||
title="Déconnexion"
|
title="Déconnexion"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<LogOut className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
|
||||||
</svg>
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Card } from '@/components/ui/Card';
|
|||||||
import { RecentTaskTimeline } from '@/components/ui/RecentTaskTimeline';
|
import { RecentTaskTimeline } from '@/components/ui/RecentTaskTimeline';
|
||||||
import { useTasksContext } from '@/contexts/TasksContext';
|
import { useTasksContext } from '@/contexts/TasksContext';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { Clipboard } from 'lucide-react';
|
||||||
|
|
||||||
interface RecentTasksProps {
|
interface RecentTasksProps {
|
||||||
tasks: Task[];
|
tasks: Task[];
|
||||||
@@ -49,9 +50,7 @@ export function RecentTasks({ tasks, selectedSources = [], hiddenSources = [] }:
|
|||||||
|
|
||||||
{recentTasks.length === 0 ? (
|
{recentTasks.length === 0 ? (
|
||||||
<div className="text-center py-8 text-[var(--muted-foreground)]">
|
<div className="text-center py-8 text-[var(--muted-foreground)]">
|
||||||
<svg className="w-12 h-12 mx-auto mb-3 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Clipboard className="w-12 h-12 mx-auto mb-3 opacity-50" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
|
||||||
</svg>
|
|
||||||
<p>Aucune tâche disponible</p>
|
<p>Aucune tâche disponible</p>
|
||||||
<p className="text-sm">Créez votre première tâche pour commencer</p>
|
<p className="text-sm">Créez votre première tâche pour commencer</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import { useState, useEffect, useRef } from 'react';
|
import { useState, useEffect, useRef } from 'react';
|
||||||
|
import { Check, User, ArrowRight } from 'lucide-react';
|
||||||
|
|
||||||
const WELCOME_GREETINGS = [
|
const WELCOME_GREETINGS = [
|
||||||
"Bienvenue",
|
"Bienvenue",
|
||||||
@@ -216,16 +217,12 @@ export function WelcomeSection() {
|
|||||||
className="relative w-20 h-20 rounded-full object-cover border-4 border-[var(--primary)]/40 shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:border-[var(--accent)]/60"
|
className="relative w-20 h-20 rounded-full object-cover border-4 border-[var(--primary)]/40 shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:border-[var(--accent)]/60"
|
||||||
/>
|
/>
|
||||||
<div className="absolute -bottom-2 -right-2 w-7 h-7 bg-gradient-to-r from-[var(--success)] to-[var(--green)] rounded-full border-4 border-[var(--card)] flex items-center justify-center shadow-lg">
|
<div className="absolute -bottom-2 -right-2 w-7 h-7 bg-gradient-to-r from-[var(--success)] to-[var(--green)] rounded-full border-4 border-[var(--card)] flex items-center justify-center shadow-lg">
|
||||||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
|
<Check className="w-4 h-4 text-white" />
|
||||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="relative w-20 h-20 rounded-full bg-gradient-to-br from-[var(--primary)]/30 to-[var(--accent)]/30 border-4 border-[var(--primary)]/40 flex items-center justify-center shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:border-[var(--accent)]/60">
|
<div className="relative w-20 h-20 rounded-full bg-gradient-to-br from-[var(--primary)]/30 to-[var(--accent)]/30 border-4 border-[var(--primary)]/40 flex items-center justify-center shadow-2xl transition-all duration-500 group-hover:scale-110 group-hover:border-[var(--accent)]/60">
|
||||||
<svg className="w-10 h-10 text-[var(--primary)] transition-colors duration-500 group-hover:text-[var(--accent)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<User className="w-10 h-10 text-[var(--primary)] transition-colors duration-500 group-hover:text-[var(--accent)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -282,14 +279,9 @@ export function WelcomeSection() {
|
|||||||
>
|
>
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-[var(--primary)]/10 to-[var(--accent)]/10 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
<div className="absolute inset-0 bg-gradient-to-r from-[var(--primary)]/10 to-[var(--accent)]/10 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<svg
|
<ArrowRight
|
||||||
className="w-6 h-6 text-[var(--muted-foreground)] group-hover:text-[var(--primary)] transition-all duration-500 group-hover:rotate-180"
|
className="w-6 h-6 text-[var(--muted-foreground)] group-hover:text-[var(--primary)] transition-all duration-500 group-hover:rotate-180"
|
||||||
fill="none"
|
/>
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Button, ToggleButton, SearchInput, ControlPanel, ControlSection, Contro
|
|||||||
import { IntegrationFilter } from '@/components/dashboard/IntegrationFilter';
|
import { IntegrationFilter } from '@/components/dashboard/IntegrationFilter';
|
||||||
import { FontSizeToggle } from '@/components/ui/FontSizeToggle';
|
import { FontSizeToggle } from '@/components/ui/FontSizeToggle';
|
||||||
import type { KanbanFilters } from '@/lib/types';
|
import type { KanbanFilters } from '@/lib/types';
|
||||||
|
import { Filter, Target, Calendar, Plus, List, Grid3X3, Layout } from 'lucide-react';
|
||||||
|
|
||||||
interface DesktopControlsProps {
|
interface DesktopControlsProps {
|
||||||
showFilters: boolean;
|
showFilters: boolean;
|
||||||
@@ -94,11 +95,7 @@ export function DesktopControls({
|
|||||||
isActive={showFilters}
|
isActive={showFilters}
|
||||||
count={activeFiltersCount}
|
count={activeFiltersCount}
|
||||||
onClick={onToggleFilters}
|
onClick={onToggleFilters}
|
||||||
icon={
|
icon={<Filter className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Filtres
|
Filtres
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -107,11 +104,7 @@ export function DesktopControls({
|
|||||||
variant="accent"
|
variant="accent"
|
||||||
isActive={showObjectives}
|
isActive={showObjectives}
|
||||||
onClick={onToggleObjectives}
|
onClick={onToggleObjectives}
|
||||||
icon={
|
icon={<Target className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Objectifs
|
Objectifs
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -121,11 +114,7 @@ export function DesktopControls({
|
|||||||
isActive={kanbanFilters.showWithDueDate}
|
isActive={kanbanFilters.showWithDueDate}
|
||||||
onClick={handleDueDateFilterToggle}
|
onClick={handleDueDateFilterToggle}
|
||||||
title={kanbanFilters.showWithDueDate ? "Afficher toutes les tâches" : "Afficher seulement les tâches avec date de fin"}
|
title={kanbanFilters.showWithDueDate ? "Afficher toutes les tâches" : "Afficher seulement les tâches avec date de fin"}
|
||||||
icon={
|
icon={<Calendar className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 002 2v12a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</ControlGroup>
|
</ControlGroup>
|
||||||
</ControlSection>
|
</ControlSection>
|
||||||
@@ -144,15 +133,7 @@ export function DesktopControls({
|
|||||||
isActive={compactView}
|
isActive={compactView}
|
||||||
onClick={onToggleCompactView}
|
onClick={onToggleCompactView}
|
||||||
title={compactView ? "Vue détaillée" : "Vue compacte"}
|
title={compactView ? "Vue détaillée" : "Vue compacte"}
|
||||||
icon={
|
icon={compactView ? <List className="w-4 h-4" /> : <Grid3X3 className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
{compactView ? (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 10h16M4 14h16M4 18h16" />
|
|
||||||
) : (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
)}
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{compactView ? 'Détaillée' : 'Compacte'}
|
{compactView ? 'Détaillée' : 'Compacte'}
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -162,15 +143,7 @@ export function DesktopControls({
|
|||||||
isActive={swimlanesByTags}
|
isActive={swimlanesByTags}
|
||||||
onClick={onToggleSwimlanes}
|
onClick={onToggleSwimlanes}
|
||||||
title={swimlanesByTags ? "Vue standard" : "Vue swimlanes"}
|
title={swimlanesByTags ? "Vue standard" : "Vue swimlanes"}
|
||||||
icon={
|
icon={swimlanesByTags ? <Layout className="w-4 h-4" /> : <Grid3X3 className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
{swimlanesByTags ? (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z" />
|
|
||||||
) : (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14-7H5m14 14H5" />
|
|
||||||
)}
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{swimlanesByTags ? 'Standard' : 'Swimlanes'}
|
{swimlanesByTags ? 'Standard' : 'Swimlanes'}
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -186,9 +159,7 @@ export function DesktopControls({
|
|||||||
onClick={onCreateTask}
|
onClick={onCreateTask}
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Plus className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
Nouvelle tâche
|
Nouvelle tâche
|
||||||
</Button>
|
</Button>
|
||||||
</ControlSection>
|
</ControlSection>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { PriorityFilters } from './filters/PriorityFilters';
|
|||||||
import { TagFilters } from './filters/TagFilters';
|
import { TagFilters } from './filters/TagFilters';
|
||||||
import { GeneralFilters } from './filters/GeneralFilters';
|
import { GeneralFilters } from './filters/GeneralFilters';
|
||||||
import { ColumnFilters } from './filters/ColumnFilters';
|
import { ColumnFilters } from './filters/ColumnFilters';
|
||||||
|
import { Layout, Grid3X3 } from 'lucide-react';
|
||||||
|
|
||||||
import type { KanbanFilters } from '@/lib/types';
|
import type { KanbanFilters } from '@/lib/types';
|
||||||
|
|
||||||
@@ -138,20 +139,7 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
|
|||||||
isActive={!!filters.swimlanesByTags}
|
isActive={!!filters.swimlanesByTags}
|
||||||
onClick={handleSwimlanesToggle}
|
onClick={handleSwimlanesToggle}
|
||||||
title="Mode d'affichage"
|
title="Mode d'affichage"
|
||||||
icon={
|
icon={filters.swimlanesByTags ? <Layout className="w-4 h-4" /> : <Grid3X3 className="w-4 h-4" />}
|
||||||
<svg
|
|
||||||
className="w-4 h-4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
{filters.swimlanesByTags ? (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 10h16M4 14h16M4 18h16" />
|
|
||||||
) : (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
||||||
)}
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{!filters.swimlanesByTags
|
{!filters.swimlanesByTags
|
||||||
? 'Normal'
|
? 'Normal'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Button, ToggleButton, ControlPanel } from '@/components/ui';
|
|||||||
import { IntegrationFilter } from '@/components/dashboard/IntegrationFilter';
|
import { IntegrationFilter } from '@/components/dashboard/IntegrationFilter';
|
||||||
import { FontSizeToggle } from '@/components/ui/FontSizeToggle';
|
import { FontSizeToggle } from '@/components/ui/FontSizeToggle';
|
||||||
import type { KanbanFilters } from '@/lib/types';
|
import type { KanbanFilters } from '@/lib/types';
|
||||||
|
import { Menu, Plus, Filter, Target, List, Grid3X3 } from 'lucide-react';
|
||||||
|
|
||||||
interface MobileControlsProps {
|
interface MobileControlsProps {
|
||||||
showFilters: boolean;
|
showFilters: boolean;
|
||||||
@@ -43,11 +44,7 @@ export function MobileControls({
|
|||||||
isActive={isMenuOpen}
|
isActive={isMenuOpen}
|
||||||
count={activeFiltersCount}
|
count={activeFiltersCount}
|
||||||
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||||
icon={
|
icon={<Menu className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Options
|
Options
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -59,9 +56,7 @@ export function MobileControls({
|
|||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Plus className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
<span className="hidden xs:inline">Nouvelle</span>
|
<span className="hidden xs:inline">Nouvelle</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,11 +77,7 @@ export function MobileControls({
|
|||||||
onToggleFilters();
|
onToggleFilters();
|
||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
icon={
|
icon={<Filter className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Filtres
|
Filtres
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -98,11 +89,7 @@ export function MobileControls({
|
|||||||
onToggleObjectives();
|
onToggleObjectives();
|
||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
icon={
|
icon={<Target className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Objectifs
|
Objectifs
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
@@ -123,15 +110,7 @@ export function MobileControls({
|
|||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
icon={
|
icon={compactView ? <List className="w-4 h-4" /> : <Grid3X3 className="w-4 h-4" />}
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
{compactView ? (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 10h16M4 14h16M4 18h16" />
|
|
||||||
) : (
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
)}
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Vue {compactView ? 'détaillée' : 'compacte'}
|
Vue {compactView ? 'détaillée' : 'compacte'}
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Task, TaskStatus } from '@/lib/types';
|
|||||||
import { TaskCard } from './TaskCard';
|
import { TaskCard } from './TaskCard';
|
||||||
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card';
|
||||||
import { Badge } from '@/components/ui/Badge';
|
import { Badge } from '@/components/ui/Badge';
|
||||||
|
import { ChevronDown } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
DragEndEvent,
|
DragEndEvent,
|
||||||
@@ -156,16 +157,11 @@ export function ObjectivesBoard({
|
|||||||
className="lg:hidden p-1 hover:bg-[var(--accent)]/20 rounded transition-colors"
|
className="lg:hidden p-1 hover:bg-[var(--accent)]/20 rounded transition-colors"
|
||||||
aria-label={isCollapsed ? "Développer" : "Réduire"}
|
aria-label={isCollapsed ? "Développer" : "Réduire"}
|
||||||
>
|
>
|
||||||
<svg
|
<ChevronDown
|
||||||
className={`w-4 h-4 text-[var(--accent)] transition-transform duration-200 ${
|
className={`w-4 h-4 text-[var(--accent)] transition-transform duration-200 ${
|
||||||
isCollapsed ? 'rotate-180' : ''
|
isCollapsed ? 'rotate-180' : ''
|
||||||
}`}
|
}`}
|
||||||
fill="none"
|
/>
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { useState } from 'react';
|
|||||||
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
|
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
|
||||||
import { useDragAndDrop } from '@/hooks/useDragAndDrop';
|
import { useDragAndDrop } from '@/hooks/useDragAndDrop';
|
||||||
import { getAllStatuses, getTechStyle } from '@/lib/status-config';
|
import { getAllStatuses, getTechStyle } from '@/lib/status-config';
|
||||||
|
import { ChevronRight } from 'lucide-react';
|
||||||
import { Card, CardHeader, ColumnHeader, DropZone } from '@/components/ui';
|
import { Card, CardHeader, ColumnHeader, DropZone } from '@/components/ui';
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
@@ -229,14 +230,9 @@ export function SwimlanesBase({
|
|||||||
onClick={() => toggleSwimlane(swimlane.key)}
|
onClick={() => toggleSwimlane(swimlane.key)}
|
||||||
className="flex items-center gap-2 hover:bg-[var(--card-hover)] rounded p-1 -m-1 transition-colors w-full"
|
className="flex items-center gap-2 hover:bg-[var(--card-hover)] rounded p-1 -m-1 transition-colors w-full"
|
||||||
>
|
>
|
||||||
<svg
|
<ChevronRight
|
||||||
className={`w-4 h-4 text-[var(--muted-foreground)] transition-transform ${isCollapsed ? '' : 'rotate-90'}`}
|
className={`w-4 h-4 text-[var(--muted-foreground)] transition-transform ${isCollapsed ? '' : 'rotate-90'}`}
|
||||||
fill="none"
|
/>
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
{swimlane.color && (
|
{swimlane.color && (
|
||||||
<div
|
<div
|
||||||
className="w-3 h-3 rounded-full"
|
className="w-3 h-3 rounded-full"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { FilterChip } from '@/components/ui';
|
import { FilterChip } from '@/components/ui';
|
||||||
|
import { Calendar, CheckCircle } from 'lucide-react';
|
||||||
|
|
||||||
interface GeneralFiltersProps {
|
interface GeneralFiltersProps {
|
||||||
showWithDueDate?: boolean;
|
showWithDueDate?: boolean;
|
||||||
@@ -24,16 +25,7 @@ export function GeneralFilters({
|
|||||||
<FilterChip
|
<FilterChip
|
||||||
onClick={onDueDateFilterToggle}
|
onClick={onDueDateFilterToggle}
|
||||||
variant={showWithDueDate ? 'selected' : 'default'}
|
variant={showWithDueDate ? 'selected' : 'default'}
|
||||||
icon={
|
icon={<Calendar className="w-4 h-4" />}
|
||||||
<svg
|
|
||||||
className="w-4 h-4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 002 2v12a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Avec date de fin
|
Avec date de fin
|
||||||
</FilterChip>
|
</FilterChip>
|
||||||
@@ -41,16 +33,7 @@ export function GeneralFilters({
|
|||||||
<FilterChip
|
<FilterChip
|
||||||
onClick={onCompletedLast7DaysFilterToggle}
|
onClick={onCompletedLast7DaysFilterToggle}
|
||||||
variant={showCompletedLast7Days ? 'selected' : 'default'}
|
variant={showCompletedLast7Days ? 'selected' : 'default'}
|
||||||
icon={
|
icon={<CheckCircle className="w-4 h-4" />}
|
||||||
<svg
|
|
||||||
className="w-4 h-4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Complété les 7 derniers jours
|
Complété les 7 derniers jours
|
||||||
</FilterChip>
|
</FilterChip>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { Card, CardContent } from '@/components/ui/Card';
|
import { Card, CardContent } from '@/components/ui/Card';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { ChevronRight } from 'lucide-react';
|
||||||
|
|
||||||
interface SettingsPage {
|
interface SettingsPage {
|
||||||
href: string;
|
href: string;
|
||||||
@@ -50,14 +51,7 @@ export function SettingsNavigation({ settingsPages }: SettingsNavigationProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<svg
|
<ChevronRight className="w-5 h-5 text-[var(--muted-foreground)]" />
|
||||||
className="w-5 h-5 text-[var(--muted-foreground)]"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Card } from '@/components/ui/Card';
|
import { Card } from '@/components/ui/Card';
|
||||||
import { Tag } from '@/lib/types';
|
import { Tag } from '@/lib/types';
|
||||||
|
import { Edit, Trash2, Loader2 } from 'lucide-react';
|
||||||
|
|
||||||
interface TagsGridProps {
|
interface TagsGridProps {
|
||||||
tags: (Tag & { usage?: number })[];
|
tags: (Tag & { usage?: number })[];
|
||||||
@@ -74,9 +75,7 @@ export function TagsGrid({
|
|||||||
onClick={() => onEditTag(tag)}
|
onClick={() => onEditTag(tag)}
|
||||||
className="h-7 w-7 p-0 text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
|
className="h-7 w-7 p-0 text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
|
||||||
>
|
>
|
||||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Edit className="w-3 h-3" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
|
||||||
</svg>
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -90,14 +89,9 @@ export function TagsGrid({
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{deletingTagId === tag.id ? (
|
{deletingTagId === tag.id ? (
|
||||||
<svg className="w-3 h-3 animate-spin" fill="none" viewBox="0 0 24 24">
|
<Loader2 className="w-3 h-3 animate-spin" />
|
||||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
||||||
<path className="opacity-75" fill="currentColor" d="m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
||||||
</svg>
|
|
||||||
) : (
|
) : (
|
||||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Trash2 className="w-3 h-3" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
||||||
</svg>
|
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { TagForm } from '@/components/forms/TagForm';
|
|||||||
import { TagsStats } from './TagsStats';
|
import { TagsStats } from './TagsStats';
|
||||||
import { TagsFilters } from './TagsFilters';
|
import { TagsFilters } from './TagsFilters';
|
||||||
import { TagsGrid } from './TagsGrid';
|
import { TagsGrid } from './TagsGrid';
|
||||||
|
import { Plus } from 'lucide-react';
|
||||||
|
|
||||||
interface TagsManagementProps {
|
interface TagsManagementProps {
|
||||||
tags: (Tag & { usage: number })[];
|
tags: (Tag & { usage: number })[];
|
||||||
@@ -112,9 +113,7 @@ export function TagsManagement({ tags, onRefreshTags, onDeleteTag }: TagsManagem
|
|||||||
onClick={() => setIsCreateModalOpen(true)}
|
onClick={() => setIsCreateModalOpen(true)}
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Plus className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
Nouveau tag
|
Nouveau tag
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { useState, useRef, useEffect, useCallback, ReactNode } from 'react';
|
import { useState, useRef, useEffect, useCallback, ReactNode } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { ChevronDown } from 'lucide-react';
|
||||||
|
|
||||||
export type DropdownPlacement =
|
export type DropdownPlacement =
|
||||||
| 'top-start'
|
| 'top-start'
|
||||||
@@ -255,14 +256,9 @@ export function Dropdown({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{trigger}
|
{trigger}
|
||||||
<svg
|
<ChevronDown
|
||||||
className={`w-4 h-4 transition-transform ${open ? 'rotate-180' : ''}`}
|
className={`w-4 h-4 transition-transform ${open ? 'rotate-180' : ''}`}
|
||||||
fill="none"
|
/>
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Theme, THEME_CONFIG, getThemeIcon } from '@/lib/ui-config';
|
|||||||
import { useKeyboardShortcutsModal } from '@/contexts/KeyboardShortcutsContext';
|
import { useKeyboardShortcutsModal } from '@/contexts/KeyboardShortcutsContext';
|
||||||
import { AuthButton } from '@/components/AuthButton';
|
import { AuthButton } from '@/components/AuthButton';
|
||||||
import { useSession, signOut } from 'next-auth/react';
|
import { useSession, signOut } from 'next-auth/react';
|
||||||
|
import { Check, X, Menu } from 'lucide-react';
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -144,9 +145,7 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
|
|||||||
<span className="text-base">{themeOption.icon}</span>
|
<span className="text-base">{themeOption.icon}</span>
|
||||||
<span className="font-mono">{themeOption.label}</span>
|
<span className="font-mono">{themeOption.label}</span>
|
||||||
{theme === themeOption.value && (
|
{theme === themeOption.value && (
|
||||||
<svg className="w-4 h-4 ml-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Check className="w-4 h-4 ml-auto" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
||||||
</svg>
|
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
@@ -163,13 +162,9 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
|
|||||||
title="Toggle menu"
|
title="Toggle menu"
|
||||||
>
|
>
|
||||||
{mobileMenuOpen ? (
|
{mobileMenuOpen ? (
|
||||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<X className="w-5 h-5" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
||||||
</svg>
|
|
||||||
) : (
|
) : (
|
||||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Menu className="w-5 h-5" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
</svg>
|
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -259,9 +254,7 @@ export function Header({ title = "TowerControl", subtitle = "Task Management", s
|
|||||||
<span className="text-base">{themeOption.icon}</span>
|
<span className="text-base">{themeOption.icon}</span>
|
||||||
<span className="font-mono">{themeOption.label}</span>
|
<span className="font-mono">{themeOption.label}</span>
|
||||||
{theme === themeOption.value && (
|
{theme === themeOption.value && (
|
||||||
<svg className="w-4 h-4 ml-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Check className="w-4 h-4 ml-auto" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
||||||
</svg>
|
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { TaskStatus } from '@/lib/types';
|
|||||||
import { PriorityBadge } from './PriorityBadge';
|
import { PriorityBadge } from './PriorityBadge';
|
||||||
import { TagDisplay } from './TagDisplay';
|
import { TagDisplay } from './TagDisplay';
|
||||||
import { formatDateForDisplay } from '@/lib/date-utils';
|
import { formatDateForDisplay } from '@/lib/date-utils';
|
||||||
|
import { ChevronRight } from 'lucide-react';
|
||||||
|
|
||||||
interface RecentTaskTimelineProps extends HTMLAttributes<HTMLDivElement> {
|
interface RecentTaskTimelineProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -120,9 +121,7 @@ export function RecentTaskTimeline({
|
|||||||
|
|
||||||
{/* Arrow indicator */}
|
{/* Arrow indicator */}
|
||||||
<div className="flex-shrink-0 mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
<div className="flex-shrink-0 mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
<svg className="w-4 h-4 text-[var(--primary)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<ChevronRight className="w-4 h-4 text-[var(--primary)]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { Tag } from '@/lib/types';
|
import { Tag } from '@/lib/types';
|
||||||
import { Badge } from './Badge';
|
import { Badge } from './Badge';
|
||||||
|
import { Edit, Trash2 } from 'lucide-react';
|
||||||
|
|
||||||
interface TagDisplayProps {
|
interface TagDisplayProps {
|
||||||
tags: string[];
|
tags: string[];
|
||||||
@@ -134,9 +135,7 @@ export function TagList({
|
|||||||
className="p-1 text-slate-400 hover:text-cyan-400 transition-colors"
|
className="p-1 text-slate-400 hover:text-cyan-400 transition-colors"
|
||||||
title="Éditer le tag"
|
title="Éditer le tag"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Edit className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -146,9 +145,7 @@ export function TagList({
|
|||||||
className="p-1 text-slate-400 hover:text-red-400 transition-colors"
|
className="p-1 text-slate-400 hover:text-red-400 transition-colors"
|
||||||
title="Supprimer le tag"
|
title="Supprimer le tag"
|
||||||
>
|
>
|
||||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Trash2 className="w-4 h-4" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user