chore: clean up code formatting and remove unnecessary whitespace across multiple files for improved readability
This commit is contained in:
@@ -18,19 +18,13 @@ export function LiveIndicator({ isConnected, error }: LiveIndicatorProps) {
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center gap-2 rounded-full px-3 py-1.5 text-sm transition-colors ${
|
||||
isConnected
|
||||
? 'bg-success/10 text-success'
|
||||
: 'bg-yellow/10 text-yellow'
|
||||
isConnected ? 'bg-success/10 text-success' : 'bg-yellow/10 text-yellow'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`h-2 w-2 rounded-full ${
|
||||
isConnected ? 'bg-success animate-pulse' : 'bg-yellow'
|
||||
}`}
|
||||
className={`h-2 w-2 rounded-full ${isConnected ? 'bg-success animate-pulse' : 'bg-yellow'}`}
|
||||
/>
|
||||
<span>{isConnected ? 'Live' : 'Connexion...'}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ export function SessionLiveWrapper({
|
||||
<div className="mb-4 flex items-center justify-between rounded-lg border border-border bg-card p-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<LiveIndicator isConnected={isConnected} error={error} />
|
||||
|
||||
|
||||
{lastEventUser && (
|
||||
<div className="flex items-center gap-2 text-sm text-muted animate-pulse">
|
||||
<span>✏️</span>
|
||||
@@ -101,11 +101,7 @@ export function SessionLiveWrapper({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setShareModalOpen(true)}
|
||||
>
|
||||
<Button variant="outline" size="sm" onClick={() => setShareModalOpen(true)}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -120,9 +116,7 @@ export function SessionLiveWrapper({
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className={!canEdit ? 'pointer-events-none opacity-90' : ''}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={!canEdit ? 'pointer-events-none opacity-90' : ''}>{children}</div>
|
||||
|
||||
{/* Share Modal */}
|
||||
<ShareModal
|
||||
@@ -136,5 +130,3 @@ export function SessionLiveWrapper({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -105,14 +105,10 @@ export function ShareModal({
|
||||
|
||||
{/* Current shares */}
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
Collaborateurs ({shares.length})
|
||||
</p>
|
||||
|
||||
<p className="text-sm font-medium text-foreground">Collaborateurs ({shares.length})</p>
|
||||
|
||||
{shares.length === 0 ? (
|
||||
<p className="text-sm text-muted">
|
||||
Aucun collaborateur pour le moment
|
||||
</p>
|
||||
<p className="text-sm text-muted">Aucun collaborateur pour le moment</p>
|
||||
) : (
|
||||
<ul className="space-y-2">
|
||||
{shares.map((share) => (
|
||||
@@ -126,12 +122,10 @@ export function ShareModal({
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
{share.user.name || share.user.email}
|
||||
</p>
|
||||
{share.user.name && (
|
||||
<p className="text-xs text-muted">{share.user.email}</p>
|
||||
)}
|
||||
{share.user.name && <p className="text-xs text-muted">{share.user.email}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant={share.role === 'EDITOR' ? 'primary' : 'default'}>
|
||||
{share.role === 'EDITOR' ? 'Éditeur' : 'Lecteur'}
|
||||
@@ -176,5 +170,3 @@ export function ShareModal({
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export { LiveIndicator } from './LiveIndicator';
|
||||
export { ShareModal } from './ShareModal';
|
||||
export { SessionLiveWrapper } from './SessionLiveWrapper';
|
||||
|
||||
|
||||
@@ -112,11 +112,7 @@ export function Header() {
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
className="flex h-9 items-center gap-2 rounded-lg border border-border bg-card pl-1.5 pr-3 transition-colors hover:bg-card-hover"
|
||||
>
|
||||
<Avatar
|
||||
email={session.user.email!}
|
||||
name={session.user.name}
|
||||
size={24}
|
||||
/>
|
||||
<Avatar email={session.user.email!} name={session.user.name} size={24} />
|
||||
<span className="text-sm font-medium text-foreground">
|
||||
{session.user.name || session.user.email?.split('@')[0]}
|
||||
</span>
|
||||
@@ -137,10 +133,7 @@ export function Header() {
|
||||
|
||||
{menuOpen && (
|
||||
<>
|
||||
<div
|
||||
className="fixed inset-0 z-10"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
/>
|
||||
<div className="fixed inset-0 z-10" onClick={() => setMenuOpen(false)} />
|
||||
<div className="absolute right-0 z-20 mt-2 w-48 rounded-lg border border-border bg-card py-1 shadow-lg">
|
||||
<div className="border-b border-border px-4 py-2">
|
||||
<p className="text-xs text-muted">Connecté en tant que</p>
|
||||
|
||||
@@ -140,4 +140,3 @@ function InfluenceSlider({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,14 +66,15 @@ export function MotivatorBoard({ sessionId, cards: initialCards, canEdit }: Moti
|
||||
|
||||
// Persist to server
|
||||
startTransition(async () => {
|
||||
await reorderMotivatorCards(sessionId, newCards.map((c) => c.id));
|
||||
await reorderMotivatorCards(
|
||||
sessionId,
|
||||
newCards.map((c) => c.id)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function handleInfluenceChange(cardId: string, influence: number) {
|
||||
setCards((prev) =>
|
||||
prev.map((c) => (c.id === cardId ? { ...c, influence } : c))
|
||||
);
|
||||
setCards((prev) => prev.map((c) => (c.id === cardId ? { ...c, influence } : c)));
|
||||
|
||||
startTransition(async () => {
|
||||
await updateCardInfluence(cardId, sessionId, influence);
|
||||
@@ -151,11 +152,7 @@ export function MotivatorBoard({ sessionId, cards: initialCards, canEdit }: Moti
|
||||
>
|
||||
<div className="flex gap-2 min-w-max px-2">
|
||||
{sortedCards.map((card) => (
|
||||
<MotivatorCard
|
||||
key={card.id}
|
||||
card={card}
|
||||
disabled={!canEdit}
|
||||
/>
|
||||
<MotivatorCard key={card.id} card={card} disabled={!canEdit} />
|
||||
))}
|
||||
</div>
|
||||
</SortableContext>
|
||||
@@ -182,7 +179,8 @@ export function MotivatorBoard({ sessionId, cards: initialCards, canEdit }: Moti
|
||||
Évaluez l'influence de chaque motivation
|
||||
</h2>
|
||||
<p className="text-muted">
|
||||
Pour chaque carte, indiquez si cette motivation a une influence positive ou négative sur votre situation actuelle
|
||||
Pour chaque carte, indiquez si cette motivation a une influence positive ou négative
|
||||
sur votre situation actuelle
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -216,9 +214,7 @@ export function MotivatorBoard({ sessionId, cards: initialCards, canEdit }: Moti
|
||||
<h2 className="text-xl font-semibold text-foreground mb-2">
|
||||
Récapitulatif de vos Moving Motivators
|
||||
</h2>
|
||||
<p className="text-muted">
|
||||
Voici l'analyse de vos motivations et leur impact
|
||||
</p>
|
||||
<p className="text-muted">Voici l'analyse de vos motivations et leur impact</p>
|
||||
</div>
|
||||
|
||||
<MotivatorSummary cards={sortedCards} />
|
||||
@@ -273,4 +269,3 @@ function StepIndicator({
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,14 +19,7 @@ export function MotivatorCard({
|
||||
}: MotivatorCardProps) {
|
||||
const config = MOTIVATOR_BY_TYPE[card.type];
|
||||
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
||||
id: card.id,
|
||||
disabled,
|
||||
});
|
||||
@@ -62,10 +55,7 @@ export function MotivatorCard({
|
||||
<div className="text-3xl mb-1 mt-2">{config.icon}</div>
|
||||
|
||||
{/* Name */}
|
||||
<div
|
||||
className="font-semibold text-sm text-center px-2"
|
||||
style={{ color: config.color }}
|
||||
>
|
||||
<div className="font-semibold text-sm text-center px-2" style={{ color: config.color }}>
|
||||
{config.name}
|
||||
</div>
|
||||
|
||||
@@ -129,9 +119,7 @@ export function MotivatorCardStatic({
|
||||
/>
|
||||
|
||||
{/* Icon */}
|
||||
<div className={`mb-1 mt-2 ${size === 'small' ? 'text-xl' : 'text-3xl'}`}>
|
||||
{config.icon}
|
||||
</div>
|
||||
<div className={`mb-1 mt-2 ${size === 'small' ? 'text-xl' : 'text-3xl'}`}>{config.icon}</div>
|
||||
|
||||
{/* Name */}
|
||||
<div
|
||||
@@ -169,4 +157,3 @@ export function MotivatorCardStatic({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ export function MotivatorLiveWrapper({
|
||||
<div className="mb-4 flex items-center justify-between rounded-lg border border-border bg-card p-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<LiveIndicator isConnected={isConnected} error={error} />
|
||||
|
||||
|
||||
{lastEventUser && (
|
||||
<div className="flex items-center gap-2 text-sm text-muted animate-pulse">
|
||||
<span>✏️</span>
|
||||
@@ -101,11 +101,7 @@ export function MotivatorLiveWrapper({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setShareModalOpen(true)}
|
||||
>
|
||||
<Button variant="outline" size="sm" onClick={() => setShareModalOpen(true)}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
@@ -120,9 +116,7 @@ export function MotivatorLiveWrapper({
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className={!canEdit ? 'pointer-events-none opacity-90' : ''}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={!canEdit ? 'pointer-events-none opacity-90' : ''}>{children}</div>
|
||||
|
||||
{/* Share Modal */}
|
||||
<MotivatorShareModal
|
||||
@@ -136,4 +130,3 @@ export function MotivatorLiveWrapper({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,14 +105,10 @@ export function MotivatorShareModal({
|
||||
|
||||
{/* Current shares */}
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
Collaborateurs ({shares.length})
|
||||
</p>
|
||||
|
||||
<p className="text-sm font-medium text-foreground">Collaborateurs ({shares.length})</p>
|
||||
|
||||
{shares.length === 0 ? (
|
||||
<p className="text-sm text-muted">
|
||||
Aucun collaborateur pour le moment
|
||||
</p>
|
||||
<p className="text-sm text-muted">Aucun collaborateur pour le moment</p>
|
||||
) : (
|
||||
<ul className="space-y-2">
|
||||
{shares.map((share) => (
|
||||
@@ -126,12 +122,10 @@ export function MotivatorShareModal({
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
{share.user.name || share.user.email}
|
||||
</p>
|
||||
{share.user.name && (
|
||||
<p className="text-xs text-muted">{share.user.email}</p>
|
||||
)}
|
||||
{share.user.name && <p className="text-xs text-muted">{share.user.email}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant={share.role === 'EDITOR' ? 'primary' : 'default'}>
|
||||
{share.role === 'EDITOR' ? 'Éditeur' : 'Lecteur'}
|
||||
@@ -176,4 +170,3 @@ export function MotivatorShareModal({
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,14 @@ export function MotivatorSummary({ cards }: MotivatorSummaryProps) {
|
||||
const bottom3 = sortedByImportance.slice(0, 3);
|
||||
|
||||
// Cards with positive influence
|
||||
const positiveInfluence = cards.filter((c) => c.influence > 0).sort((a, b) => b.influence - a.influence);
|
||||
const positiveInfluence = cards
|
||||
.filter((c) => c.influence > 0)
|
||||
.sort((a, b) => b.influence - a.influence);
|
||||
|
||||
// Cards with negative influence
|
||||
const negativeInfluence = cards.filter((c) => c.influence < 0).sort((a, b) => a.influence - b.influence);
|
||||
const negativeInfluence = cards
|
||||
.filter((c) => c.influence < 0)
|
||||
.sort((a, b) => a.influence - b.influence);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
@@ -100,4 +104,3 @@ function SummarySection({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,4 +4,3 @@ export { MotivatorSummary } from './MotivatorSummary';
|
||||
export { InfluenceZone } from './InfluenceZone';
|
||||
export { MotivatorLiveWrapper } from './MotivatorLiveWrapper';
|
||||
export { MotivatorShareModal } from './MotivatorShareModal';
|
||||
|
||||
|
||||
@@ -103,4 +103,3 @@ export function EditableTitle({ sessionId, initialTitle, isOwner }: EditableTitl
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export { EditableTitle } from './EditableTitle';
|
||||
|
||||
|
||||
@@ -22,7 +22,10 @@ interface ActionPanelProps {
|
||||
onActionLeave: () => void;
|
||||
}
|
||||
|
||||
const categoryBadgeVariant: Record<SwotCategory, 'strength' | 'weakness' | 'opportunity' | 'threat'> = {
|
||||
const categoryBadgeVariant: Record<
|
||||
SwotCategory,
|
||||
'strength' | 'weakness' | 'opportunity' | 'threat'
|
||||
> = {
|
||||
STRENGTH: 'strength',
|
||||
WEAKNESS: 'weakness',
|
||||
OPPORTUNITY: 'opportunity',
|
||||
@@ -189,7 +192,12 @@ export function ActionPanel({
|
||||
className="rounded p-1 text-muted opacity-0 transition-opacity hover:bg-card-hover hover:text-foreground group-hover:opacity-100"
|
||||
aria-label="Modifier"
|
||||
>
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg
|
||||
className="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -203,7 +211,12 @@ export function ActionPanel({
|
||||
className="rounded p-1 text-muted opacity-0 transition-opacity hover:bg-destructive/10 hover:text-destructive group-hover:opacity-100"
|
||||
aria-label="Supprimer"
|
||||
>
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg
|
||||
className="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -271,7 +284,7 @@ export function ActionPanel({
|
||||
<Modal
|
||||
isOpen={showModal}
|
||||
onClose={closeModal}
|
||||
title={editingAction ? 'Modifier l\'action' : 'Nouvelle action croisée'}
|
||||
title={editingAction ? "Modifier l'action" : 'Nouvelle action croisée'}
|
||||
size="lg"
|
||||
>
|
||||
<form onSubmit={handleSubmit}>
|
||||
@@ -339,7 +352,7 @@ export function ActionPanel({
|
||||
Annuler
|
||||
</Button>
|
||||
<Button type="submit" loading={isPending}>
|
||||
{editingAction ? 'Enregistrer' : 'Créer l\'action'}
|
||||
{editingAction ? 'Enregistrer' : "Créer l'action"}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</form>
|
||||
@@ -347,4 +360,3 @@ export function ActionPanel({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,22 +11,17 @@ interface HelpContent {
|
||||
|
||||
const HELP_CONTENT: Record<SwotCategory, HelpContent> = {
|
||||
STRENGTH: {
|
||||
description:
|
||||
'Les atouts internes et qualités qui distinguent positivement.',
|
||||
description: 'Les atouts internes et qualités qui distinguent positivement.',
|
||||
examples: [
|
||||
'Expertise technique solide',
|
||||
'Excellentes capacités de communication',
|
||||
'Leadership naturel',
|
||||
'Rigueur et organisation',
|
||||
],
|
||||
questions: [
|
||||
'Qu\'est-ce qui le/la distingue ?',
|
||||
'Quels retours positifs reçoit-il/elle ?',
|
||||
],
|
||||
questions: ["Qu'est-ce qui le/la distingue ?", 'Quels retours positifs reçoit-il/elle ?'],
|
||||
},
|
||||
WEAKNESS: {
|
||||
description:
|
||||
'Les axes d\'amélioration et points à travailler.',
|
||||
description: "Les axes d'amélioration et points à travailler.",
|
||||
examples: [
|
||||
'Difficulté à déléguer',
|
||||
'Gestion du stress à améliorer',
|
||||
@@ -39,22 +34,17 @@ const HELP_CONTENT: Record<SwotCategory, HelpContent> = {
|
||||
],
|
||||
},
|
||||
OPPORTUNITY: {
|
||||
description:
|
||||
'Les facteurs externes favorables à saisir.',
|
||||
description: 'Les facteurs externes favorables à saisir.',
|
||||
examples: [
|
||||
'Nouveau projet stratégique',
|
||||
'Formation disponible',
|
||||
'Poste ouvert en interne',
|
||||
'Mentor potentiel identifié',
|
||||
],
|
||||
questions: [
|
||||
'Quelles évolutions pourraient l\'aider ?',
|
||||
'Quelles ressources sont disponibles ?',
|
||||
],
|
||||
questions: ["Quelles évolutions pourraient l'aider ?", 'Quelles ressources sont disponibles ?'],
|
||||
},
|
||||
THREAT: {
|
||||
description:
|
||||
'Les risques externes à anticiper.',
|
||||
description: 'Les risques externes à anticiper.',
|
||||
examples: [
|
||||
'Réorganisation menaçant le poste',
|
||||
'Compétences devenant obsolètes',
|
||||
@@ -82,9 +72,10 @@ export function QuadrantHelp({ category }: QuadrantHelpProps) {
|
||||
className={`
|
||||
flex h-5 w-5 items-center justify-center rounded-full
|
||||
text-xs font-medium transition-all
|
||||
${isOpen
|
||||
? 'bg-foreground/20 text-foreground rotate-45'
|
||||
: 'bg-foreground/5 text-muted hover:bg-foreground/10 hover:text-foreground'
|
||||
${
|
||||
isOpen
|
||||
? 'bg-foreground/20 text-foreground rotate-45'
|
||||
: 'bg-foreground/5 text-muted hover:bg-foreground/10 hover:text-foreground'
|
||||
}
|
||||
`}
|
||||
aria-label="Aide"
|
||||
@@ -113,9 +104,7 @@ export function QuadrantHelpPanel({ category, isOpen }: QuadrantHelpPanelProps)
|
||||
<div className="overflow-hidden">
|
||||
<div className="rounded-lg bg-white/40 dark:bg-black/20 p-3 mb-3">
|
||||
{/* Description */}
|
||||
<p className="text-xs text-foreground/80 leading-relaxed">
|
||||
{content.description}
|
||||
</p>
|
||||
<p className="text-xs text-foreground/80 leading-relaxed">{content.description}</p>
|
||||
|
||||
<div className="mt-3 flex gap-4">
|
||||
{/* Examples */}
|
||||
@@ -125,10 +114,7 @@ export function QuadrantHelpPanel({ category, isOpen }: QuadrantHelpPanelProps)
|
||||
</h4>
|
||||
<ul className="space-y-0.5">
|
||||
{content.examples.map((example, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-1.5 text-xs text-foreground/70"
|
||||
>
|
||||
<li key={i} className="flex items-start gap-1.5 text-xs text-foreground/70">
|
||||
<span className="mt-1.5 h-1 w-1 flex-shrink-0 rounded-full bg-current opacity-50" />
|
||||
{example}
|
||||
</li>
|
||||
@@ -143,10 +129,7 @@ export function QuadrantHelpPanel({ category, isOpen }: QuadrantHelpPanelProps)
|
||||
</h4>
|
||||
<ul className="space-y-1">
|
||||
{content.questions.map((question, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="text-xs italic text-foreground/60"
|
||||
>
|
||||
<li key={i} className="text-xs italic text-foreground/60">
|
||||
{question}
|
||||
</li>
|
||||
))}
|
||||
@@ -158,4 +141,3 @@ export function QuadrantHelpPanel({ category, isOpen }: QuadrantHelpPanelProps)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useTransition } from 'react';
|
||||
import {
|
||||
DragDropContext,
|
||||
Droppable,
|
||||
Draggable,
|
||||
DropResult,
|
||||
} from '@hello-pangea/dnd';
|
||||
import { DragDropContext, Droppable, Draggable, DropResult } from '@hello-pangea/dnd';
|
||||
import type { SwotItem, Action, ActionLink, SwotCategory } from '@prisma/client';
|
||||
import { SwotQuadrant } from './SwotQuadrant';
|
||||
import { SwotCard } from './SwotCard';
|
||||
@@ -67,9 +62,7 @@ export function SwotBoard({ sessionId, items, actions }: SwotBoardProps) {
|
||||
if (!linkMode) return;
|
||||
|
||||
setSelectedItems((prev) =>
|
||||
prev.includes(itemId)
|
||||
? prev.filter((id) => id !== itemId)
|
||||
: [...prev, itemId]
|
||||
prev.includes(itemId) ? prev.filter((id) => id !== itemId) : [...prev, itemId]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -167,4 +160,3 @@ export function SwotBoard({ sessionId, items, actions }: SwotBoardProps) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,12 @@ export const SwotCard = forwardRef<HTMLDivElement, SwotCardProps>(
|
||||
className="rounded p-1 text-muted hover:bg-card-hover hover:text-foreground"
|
||||
aria-label="Modifier"
|
||||
>
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg
|
||||
className="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -137,7 +142,12 @@ export const SwotCard = forwardRef<HTMLDivElement, SwotCardProps>(
|
||||
className="rounded p-1 text-muted hover:bg-primary/10 hover:text-primary"
|
||||
aria-label="Dupliquer"
|
||||
>
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg
|
||||
className="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -154,7 +164,12 @@ export const SwotCard = forwardRef<HTMLDivElement, SwotCardProps>(
|
||||
className="rounded p-1 text-muted hover:bg-destructive/10 hover:text-destructive"
|
||||
aria-label="Supprimer"
|
||||
>
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<svg
|
||||
className="h-3.5 w-3.5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -168,7 +183,9 @@ export const SwotCard = forwardRef<HTMLDivElement, SwotCardProps>(
|
||||
|
||||
{/* Selection indicator in link mode */}
|
||||
{linkMode && isSelected && (
|
||||
<div className={`absolute -right-1 -top-1 rounded-full bg-card p-0.5 shadow ${styles.text}`}>
|
||||
<div
|
||||
className={`absolute -right-1 -top-1 rounded-full bg-card p-0.5 shadow ${styles.text}`}
|
||||
>
|
||||
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
|
||||
</svg>
|
||||
@@ -182,4 +199,3 @@ export const SwotCard = forwardRef<HTMLDivElement, SwotCardProps>(
|
||||
);
|
||||
|
||||
SwotCard.displayName = 'SwotCard';
|
||||
|
||||
|
||||
@@ -92,9 +92,10 @@ export const SwotQuadrant = forwardRef<HTMLDivElement, SwotQuadrantProps>(
|
||||
className={`
|
||||
flex h-5 w-5 items-center justify-center rounded-full
|
||||
text-xs font-medium transition-all
|
||||
${showHelp
|
||||
? 'bg-foreground/20 text-foreground'
|
||||
: 'bg-foreground/5 text-muted hover:bg-foreground/10 hover:text-foreground'
|
||||
${
|
||||
showHelp
|
||||
? 'bg-foreground/20 text-foreground'
|
||||
: 'bg-foreground/5 text-muted hover:bg-foreground/10 hover:text-foreground'
|
||||
}
|
||||
`}
|
||||
aria-label="Aide"
|
||||
@@ -112,7 +113,12 @@ export const SwotQuadrant = forwardRef<HTMLDivElement, SwotQuadrantProps>(
|
||||
aria-label={`Ajouter un item ${title}`}
|
||||
>
|
||||
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 4v16m8-8H4"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -166,4 +172,3 @@ export const SwotQuadrant = forwardRef<HTMLDivElement, SwotQuadrantProps>(
|
||||
);
|
||||
|
||||
SwotQuadrant.displayName = 'SwotQuadrant';
|
||||
|
||||
|
||||
@@ -3,4 +3,3 @@ export { SwotQuadrant } from './SwotQuadrant';
|
||||
export { SwotCard } from './SwotCard';
|
||||
export { ActionPanel } from './ActionPanel';
|
||||
export { QuadrantHelp } from './QuadrantHelp';
|
||||
|
||||
|
||||
@@ -28,5 +28,3 @@ export function Avatar({
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,4 +49,3 @@ export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
|
||||
);
|
||||
|
||||
Badge.displayName = 'Badge';
|
||||
|
||||
|
||||
@@ -10,16 +10,11 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
}
|
||||
|
||||
const variantStyles: Record<ButtonVariant, string> = {
|
||||
primary:
|
||||
'bg-primary text-primary-foreground hover:bg-primary-hover border-transparent',
|
||||
secondary:
|
||||
'bg-card text-foreground hover:bg-card-hover border-border',
|
||||
outline:
|
||||
'bg-transparent text-foreground hover:bg-card-hover border-border',
|
||||
ghost:
|
||||
'bg-transparent text-foreground hover:bg-card-hover border-transparent',
|
||||
destructive:
|
||||
'bg-destructive text-white hover:bg-destructive/90 border-transparent',
|
||||
primary: 'bg-primary text-primary-foreground hover:bg-primary-hover border-transparent',
|
||||
secondary: 'bg-card text-foreground hover:bg-card-hover border-border',
|
||||
outline: 'bg-transparent text-foreground hover:bg-card-hover border-border',
|
||||
ghost: 'bg-transparent text-foreground hover:bg-card-hover border-transparent',
|
||||
destructive: 'bg-destructive text-white hover:bg-destructive/90 border-transparent',
|
||||
};
|
||||
|
||||
const sizeStyles: Record<ButtonSize, string> = {
|
||||
@@ -29,7 +24,10 @@ const sizeStyles: Record<ButtonSize, string> = {
|
||||
};
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className = '', variant = 'primary', size = 'md', loading, disabled, children, ...props }, ref) => {
|
||||
(
|
||||
{ className = '', variant = 'primary', size = 'md', loading, disabled, children, ...props },
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
@@ -74,4 +72,3 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
);
|
||||
|
||||
Button.displayName = 'Button';
|
||||
|
||||
|
||||
@@ -40,11 +40,12 @@ export const CardTitle = forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadi
|
||||
|
||||
CardTitle.displayName = 'CardTitle';
|
||||
|
||||
export const CardDescription = forwardRef<HTMLParagraphElement, HTMLAttributes<HTMLParagraphElement>>(
|
||||
({ className = '', ...props }, ref) => (
|
||||
<p ref={ref} className={`mt-1 text-sm text-muted ${className}`} {...props} />
|
||||
)
|
||||
);
|
||||
export const CardDescription = forwardRef<
|
||||
HTMLParagraphElement,
|
||||
HTMLAttributes<HTMLParagraphElement>
|
||||
>(({ className = '', ...props }, ref) => (
|
||||
<p ref={ref} className={`mt-1 text-sm text-muted ${className}`} {...props} />
|
||||
));
|
||||
|
||||
CardDescription.displayName = 'CardDescription';
|
||||
|
||||
@@ -63,4 +64,3 @@ export const CardFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEleme
|
||||
);
|
||||
|
||||
CardFooter.displayName = 'CardFooter';
|
||||
|
||||
|
||||
@@ -79,5 +79,3 @@ export function CollaboratorDisplay({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,10 +12,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
return (
|
||||
<div className="w-full">
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={inputId}
|
||||
className="mb-2 block text-sm font-medium text-foreground"
|
||||
>
|
||||
<label htmlFor={inputId} className="mb-2 block text-sm font-medium text-foreground">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
@@ -32,13 +29,10 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
`}
|
||||
{...props}
|
||||
/>
|
||||
{error && (
|
||||
<p className="mt-1.5 text-sm text-destructive">{error}</p>
|
||||
)}
|
||||
{error && <p className="mt-1.5 text-sm text-destructive">{error}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Input.displayName = 'Input';
|
||||
|
||||
|
||||
@@ -84,12 +84,7 @@ export function Modal({ isOpen, onClose, title, children, size = 'md' }: ModalPr
|
||||
className="rounded-lg p-1 text-muted hover:bg-card-hover hover:text-foreground transition-colors"
|
||||
aria-label="Fermer"
|
||||
>
|
||||
<svg
|
||||
className="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
|
||||
@@ -12,10 +12,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
return (
|
||||
<div className="w-full">
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={textareaId}
|
||||
className="mb-2 block text-sm font-medium text-foreground"
|
||||
>
|
||||
<label htmlFor={textareaId} className="mb-2 block text-sm font-medium text-foreground">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
@@ -33,13 +30,10 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
`}
|
||||
{...props}
|
||||
/>
|
||||
{error && (
|
||||
<p className="mt-1.5 text-sm text-destructive">{error}</p>
|
||||
)}
|
||||
{error && <p className="mt-1.5 text-sm text-destructive">{error}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Textarea.displayName = 'Textarea';
|
||||
|
||||
|
||||
@@ -6,4 +6,3 @@ export { CollaboratorDisplay } from './CollaboratorDisplay';
|
||||
export { Input } from './Input';
|
||||
export { Modal, ModalFooter } from './Modal';
|
||||
export { Textarea } from './Textarea';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user