account settings update
This commit is contained in:
@@ -1,4 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { pb } from '../config/pocketbase';
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
emailVisibility: boolean;
|
||||
verified: boolean;
|
||||
name: string;
|
||||
role: string;
|
||||
company: string;
|
||||
mfa_enabled: boolean;
|
||||
created: string;
|
||||
updated: string
|
||||
}
|
||||
|
||||
interface Company {
|
||||
id: string;
|
||||
name: string;
|
||||
no: string;
|
||||
vip_level: string;
|
||||
created: string;
|
||||
updated: string
|
||||
}
|
||||
|
||||
// Définition stricte des propriétés attendues par le Layout
|
||||
interface DashboardLayoutProps {
|
||||
@@ -9,6 +32,27 @@ interface DashboardLayoutProps {
|
||||
}
|
||||
|
||||
export default function DashboardLayout({ children, activeView, onNavigate, onLogout }: DashboardLayoutProps) {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [company, setCompany] = useState<Company | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const fetchInformations = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const userRecords = await pb.collection('aegis_users').getFullList<User>();
|
||||
setUser(userRecords[0]);
|
||||
const companyRecords = await pb.collection('aegis_companies').getFullList<Company>();
|
||||
setCompany(companyRecords[0])
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des infos utilisateur :", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
fetchInformations();
|
||||
},[]);
|
||||
|
||||
const navItems = [
|
||||
{ id: 'dashboard', label: 'Tableau de bord', icon: (
|
||||
@@ -66,10 +110,14 @@ export default function DashboardLayout({ children, activeView, onNavigate, onLo
|
||||
}`}
|
||||
>
|
||||
<div className="w-8 h-8 rounded-full bg-slate-200 flex items-center justify-center text-slate-600 font-bold text-sm shrink-0">
|
||||
DC
|
||||
{isLoading? "":user?.name.split(" ").map((n)=>n[0]).join("")}
|
||||
</div>
|
||||
<div className="ml-3 overflow-hidden">
|
||||
<p className="text-sm font-medium text-slate-900 truncate">Direction Client</p>
|
||||
{isLoading?
|
||||
<p className="text-sm font-medium text-slate-200 bg-slate-200 rounded ">*</p>
|
||||
:
|
||||
<p className="text-sm font-medium text-slate-900 truncate">{user?.name}</p>
|
||||
}
|
||||
<p className="text-xs text-slate-500 truncate">Paramètres du compte</p>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -1,7 +1,62 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { pb } from '../../config/pocketbase';
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
emailVisibility: boolean;
|
||||
verified: boolean;
|
||||
name: string;
|
||||
role: string;
|
||||
company: string;
|
||||
mfa_enabled: boolean;
|
||||
created: string;
|
||||
updated: string
|
||||
}
|
||||
|
||||
interface Company {
|
||||
id: string;
|
||||
name: string;
|
||||
no: string;
|
||||
vip_level: string;
|
||||
created: string;
|
||||
updated: string
|
||||
}
|
||||
|
||||
function switchVip(vip_level:string | undefined){
|
||||
switch (vip_level?.toLowerCase()) {
|
||||
case "platinum":
|
||||
return <span className="px-2 py-1 bg-amber-600 text-white text-xs font-bold rounded shadow-sm mr-2 tracking-wider">{vip_level?.toUpperCase()}</span>;
|
||||
case "premium":
|
||||
return <span className="px-2 py-1 bg-violet-600 text-white text-xs font-bold rounded shadow-sm mr-2 tracking-wider">{vip_level?.toUpperCase()}</span>;
|
||||
default:
|
||||
return <span className="px-2 py-1 bg-blue-600 text-white text-xs font-bold rounded shadow-sm mr-2 tracking-wider">{vip_level?.toUpperCase()}</span>;
|
||||
}
|
||||
}
|
||||
|
||||
export default function AccountSettings() {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [company, setCompany] = useState<Company | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const fetchInformations = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const userRecords = await pb.collection('aegis_users').getFullList<User>();
|
||||
setUser(userRecords[0]);
|
||||
const companyRecords = await pb.collection('aegis_companies').getFullList<Company>();
|
||||
setCompany(companyRecords[0])
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des infos utilisateur :", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
fetchInformations();
|
||||
},[]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50 font-sans text-slate-900 selection:bg-blue-900 selection:text-white">
|
||||
|
||||
@@ -17,6 +72,10 @@ export default function AccountSettings() {
|
||||
|
||||
{/* Contenu Principal */}
|
||||
<main className="max-w-7xl mx-auto px-8 py-8 space-y-8">
|
||||
{isLoading?
|
||||
<div className="flex-1 flex justify-center items-center py-8">
|
||||
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-slate-900"></div>
|
||||
</div>:
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
|
||||
@@ -35,10 +94,16 @@ export default function AccountSettings() {
|
||||
<p className="text-sm font-medium text-slate-900">Authentification à double facteur (MFA)</p>
|
||||
<p className="text-xs text-slate-500 mt-1">Exigée par les politiques de sécurité GISE</p>
|
||||
</div>
|
||||
{user?.mfa_enabled?
|
||||
<span className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-emerald-500 mr-1.5"></span>
|
||||
Actif
|
||||
</span>:
|
||||
<span className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold bg-red-50 text-red-700 border border-red-200">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-red-500 mr-1.5"></span>
|
||||
Inactif
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="pt-4 border-t border-slate-100">
|
||||
@@ -46,7 +111,6 @@ export default function AccountSettings() {
|
||||
Générer de nouveaux codes de secours
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mot de passe */}
|
||||
<div className="pt-4 border-t border-slate-100">
|
||||
<p className="text-sm font-medium text-slate-900 mb-2">Mot de passe institutionnel</p>
|
||||
@@ -70,16 +134,20 @@ export default function AccountSettings() {
|
||||
<dl className="space-y-4 text-sm">
|
||||
<div>
|
||||
<dt className="text-slate-500 font-medium">Entité Légale</dt>
|
||||
<dd className="mt-1 font-semibold text-slate-900">Cabinet Juridique Example & Associés</dd>
|
||||
<dd className="mt-1 font-semibold text-slate-900">{company?.name}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-slate-500 font-medium">Administrateur du compte</dt>
|
||||
<dd className="mt-1 text-slate-900">Direction Générale (direction@example.com)</dd>
|
||||
<dd className="mt-1 text-slate-900">
|
||||
<span className="px-2 py-1 bg-blue-900 text-white text-xs font-bold rounded shadow-sm mr-2 tracking-wider">{user?.role}</span>
|
||||
<span className="text-slate-700 font-medium">{user?.name}</span>
|
||||
</dd>
|
||||
<dd className="mt-1 text-slate-900">{!user?.emailVisibility? user?.email : ""}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt className="text-slate-500 font-medium">Niveau d'Infogérance (SLA)</dt>
|
||||
<dd className="mt-1 flex items-center">
|
||||
<span className="px-2 py-1 bg-blue-900 text-white text-xs font-bold rounded shadow-sm mr-2 tracking-wider">VIP PLATINUM</span>
|
||||
{switchVip(company?.vip_level)}
|
||||
<span className="text-slate-700 font-medium">Couverture 24/7 (99.99%)</span>
|
||||
</dd>
|
||||
</div>
|
||||
@@ -87,7 +155,7 @@ export default function AccountSettings() {
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -39,6 +39,7 @@ export default function TicketDetail({ ticketId, onBack }: TicketDetailProps) {
|
||||
|
||||
// Récupération du ticket et de ses messages associés
|
||||
const fetchTicketData = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const ticketData = await pb.collection('aegis_tickets').getOne<Ticket>(ticketId);
|
||||
setTicket(ticketData);
|
||||
|
||||
Reference in New Issue
Block a user