Initial commit

This commit is contained in:
dahoud
2025-10-01 01:39:07 +00:00
commit b430bf3b96
826 changed files with 255287 additions and 0 deletions

173
layout/AppTopbar.tsx Normal file
View File

@@ -0,0 +1,173 @@
'use client';
import React, { forwardRef, useImperativeHandle, useContext, useRef, useState } from 'react';
import AppBreadCrumb from './AppBreadCrumb';
import { LayoutContext } from './context/layoutcontext';
import { useAuth } from '../contexts/AuthContext';
import { StyleClass } from 'primereact/styleclass';
import { Ripple } from 'primereact/ripple';
import { Button } from 'primereact/button';
import { InputText } from 'primereact/inputtext';
import { classNames } from 'primereact/utils';
import ConnectionStatusSimple from '../components/ConnectionStatusSimple';
const AppTopbar = forwardRef((props: { sidebarRef: React.RefObject<HTMLDivElement> }, ref) => {
const [searchActive, setSearchActive] = useState(false);
const { user, logout, isAuthenticated } = useAuth();
const btnRef1 = useRef(null);
const btnRef2 = useRef(null);
const menubutton = useRef(null);
const menubuttonRef = useRef(null);
const searchInput = useRef(null);
const profileRef = useRef(null);
const profileMenuRef = useRef(null);
const { onMenuToggle, showConfigSidebar, showSidebar, layoutConfig } = useContext(LayoutContext);
useImperativeHandle(ref, () => ({
menubutton: menubuttonRef.current
}));
const activateSearch = () => {
setSearchActive(true);
setTimeout(() => {
(searchInput.current as any).focus();
}, 1000);
};
const deactivateSearch = () => {
setSearchActive(false);
};
const handleKeyDown = (event: any) => {
if (event.key === 'Escape') {
deactivateSearch();
}
};
const handleLogout = async () => {
try {
await logout();
} catch (error) {
console.error('Erreur lors de la déconnexion:', error);
}
};
return (
<React.Fragment>
<div className="layout-topbar">
<div className="topbar-start">
<button ref={btnRef1} type="button" className="p-ripple topbar-menubutton p-link p-trigger" onClick={onMenuToggle}>
<i className="pi pi-bars"></i>
<Ripple />
</button>
<div className="topbar-breadcrumb">
<AppBreadCrumb></AppBreadCrumb>
</div>
</div>
<div className="topbar-end">
<ul className="topbar-menu">
<li className="hidden lg:block">
<div className={classNames('topbar-search', { 'topbar-search-active': searchActive })}>
<Button icon="pi pi-search" className="topbar-searchbutton p-button-text p-button-secondary text-color-secondary p-button-rounded flex-shrink-0" type="button" onClick={activateSearch}></Button>
<div className="search-input-wrapper">
<span className="p-input-icon-right">
<InputText
ref={searchInput}
type="text"
placeholder="Search"
onBlur={deactivateSearch}
onKeyDown={(e) => {
if (e.key === 'Escape') deactivateSearch();
}}
/>
<i className="pi pi-search"></i>
</span>
</div>
</div>
</li>
<li className="profile-item topbar-item">
<ConnectionStatusSimple
showToasts={false}
showIndicator={true}
className="mr-2"
/>
</li>
<li className="profile-item topbar-item">
<Button type="button" icon="pi pi-bell" className="p-button-text p-button-secondary text-color-secondary p-button-rounded flex-shrink-0"></Button>
</li>
<li className="profile-item topbar-item">
<Button type="button" icon="pi pi-comment" className="p-button-text p-button-secondary relative text-color-secondary p-button-rounded flex-shrink-0"></Button>
</li>
<li className="ml-3">
<Button type="button" icon="pi pi-cog" className="p-button-text p-button-secondary text-color-secondary p-button-rounded flex-shrink-0" onClick={showConfigSidebar}></Button>
</li>
{isAuthenticated && user && (
<li ref={profileMenuRef} className="profile-item topbar-item">
<StyleClass nodeRef={profileRef} selector="@next" enterClassName="hidden" enterActiveClassName="px-scalein" leaveToClassName="hidden" leaveActiveClassName="px-fadeout" hideOnOutsideClick>
<a className="p-ripple" ref={profileRef}>
<img className="border-circle cursor-pointer" src="/layout/images/avatar/avatar-m-1.jpg" alt="avatar" />
<span className="ml-2 font-medium hidden lg:block">{user.fullName || user.username}</span>
<Ripple />
</a>
</StyleClass>
<ul className="topbar-menu active-topbar-menu p-4 w-20rem z-5 hidden border-round">
<li role="menuitem" className="m-0 mb-3 pb-2 border-bottom-1 surface-border">
<div className="flex flex-column">
<span className="font-medium text-900">{user.fullName || user.username}</span>
<span className="text-sm text-600">{user.email}</span>
<span className="text-xs text-500 mt-1">Rôle: {user.highestRole || 'Utilisateur'}</span>
</div>
</li>
<li role="menuitem" className="m-0 mb-3">
<StyleClass nodeRef={menubutton} selector="@grandparent" enterClassName="hidden" enterActiveClassName="px-scalein" leaveToClassName="hidden" leaveActiveClassName="px-fadeout" hideOnOutsideClick>
<a href="/profile" ref={menubutton} className="flex align-items-center hover:text-primary-500 transition-duration-200">
<i className="pi pi-fw pi-user mr-2"></i>
<span>Mon Profil</span>
</a>
</StyleClass>
</li>
<li role="menuitem" className="m-0 mb-3">
<StyleClass nodeRef={menubuttonRef} selector="@grandparent" enterClassName="hidden" enterActiveClassName="px-scalein" leaveToClassName="hidden" leaveActiveClassName="px-fadeout" hideOnOutsideClick>
<a href="#" ref={menubuttonRef} className="flex align-items-center hover:text-primary-500 transition-duration-200">
<i className="pi pi-fw pi-cog mr-2"></i>
<span>Paramètres</span>
</a>
</StyleClass>
</li>
<li role="menuitem" className="m-0">
<StyleClass nodeRef={btnRef2} selector="@grandparent" enterClassName="hidden" enterActiveClassName="px-scalein" leaveToClassName="hidden" leaveActiveClassName="px-fadeout" hideOnOutsideClick>
<a href="#" ref={btnRef2} onClick={handleLogout} className="flex align-items-center hover:text-primary-500 transition-duration-200">
<i className="pi pi-fw pi-sign-out mr-2"></i>
<span>Se déconnecter</span>
</a>
</StyleClass>
</li>
</ul>
</li>
)}
<li className="right-panel-button relative hidden lg:block">
<Button type="button" label="Today" style={{ width: '5.7rem' }} icon="pi pi-bookmark" className="layout-rightmenu-button md:block font-normal p-button-text p-button-rounded" onClick={showSidebar}></Button>
<Button type="button" icon="pi pi-bookmark" className="layout-rightmenu-button block md:hidden font-normal p-button-text p-button-rounded" onClick={showSidebar}></Button>
</li>
</ul>
</div>
</div>
</React.Fragment>
);
});
export default AppTopbar;
AppTopbar.displayName = 'AppTopbar';