refactor(ui): unify low-level controls and expand design system
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m57s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m57s
This commit is contained in:
@@ -1,46 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useRef } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@/components/ui';
|
||||
import { Button, DropdownMenu } from '@/components/ui';
|
||||
import { WORKSHOPS } from '@/lib/workshops';
|
||||
import { useClickOutside } from '@/hooks/useClickOutside';
|
||||
|
||||
export function NewWorkshopDropdown() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
useClickOutside(containerRef, () => setOpen(false), open);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="relative">
|
||||
<Button
|
||||
type="button"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => setOpen(!open)}
|
||||
className="gap-1.5"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
Nouvel atelier
|
||||
<svg
|
||||
className={`h-3.5 w-3.5 transition-transform ${open ? 'rotate-180' : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</Button>
|
||||
{open && (
|
||||
<div className="absolute right-0 z-20 mt-2 w-60 rounded-xl border border-border bg-card py-1.5 shadow-lg">
|
||||
<DropdownMenu
|
||||
panelClassName="absolute right-0 z-20 mt-2 w-60 rounded-xl border border-border bg-card py-1.5 shadow-lg"
|
||||
trigger={({ open, toggle }) => (
|
||||
<Button type="button" variant="primary" size="sm" onClick={toggle} className="gap-1.5">
|
||||
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
Nouvel atelier
|
||||
<svg
|
||||
className={`h-3.5 w-3.5 transition-transform ${open ? 'rotate-180' : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</Button>
|
||||
)}
|
||||
>
|
||||
{({ close }) => (
|
||||
<>
|
||||
{WORKSHOPS.map((w) => (
|
||||
<Link
|
||||
key={w.id}
|
||||
href={w.newPath}
|
||||
className="flex items-center gap-3 px-4 py-2.5 text-sm text-foreground hover:bg-card-hover transition-colors"
|
||||
onClick={() => setOpen(false)}
|
||||
onClick={close}
|
||||
>
|
||||
<span
|
||||
className="flex h-8 w-8 items-center justify-center rounded-lg text-base flex-shrink-0"
|
||||
@@ -54,8 +46,8 @@ export function NewWorkshopDropdown() {
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,16 @@
|
||||
|
||||
import { useState, useTransition } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Button, Modal, ModalFooter, Input, CollaboratorDisplay } from '@/components/ui';
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalFooter,
|
||||
Input,
|
||||
CollaboratorDisplay,
|
||||
IconButton,
|
||||
IconEdit,
|
||||
IconTrash,
|
||||
} from '@/components/ui';
|
||||
import { deleteSwotSession, updateSwotSession } from '@/actions/session';
|
||||
import { deleteMotivatorSession, updateMotivatorSession } from '@/actions/moving-motivators';
|
||||
import { deleteYearReviewSession, updateYearReviewSession } from '@/actions/year-review';
|
||||
@@ -211,25 +220,21 @@ export function SessionCard({
|
||||
<>
|
||||
{(session.isOwner || session.role === 'EDITOR' || session.isTeamCollab) && (
|
||||
<div className={`absolute flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20 ${view === 'table' ? 'top-1/2 -translate-y-1/2 right-3' : 'top-2.5 right-2.5'}`}>
|
||||
<button
|
||||
<IconButton
|
||||
onClick={(e) => { e.preventDefault(); e.stopPropagation(); openEditModal(); }}
|
||||
className="p-1.5 rounded-lg bg-card border border-border text-muted hover:text-primary hover:bg-primary/5 shadow-sm"
|
||||
title="Modifier"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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>
|
||||
label="Modifier"
|
||||
icon={<IconEdit />}
|
||||
variant="primary"
|
||||
className="bg-card shadow-sm"
|
||||
/>
|
||||
{(session.isOwner || session.isTeamCollab) && (
|
||||
<button
|
||||
<IconButton
|
||||
onClick={(e) => { e.preventDefault(); e.stopPropagation(); setShowDeleteModal(true); }}
|
||||
className="p-1.5 rounded-lg bg-card border border-border text-muted hover:text-destructive hover:bg-destructive/5 shadow-sm"
|
||||
title="Supprimer"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<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>
|
||||
label="Supprimer"
|
||||
icon={<IconTrash />}
|
||||
variant="destructive"
|
||||
className="bg-card shadow-sm"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
@@ -247,19 +252,15 @@ export function SessionCard({
|
||||
|
||||
<Modal isOpen={showEditModal} onClose={() => setShowEditModal(false)} title="Modifier l'atelier" size="sm">
|
||||
<form onSubmit={(e) => { e.preventDefault(); handleEdit(); }} className="space-y-4">
|
||||
<Input id="edit-title" label="Titre" value={editTitle} onChange={(e) => setEditTitle(e.target.value)} placeholder="Titre de l'atelier" required />
|
||||
<div>
|
||||
<label htmlFor="edit-title" className="block text-sm font-medium text-foreground mb-1">Titre</label>
|
||||
<Input id="edit-title" value={editTitle} onChange={(e) => setEditTitle(e.target.value)} placeholder="Titre de l'atelier" required />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="edit-participant" className="block text-sm font-medium text-foreground mb-1">{workshop.participantLabel}</label>
|
||||
{!isWeather && !isGifMood && (
|
||||
<Input id="edit-participant" value={editParticipant} onChange={(e) => setEditParticipant(e.target.value)}
|
||||
<Input id="edit-participant" label={workshop.participantLabel} value={editParticipant} onChange={(e) => setEditParticipant(e.target.value)}
|
||||
placeholder={isSwot ? 'Nom du collaborateur' : 'Nom du participant'} required />
|
||||
)}
|
||||
</div>
|
||||
<ModalFooter>
|
||||
<Button type="button" variant="ghost" onClick={() => setShowEditModal(false)} disabled={isPending}>Annuler</Button>
|
||||
<Button type="button" variant="outline" onClick={() => setShowEditModal(false)} disabled={isPending}>Annuler</Button>
|
||||
<Button type="submit" disabled={isPending || !editTitle.trim() || (!isWeather && !isGifMood && !editParticipant.trim())}>
|
||||
{isPending ? 'Enregistrement...' : 'Enregistrer'}
|
||||
</Button>
|
||||
@@ -272,7 +273,7 @@ export function SessionCard({
|
||||
<p className="text-muted">Êtes-vous sûr de vouloir supprimer <strong className="text-foreground">"{session.title}"</strong> ?</p>
|
||||
<p className="text-sm text-destructive">Cette action est irréversible. Toutes les données seront perdues.</p>
|
||||
<ModalFooter>
|
||||
<Button variant="ghost" onClick={() => setShowDeleteModal(false)} disabled={isPending}>Annuler</Button>
|
||||
<Button variant="outline" onClick={() => setShowDeleteModal(false)} disabled={isPending}>Annuler</Button>
|
||||
<Button variant="destructive" onClick={handleDelete} disabled={isPending}>{isPending ? 'Suppression...' : 'Supprimer'}</Button>
|
||||
</ModalFooter>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user