Refact/cleanup #4

Merged
maxime.daniels merged 13 commits from refact/cleanup into master 2026-08-03 12:56:36 +02:00
5 changed files with 34 additions and 41 deletions
Showing only changes of commit 25ddc59f98 - Show all commits
+13 -16
View File
@@ -1,4 +1,6 @@
import { Card, CardContent } from '@/components/ui/Card'; import { Card, CardContent, CardHeader } from '@/components/ui/Card';
import { Check } from 'lucide-react';
import Badge from '@ui/Badge';
interface BackupWidgetProps { interface BackupWidgetProps {
onClick?: () => void; onClick?: () => void;
@@ -6,27 +8,22 @@ interface BackupWidgetProps {
export default function BackupWidget({ onClick }: BackupWidgetProps) { export default function BackupWidget({ onClick }: BackupWidgetProps) {
return ( return (
<Card <Card
onClick={onClick} onClick={onClick}
className="cursor-pointer hover:border-blue-300 hover:shadow-md transition-all group" className="cursor-pointer transition-all duration-300 ease-in-out"
> >
<CardHeader>
<h2 className="text-lg font-semibold">Sauvegardes</h2>
<Badge className="max-w-fit min-w-fit" name="PRA Immuable">
</Badge>
</CardHeader>
<CardContent className="p-6"> <CardContent className="p-6">
<div className="flex items-center justify-between mb-4"> <Card variant='digged' className="bg-slate-50 rounded-lg p-4 border border-slate-100 mb-4">
<h2 className="text-lg font-semibold text-slate-900 group-hover:text-blue-900 transition-colors">Sauvegardes</h2>
<span className="bg-slate-100 text-slate-600 text-xs px-2 py-1 rounded font-medium border border-slate-200">
PRA Immuable
</span>
</div>
<div className="bg-slate-50 rounded-lg p-4 border border-slate-100 mb-4 group-hover:bg-blue-50/50 transition-colors">
<p className="text-sm text-slate-500 mb-1">Dernier snapshot système</p> <p className="text-sm text-slate-500 mb-1">Dernier snapshot système</p>
<p className="text-slate-900 font-medium">Aujourd'hui à 03:00 AM</p> <p className="text-slate-900 font-medium">Aujourd'hui à 03:00 AM</p>
</div> </Card>
<div className="flex items-center text-emerald-600 text-sm font-medium"> <div className="flex items-center text-emerald-600 text-sm font-medium">
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <Check></Check>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
</svg>
Intégrité validée avec succès Intégrité validée avec succès
</div> </div>
</CardContent> </CardContent>
+4 -8
View File
@@ -5,7 +5,6 @@ import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input'; import { Input } from '@/components/ui/Input';
import { Select } from '@/components/ui/Select'; import { Select } from '@/components/ui/Select';
import { Textarea } from '@/components/ui/Textarea'; import { Textarea } from '@/components/ui/Textarea';
import { cn } from '@/utils/utils';
interface NewTicketWidgetProps { interface NewTicketWidgetProps {
onCancel: () => void; onCancel: () => void;
@@ -22,6 +21,7 @@ export const NewTicketWidget: React.FC<NewTicketWidgetProps> = ({ onCancel, onSu
const [affectedAsset, setAffectedAsset] = useState(''); const [affectedAsset, setAffectedAsset] = useState('');
const [incidentTime, setIncidentTime] = useState(''); const [incidentTime, setIncidentTime] = useState('');
const [description, setDescription] = useState(''); const [description, setDescription] = useState('');
const [buttonVariant, setButtonVariant]=useState('primary');
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
@@ -39,7 +39,7 @@ export const NewTicketWidget: React.FC<NewTicketWidgetProps> = ({ onCancel, onSu
return ( return (
<Card> <Card>
<CardHeader className="bg-slate-50 border-b border-slate-100"> <CardHeader>
<h1 className="text-xl font-bold text-slate-900 tracking-tight">Ouvrir un nouveau ticket</h1> <h1 className="text-xl font-bold text-slate-900 tracking-tight">Ouvrir un nouveau ticket</h1>
<p className="text-sm text-slate-500 mt-0.5">Qualification de votre requête ITSM</p> <p className="text-sm text-slate-500 mt-0.5">Qualification de votre requête ITSM</p>
</CardHeader> </CardHeader>
@@ -62,7 +62,7 @@ export const NewTicketWidget: React.FC<NewTicketWidgetProps> = ({ onCancel, onSu
<Select <Select
label="Type de demande" label="Type de demande"
value={category} value={category}
onChange={(e) => setCategory(e.target.value as any)} onChange={(e) => {setCategory(e.target.value as any); setButtonVariant(e.target.value==="Incident Critique"?"danger":"primary")}}
options={[ options={[
{ value: 'Incident Critique', label: 'Incident Critique (Panne, Dégradation)' }, { value: 'Incident Critique', label: 'Incident Critique (Panne, Dégradation)' },
{ value: 'Évolution', label: 'Évolution (Ajout de ressources, Modification)' }, { value: 'Évolution', label: 'Évolution (Ajout de ressources, Modification)' },
@@ -143,11 +143,7 @@ export const NewTicketWidget: React.FC<NewTicketWidgetProps> = ({ onCancel, onSu
<Button <Button
type="submit" type="submit"
isLoading={isSubmitting} isLoading={isSubmitting}
className={cn( variant={buttonVariant}
category === 'Incident Critique'
? "bg-red-600 hover:bg-red-700 focus:ring-red-600"
: ""
)}
> >
Soumettre le ticket Soumettre le ticket
</Button> </Button>
+6 -6
View File
@@ -1,4 +1,4 @@
import { Card, CardContent } from '@/components/ui/Card'; import { Card, CardContent, CardHeader } from '@/components/ui/Card';
interface SecurityWidgetProps { interface SecurityWidgetProps {
onClick?: () => void; onClick?: () => void;
@@ -6,18 +6,18 @@ interface SecurityWidgetProps {
export default function SecurityWidget({ onClick }: SecurityWidgetProps) { export default function SecurityWidget({ onClick }: SecurityWidgetProps) {
return ( return (
<Card <Card
onClick={onClick} onClick={onClick}
className="cursor-pointer hover:border-blue-300 hover:shadow-md transition-all group" className="cursor-pointer hover:border-blue-300 transition-all duration-300 ease-in-out"
> >
<CardHeader>
<h2 className="text-lg font-semibold transition-colors">Posture de Sécurité</h2>
</CardHeader>
<CardContent className="p-6"> <CardContent className="p-6">
<h2 className="text-lg font-semibold text-slate-900 mb-4 group-hover:text-blue-900 transition-colors">Posture de Sécurité</h2>
<div className="flex items-baseline space-x-2 mb-4"> <div className="flex items-baseline space-x-2 mb-4">
<span className="text-3xl font-bold text-slate-900">1,432</span> <span className="text-3xl font-bold text-slate-900">1,432</span>
<span className="text-sm text-slate-500">menaces bloquées (30j)</span> <span className="text-sm text-slate-500">menaces bloquées (30j)</span>
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between items-center text-sm"> <div className="flex justify-between items-center text-sm">
<span className="text-slate-600">Bouclier Cloudflare WAF</span> <span className="text-slate-600">Bouclier Cloudflare WAF</span>
+8 -8
View File
@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import type { TicketMessage } from '@/types/Message'; import type { TicketMessage } from '@/types/Message';
import { Card } from '@/components/ui/Card'; import { Card, CardContent, CardHeader } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button'; import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input'; import { Input } from '@/components/ui/Input';
import { EmptyState } from '@/components/ui/EmptyState'; import { EmptyState } from '@/components/ui/EmptyState';
@@ -34,13 +34,13 @@ export const TicketChatWidget: React.FC<TicketChatWidgetProps> = ({
}; };
return ( return (
<Card className="flex flex-col h-[500px] overflow-hidden shadow-sm"> <Card className="h-125">
<div className="p-4 border-b border-slate-100 bg-slate-50"> <CardHeader>
<h2 className="text-sm font-semibold text-slate-800">Échanges chiffrés avec l'ingénierie</h2> <h2 className="text-sm font-semibold text-slate-800">Échanges chiffrés</h2>
</div> </CardHeader>
{/* Zone des messages */} {/* Zone des messages */}
<div className="flex-1 overflow-y-auto p-6 space-y-6 scrollbar-hide bg-white"> <CardContent className="flex-1 overflow-y-auto p-6 space-y-6">
{messages.length === 0 ? ( {messages.length === 0 ? (
<EmptyState message="Aucun message pour l'instant. Démarrez la conversation ci-dessous." /> <EmptyState message="Aucun message pour l'instant. Démarrez la conversation ci-dessous." />
) : ( ) : (
@@ -48,10 +48,10 @@ export const TicketChatWidget: React.FC<TicketChatWidgetProps> = ({
<MessageBubble key={msg.id} message={msg} currentUserId={currentUserId} /> <MessageBubble key={msg.id} message={msg} currentUserId={currentUserId} />
)) ))
)} )}
</div> </CardContent>
{/* Zone de saisie avec notre composant UI */} {/* Zone de saisie avec notre composant UI */}
<form onSubmit={handleSubmit} className="p-4 border-t border-slate-100 bg-slate-50 flex items-start space-x-3"> <form onSubmit={handleSubmit} className="p-4 flex items-start space-x-3">
<div className="flex-1"> <div className="flex-1">
<Input <Input
value={newMessage} value={newMessage}
+3 -3
View File
@@ -10,7 +10,7 @@ interface TicketInfoWidgetProps {
export const TicketInfoWidget: React.FC<TicketInfoWidgetProps> = ({ ticket }) => { export const TicketInfoWidget: React.FC<TicketInfoWidgetProps> = ({ ticket }) => {
return ( return (
<Card> <Card>
<CardHeader className="bg-slate-50 border-b border-slate-100 flex flex-col sm:flex-row sm:items-start justify-between gap-4"> <CardHeader>
<div className="space-y-2"> <div className="space-y-2">
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<span className="text-xs font-bold uppercase tracking-wider px-2.5 py-1 bg-slate-200 text-slate-700 rounded-md"> <span className="text-xs font-bold uppercase tracking-wider px-2.5 py-1 bg-slate-200 text-slate-700 rounded-md">
@@ -24,10 +24,10 @@ export const TicketInfoWidget: React.FC<TicketInfoWidgetProps> = ({ ticket }) =>
</p> </p>
</div> </div>
<StatusBadge status={ticket.status} className="shrink-0" /> <StatusBadge status={ticket.status} className="shrink-0 max-w-fit" />
</CardHeader> </CardHeader>
<CardContent className="p-6 bg-white"> <CardContent>
<p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wide"> <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wide">
Description du besoin : Description du besoin :
</p> </p>