Compare commits

...

6 Commits

Author SHA1 Message Date
ee31eb5511 style: organizations and stuffs 2025-04-04 18:15:58 +01:00
b926019ab6 style: bootstrap version of homepage 2025-04-03 17:10:50 +01:00
d3a8fb56ba style: sidebar & header okay, started home 2025-04-01 23:01:27 +01:00
ea04c954b0 fix: missing .env chore: splashScreen 2025-04-01 20:06:19 +01:00
8c12667693 style: login page Okay 2025-04-01 19:26:46 +01:00
921007ae13 style: responsive 2025-03-28 21:12:10 +01:00
29 changed files with 1306 additions and 821 deletions

View File

@ -14,8 +14,11 @@
"@tanstack/react-query": "^5.69.0",
"@tanstack/react-table": "^8.21.2",
"axios": "^1.8.4",
"bootstrap": "^5.3.3",
"clsx": "^2.1.1",
"declarations": "link:@/lib/declarations",
"jwt-decode": "^4.0.0",
"leaflet": "^1.9.4",
"next": "15.2.3",
"next-auth": "^4.24.11",
"nextjs-toploader": "^3.8.15",
@ -32,6 +35,7 @@
"@eslint/eslintrc": "^3",
"@svgr/webpack": "^8.1.0",
"@tailwindcss/postcss": "^4",
"@types/leaflet": "^1.9.17",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
@ -39,7 +43,6 @@
"eslint-config-next": "15.2.3",
"install": "^0.13.0",
"npm": "^11.2.0",
"tailwindcss": "^4",
"typescript": "^5"
}
}

46
pnpm-lock.yaml generated
View File

@ -23,12 +23,21 @@ importers:
axios:
specifier: ^1.8.4
version: 1.8.4
bootstrap:
specifier: ^5.3.3
version: 5.3.3(@popperjs/core@2.11.8)
clsx:
specifier: ^2.1.1
version: 2.1.1
declarations:
specifier: link:@/lib/declarations
version: link:@/lib/declarations
jwt-decode:
specifier: ^4.0.0
version: 4.0.0
leaflet:
specifier: ^1.9.4
version: 1.9.4
next:
specifier: 15.2.3
version: 15.2.3(@babel/core@7.26.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.86.0)
@ -72,6 +81,9 @@ importers:
'@tailwindcss/postcss':
specifier: ^4
version: 4.0.15
'@types/leaflet':
specifier: ^1.9.17
version: 1.9.17
'@types/node':
specifier: ^20
version: 20.17.27
@ -93,9 +105,6 @@ importers:
npm:
specifier: ^11.2.0
version: 11.2.0
tailwindcss:
specifier: ^4
version: 4.0.15
typescript:
specifier: ^5
version: 5.8.2
@ -1018,6 +1027,9 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
'@radix-ui/colors@3.0.0':
resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==}
@ -1875,12 +1887,18 @@ packages:
'@types/estree@1.0.7':
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
'@types/geojson@7946.0.16':
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/json5@0.0.29':
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
'@types/leaflet@1.9.17':
resolution: {integrity: sha512-IJ4K6t7I3Fh5qXbQ1uwL3CFVbCi6haW9+53oLWgdKlLP7EaS21byWFJxxqOx9y8I0AP0actXSJLVMbyvxhkUTA==}
'@types/node@20.17.27':
resolution: {integrity: sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA==}
@ -2100,6 +2118,11 @@ packages:
boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
bootstrap@5.3.3:
resolution: {integrity: sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==}
peerDependencies:
'@popperjs/core': ^2.11.8
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@ -2845,6 +2868,9 @@ packages:
resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
engines: {node: '>=0.10'}
leaflet@1.9.4:
resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==}
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@ -4716,6 +4742,8 @@ snapshots:
'@parcel/watcher-win32-x64': 2.5.1
optional: true
'@popperjs/core@2.11.8': {}
'@radix-ui/colors@3.0.0': {}
'@radix-ui/number@1.1.0': {}
@ -5614,10 +5642,16 @@ snapshots:
'@types/estree@1.0.7': {}
'@types/geojson@7946.0.16': {}
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
'@types/leaflet@1.9.17':
dependencies:
'@types/geojson': 7946.0.16
'@types/node@20.17.27':
dependencies:
undici-types: 6.19.8
@ -5882,6 +5916,10 @@ snapshots:
boolbase@1.0.0: {}
bootstrap@5.3.3(@popperjs/core@2.11.8):
dependencies:
'@popperjs/core': 2.11.8
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@ -6765,6 +6803,8 @@ snapshots:
dependencies:
language-subtag-registry: 0.3.23
leaflet@1.9.4: {}
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1

View File

@ -49,7 +49,8 @@ export default function LoginPage() {
})
return (
<div>
<div className="d-flex flex-column bg-bluegray h-100 align-items-center">
<div className="login-main d-flex justify-content-center align-items-center position-relative">
<Form
title="Connexion"
formClassName="bg-white p-10 shadow-2xl w-3/4 lg:w-lg"
@ -70,8 +71,13 @@ export default function LoginPage() {
]}
submit={mutation.mutate}
schema={loginSchema}
child={<button disabled={mutation.isPending} type="submit" className={`${mutation.isPending ? "btn-auth-loading" : "btn-auth"} mt-4`}>{mutation.isPending ? "Chargement..." : "Connexion"}</button>}
child={<div className="d-flex justify-content-center w-100"> <button disabled={mutation.isPending} type="submit" className={`${mutation.isPending ? "btn-auth-loading" : "btn-auth"} cta modal-cta`}>{mutation.isPending ? "Chargement..." : "Connexion"}</button></div>}
/>
</div>
<div className="version">
<p className="fw-bold" >Version 0.0.1</p>
</div>
</div>
)
}

View File

@ -86,11 +86,11 @@ export default function HomePage () {
const value = String(row.original.owner.first_name) + " " + String(row.original.owner.last_name)
const initials = String(row.original.owner.first_name[0]) + String(row.original.owner.last_name[0])
return (
<div className="flex space-x-2 items-center">
<div className="flex items-center justify-center bg-[#DCDCFE] text-[#246BFD] w-10 h-10 rounded-full">
<div className="r-flex align-items-center r-gap-16">
<div className="circled-badge">
{initials}
</div>
<p>{value}</p>
<p className="r-p-m-0" >{value}</p>
</div>
)
}
@ -106,12 +106,11 @@ export default function HomePage () {
const status = String(cell.getValue())
return (
<p
className={`rounded-full px-2 py-1 font-medium text-sm w-20 h-6 text-center
${
status === "active" ? "bg-[#ECF9E8] text-[#49C91E]" :
status === "inactive" ? "bg-[#E7EBF3] text-[#9FA8BC]" :
status === "pending" ? "bg-[#EAF7FC] text-[#30B2EA]" :
status === "blocked" ? "bg-[#FDEBE8] text-[#F33F19]" :
className={`custom-badge r-p-m-0 r-flex-center rounded-5
${status === "active" ? "badge-active" :
status === "inactive" ? "badge-inactive" :
status === "pending" ? "badge-pending" :
status === "blocked" ? "badge-blocked" :
""
}
`}
@ -164,7 +163,7 @@ export default function HomePage () {
Voulez-vous vraiment supprimer l'organisation <span className="font-bold">{row.original.name}</span> ?
</p>
<div className="flex justify-between w-full pt-6 r-gap-24">
<div className="r-flex-between w-full pt-6 r-gap-24">
<button
className="cta modal-cta cancel"
onClick={() => {
@ -193,10 +192,10 @@ export default function HomePage () {
]
return (
<div className="space-y-10">
<div className="home home-table r-p-m-0">
<Statistics />
<p className="font-bold text-xl">Dernières organisations actives</p>
<h3 className="fw-bold fs-5 pt-5 pb-4">Dernières organisations actives</h3>
<Table
columns={columns}

View File

@ -24,35 +24,12 @@ export default function Dashboard({ children }: { children: ReactNode }) {
<div className="r-flex-between">
<Sidebar />
<main className="flex-grow-1 min-w-0 pt-md-1 pt-sm-5">
<div className="flex-grow-1">
<Header/>
<div className="main px-[44px] py-[64px] ">
{children}
</div>
</main>
</div>
</div >
)
}
/*
<div className="sidebar r-m-0 d-flex flex-column pt-[16px] max-w-[90px] h-[100vh] relative ">
<div className="logo r-flex-center pt-[13px] px-[20px] ">
<icons.Logo aria-label="Logo" className="scale-95" />
</div>
<div className="nav-menu r-column-center h-max pt-[160px] r-gap-40 ">
<Link href="#" className="nav-item r-flex-center ">
<icons.HomeIcon aria-label="Home" className="nav-home scale-100" />
</Link>
<Link href="#" className="nav-item border-none r-flex-center ">
<icons.CompaniesIcon aria-label="Companies" className="scale-100 " width={24} height={24} />
</Link>
<Link href="#" className="nav-item r-flex-center ">
<icons.UserGroup aria-label="Admins" className="scale-100" width={24} height={24} />
</Link>
</div>
</div>
<div className="logout absolute bottom-[60px] left-[22px]">
<icons.Logout aria-label="Logout" />
</div>
*/

View File

@ -171,11 +171,11 @@ export default function Organizations() {
const value = String(row.original.owner.first_name) + " " + String(row.original.owner.last_name)
const initials = String(row.original.owner.first_name[0]) + String(row.original.owner.last_name[0])
return (
<div className="flex space-x-2 items-center">
<div className="flex items-center justify-center bg-[#DCDCFE] text-[#246BFD] w-10 h-10 rounded-full">
<div className="r-flex align-items-center r-gap-16">
<div className="circled-badge">
{initials}
</div>
<p>{value}</p>
<p className="r-p-m-0" >{value}</p>
</div>
)
}
@ -191,12 +191,11 @@ export default function Organizations() {
const status = String(cell.getValue())
return (
<p
className={`rounded-full px-2 py-1 font-medium text-sm w-20 h-6 text-center
${
status === "active" ? "font-medium w-[80px] h-[24px] bg-[#ECF9E8] text-[#49C91E]" :
status === "inactive" ? "font-medium w-[80px] h-[24px] bg-[#E7EBF3] text-[#9FA8BC]" :
status === "pending" ? "font-medium w-[80px] h-[24px] bg-[#EAF7FC] text-[#30B2EA]" :
status === "blocked" ? "font-medium w-[80px] h-[24px] bg-[#FDEBE8] text-[#F33F19]" :
className={`custom-badge r-p-m-0 r-flex-center rounded-5
${status === "active" ? "badge-active" :
status === "inactive" ? "badge-inactive" :
status === "pending" ? "badge-pending" :
status === "blocked" ? "badge-blocked" :
""
}
`}
@ -291,8 +290,8 @@ export default function Organizations() {
.map((row) => row.original.id);
return (
<div className="grid grid-cols-1 lg:grid-cols-2 w-full space-y-3">
<div className="flex items-center space-x-3">
<div className="r-flex flex-wrap flex-lg-nowrap justify-content-between r-gap-16 w-100">
<div className="r-flex align-items-center items-center space-x-3 r-gap-16">
<input
type="checkbox"
checked={
@ -306,10 +305,10 @@ export default function Organizations() {
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<p className="cta cancel flex gap-2">
<button className="cta cancel flex gap-2">
Sélectionner une action
<Image src={icons.arrowDown} alt="arrow down" />
</p>
</button >
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
@ -328,7 +327,7 @@ export default function Organizations() {
</DropdownMenu.Root>
</div>
<div className="flex justify-between lg:justify-end space-x-3">
<div className="r-flex-between w-100 justify-content-lg-end r-gap-24">
{/* Modal d'ajout */}
<Modal
title="Ajouter une organisation"

View File

@ -1,8 +1,6 @@
@import "tailwindcss";
@font-face {
font-family: 'Urbanist'; /* Nom que vous donnerez à votre police */
src: url('../assets/fonts/Urbanist.ttf') format('truetype'); /* Chemin vers votre fichier */
font-family: 'Urbanist';
src: url('../assets/fonts/Urbanist.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@ -14,26 +12,41 @@
--secondary: #9FA8BC;
--danger: #F33F19;
--cinder: #E7E5E4;
--lightblue: #DCDCFE;
--bluegray: #E9F0FF;
--gray: #E7EBF3;
}
[ data-theme="dark"] {
--background: #04060F;
--foreground: #ffffff;
--background: #11111a;
--foreground: #eeeeff;
/* --secondary: #000; */
--cinder: #444;
--bluegray: #246BFD55;
}
@media (prefers-color-scheme: dark) {
/* @media (prefers-color-scheme: dark) {
:root {
--foreground: #04060F;
--foreground: #2a2a2a;
--background: #ffffff;
--cinder: #999;
--bluegray: --primary;
}
}
} */
body {
background: var(--background);
color: var(--foreground);
font-family: Urbanist, sans-serif;
background: var(--background)!important;
color: var(--foreground)!important;
font-family: Urbanist, sans-serif !important;
}
*{
margin: 0;
padding: 0;
}
a{
text-decoration: none!important;
color: inherit!important;
}
.input-form {
@ -41,7 +54,8 @@ body {
padding: 12px;
border: 1px solid #d1d5dc;
border-radius: 9999px;
color: black;
color: var(--foreground);
background-color: var(--background);
&:focus {
outline-color: none;
@ -52,18 +66,32 @@ body {
position: absolute;
left: 12px;
top: -0.45rem;
background-color: white;
padding-inline: 4px;
padding: 1px 5px;
line-height: normal;
color: var(--secondary);
background-color: var(--background);
border-radius: 400px;
z-index: 1;
}
.form-error {
font-size: 14px;
color: var(--danger);
}
.btn-floating-right {
position: absolute;
right: 8px;
right: 12px;
top: 50%;
transform: translateY(-50%);
}
.btn-floating-right.select{
position: relative!important;
right: 0px!important;
}
.btn-floating-left {
position: absolute;
left: 8px;
@ -100,6 +128,11 @@ body {
transition: width 0.2s, height 0.2s;
}
button {
background-color: transparent;
border: none;
}
.cta {
padding: 10px 24px;
width: max-content;
@ -115,8 +148,9 @@ body {
}
.cta.modal-cta {
padding: 9px;
margin-top: 32px;
width: 240px;
height: 40px;
}
.cta.cancel {
@ -139,9 +173,11 @@ body {
.bg-bluegray {
background-color: var(--bluegray);
}
.bg-gray {
background-color: var(--gray);
}
hr {
color: var(--gray);
}
@ -184,10 +220,39 @@ input[type="checkbox"]:checked::before {
}
/* Splash Screnn */
.splash-screen {
position: fixed;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #04060F;
background-color: #E9F0FF;
z-index: 99;
}
.splash-screen p{
width: max-content;
font-size: 32px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.splash-screen span {
/* font-family: "Inter 200"; */
font-weight: 100 !important;
}
/* Scroll Bar */
::-webkit-scrollbar {
width: 4px;
width: 7px;
padding: 0;
margin: 0;
}
@ -223,3 +288,105 @@ input[type="checkbox"]:checked::before {
height: 16px;
}
}
/* Login Header */
.login-header {
padding: 20px 0;
box-shadow: 0 0 24px #0000001A;
/* background-color: white; */
}
.word {
font-size: 24px;
font-weight: bold;
/* color: black; */
position: relative;
line-height: normal;
}
.dot {
/* font-size: 14px; */
color: blue;
position: absolute;
top: -10px;
left: 22px;
animation: bounce 1s infinite ease-in-out;
}
.splash-screen .dot{
font-size: 48px;
top: -28px;
left: 28px;
animation: bounce 1s infinite ease-in-out;
}
@keyframes bounce {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-3px);
}
}
.login-main {
min-height: 100vh;
}
.form-container {
padding: 48px 64px;
margin: auto;
width: max-content;
max-width: 624px;
border-radius: 8px;
box-shadow: 0 0 24px #0000001A;
}
.form-fields {
gap: 24px;
}
@media (max-width: 768px) {
.splash-screen p{
font-size: 24px;
}
.login-main{
width: 100%;
}
.form-container {
padding: 24px 32px;
margin: 0 4%;
width: 80%;
}
.form-fields {
gap: 12px;
}
.modal-input {
width: 100%;
min-width: 100%;
}
.form-title{
margin-bottom: 2px!important;
}
.cta.modal-cta{
margin: 0!important;
}
.input-form{
margin: 0 auto;
}
}

View File

@ -4,6 +4,7 @@ import NextTopLoader from "nextjs-toploader";
import "../assets/css/ruben-ui.css"
import { AuthProvider } from "#/components/provider/authProvider";
import { QueryClientProvide } from "#/components/provider/queryClient";
import SplashScreen from "#/components/splashScreen";
export const metadata: Metadata = {
title: "Private Docs",
@ -21,10 +22,13 @@ export default function RootLayout({
<head>
<link rel="icon" href="/favicon.svg" />
<link rel="favicon.svg" href="/favicon.svg" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossOrigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossOrigin="anonymous"></script>
</head>
<body>
<AuthProvider>
<QueryClientProvide>
<SplashScreen name="White" label="developer" timer={2000} />
<NextTopLoader color="#246BFD" shadow="0" />
{children}
</QueryClientProvide>

View File

@ -1,10 +1,28 @@
/* Header */
.sidebar-holder, .sidebar{
min-width: 78px;
max-width: 90px;
height: 100vh;
}
.header{
padding: 20px 44px;
height: max-content;
align-items: center;
/* border: solid; */
}
/* Sidebar */
.sidebar {
padding-top: 25px;
border-right: 1px solid var(--cinder);
position: fixed;
}
.nav-menu{
padding-top: 160px;
}
.nav-item .nav-home {
margin-bottom: -10px;
}
@ -29,33 +47,62 @@
margin-top: -11px;
margin-bottom: -11px;
}
.logout{
bottom: 40px;
left: 28px;
}
/* Border */
.icon-border {
border: 1px solid var(--cinder);
width: 42px;
height: 42px;
height: max-content;
border: 1px solid var(--bluegray);
padding: 8px;
border-radius: 12px;
cursor: pointer;
}
.dropdown-toggle{
align-items: center!important;
}
.dropdown-menu {
width: max-content;
background-color: var(--background);
border: none!important;
border-radius: 8px;
box-shadow: 0 0 24px #0000001A;
box-shadow: 0 0 24px #0000001A!important;
}
.dropdown-item a {
width: max-content;
.dropdown-menu{
right: 0px!important;
}
.r-dropdown-item a {
width: 100%;
padding: 10px 20px;
margin: 0!important;
display: flex;
justify-content: space-between;
justify-content: start;
align-items: center;
gap: 10px;
}
.r-dropdown-item a:hover {
background-color: var(--cinder);
}
.dropdown-toggle::after{
content: unset!important;
}
.transition-300{
transition: transform .3s ;
}
/* Main */
.main{
padding: 64px 44px;
}
.p-container {
height: 100vh;
border: 1px solid var(--gray);
@ -95,14 +142,189 @@
width: 284px;
}
.header-desktop{
display: flex!important;
}
.mobile{
display: none!important;
}
@media (max-width: 1024px) {
.admin-infos {
/* justify-content: space-between; */
/* gap: 30px; */
/* Home Page */
.stats{
width: 22%;
max-width: 400px;
height: 108px;
max-height: 108px;
padding: 24px 27px;
display: flex;
flex-grow: 1;
flex-wrap: nowrap!important;
border: 1px solid!important;
border-color: var(--primary)!important;
border-radius: 14px;
}
.admin-card {
/* max-width: 100%; */
.sqarre-bg{
width: 54px;
height: 54px;
padding: 10px;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
background: var(--bluegray);
}
th{
font-size: 14px;
padding: 8px;
height: 40px!important;
}
th:first-of-type{
border-top-left-radius: 8px!important;
}
th:last-of-type{
border-top-right-radius: 8px!important;
}
tbody tr {
height: 56px!important;
max-height: 56px!important;
overflow: hidden;
border-bottom: 1px solid var(--bluegray)!important;
}
tbody tr:hover{
background-color: var(--bluegray);
}
tbody tr td:first-child {
padding-left: 16px;
width: 56px;
}
tbody tr td:last-child {
width: 56px;
padding-right: 16px;
}
.circled-badge{
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
font-weight: 500!important;
border-radius: 40px;
color: var(--primary);
background-color: var(--lightblue);
}
.custom-badge{
width: 80px;
height: 24px;
}
.badge-active{
color: #49C91E;
background-color: #ECF9E8;
}
.badge-inactive{
color: #9FA8BC;
background-color: #E7EBF3;
}
.badge-pending{
color: #30B2EA;
background-color: #EAF7FC;
}
.badge-blocked{
color: #F33F19;
background-color: #FDEBE8;
}
a.disabled{
opacity: 40%;
}
.home .pagination {
display: none!important;
}
.search-input{
padding: 10px 40px;
width: max-content;
width: 300px;
min-width: max-content;
border: 1px solid var(--secondary);
border-radius: 100px;
}
@media (max-width: 1070px) {
.stats-container{
justify-content: space-evenly;
}
.stats{
width: 300px;
}
}
@media (max-width: 640px) {
.header, .main{
padding-left: 22px;
padding-right: 22px;
}
.header-desktop{
display: none!important;
}
.mobile{
display: flex!important;
}
.mobile-flex{
display: flex;
}
.mobile-none{
display: none;
}
.header .name{
padding-left: 44px;
}
.sidebar{
transition: all ease-in-out .4s;
}
.hamburger{
position: absolute;
top: 43px;
left: 22px;
transform: scale(2);
}
.hamburger.shifted{
left: 100px;
}
.hamburger-icon{
color: var(--primary);
border-radius: 4px;
}
.stats-container{
/* flex-direction: column; */
align-items: center;
}
.stats{
width: 300px;
}
}

View File

@ -0,0 +1,8 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.0001 29.3333H20.0001C26.6667 29.3333 29.3334 26.6667 29.3334 20V12C29.3334 5.33334 26.6667 2.66667 20.0001 2.66667H12.0001C5.33341 2.66667 2.66675 5.33334 2.66675 12V20C2.66675 26.6667 5.33341 29.3333 12.0001 29.3333Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 10.3333V19.3333C24 17.8667 22.8 16.6667 21.3333 16.6667H10.6667C9.2 16.6667 8 17.8667 8 19.3333V10.3333C8 8.86667 9.2 7.66667 10.6667 7.66667H21.3333C22.8 7.66667 24 8.86667 24 10.3333Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M25.3333 21H24" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.00008 21H6.66675" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 18.6667V14.6667C24 13.2 22.8 12 21.3333 12H10.6667C9.2 12 8 13.2 8 14.6667V18.6667" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 19.3333V21H19.3333C19.3333 22.84 17.84 24.3333 16 24.3333C14.16 24.3333 12.6667 22.84 12.6667 21H8V19.3333C8 17.8667 9.2 16.6667 10.6667 16.6667H21.3333C22.8 16.6667 24 17.8667 24 19.3333Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,9 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.3333 29.3333H6.66663C3.99996 29.3333 2.66663 28 2.66663 25.3333V14.6667C2.66663 12 3.99996 10.6667 6.66663 10.6667H13.3333V25.3333C13.3333 28 14.6666 29.3333 17.3333 29.3333Z" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.4799 5.33333C13.3733 5.73333 13.3333 6.17333 13.3333 6.66666V10.6667H6.66663V7.99999C6.66663 6.53333 7.86663 5.33333 9.33329 5.33333H13.4799Z" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.6666 10.6667V17.3333" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 10.6667V17.3333" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22.6666 22.6667H20C19.2666 22.6667 18.6666 23.2667 18.6666 24V29.3333H24V24C24 23.2667 23.4 22.6667 22.6666 22.6667Z" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 17.3333V22.6667" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.3334 25.3333V6.66667C13.3334 4.00001 14.6667 2.66667 17.3334 2.66667H25.3334C28 2.66667 29.3334 4.00001 29.3334 6.66667V25.3333C29.3334 28 28 29.3333 25.3334 29.3333H17.3334C14.6667 29.3333 13.3334 28 13.3334 25.3333Z" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,16 @@
import React from "react";
//import { GeneralHtmlAttr } from "@/lib/declarations";
//export type GeneralHtmlAttr = React.HTMLAttributes<HTMLDivElement>;
import L from "leaflet";
export const HomeIcon = (props) => {
return (
<div {...props}>
<svg width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.25 11L10.205 2.045C10.3094 1.94056 10.4333 1.85772 10.5697 1.80119C10.7061 1.74467 10.8523 1.71558 11 1.71558C11.1477 1.71558 11.2939 1.74467 11.4303 1.80119C11.5667 1.85772 11.6906 1.94056 11.795 2.045L20.75 11M3.5 8.75V18.875C3.5 19.496 4.004 20 4.625 20H8.75V15.125C8.75 14.504 9.254 14 9.875 14H12.125C12.746 14 13.25 14.504 13.25 15.125V20H17.375C17.996 20 18.5 19.496 18.5 18.875V8.75M7.25 20H15.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</div>
);
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 462 KiB

View File

@ -22,6 +22,7 @@ import menuIcon from "./Menu Dots.svg"
import messagesIcon from "./message.svg"
import homeIcon from "./NavItem.svg"
import companiesIcon from "./buildings.svg"
import companiesIconBlue from "./buildingsBlue.svg"
import arrowLeft from "./arrowLeft.svg"
import arrowRight from "./arrowRight.svg"
import filesIcon from "./ph_files.svg"
@ -43,6 +44,8 @@ import trash from "./trash.svg"
import mailIcon from "./sms.svg"
import personalCard from "./personalcard.svg"
import arrowDown from "#/assets/icons/chevron-down.svg"
import peopleIcon from "#/assets/icons/people.svg"
import docsArchive from "#/assets/icons/archive.svg"
export const icons = {
@ -57,13 +60,16 @@ export const icons = {
eyeIcon,
eyeSlashIcon,
checkboxchedIcon,
peopleIcon,
crossIcon,
addBlueIcon,
docsArchive,
archivesIcon,
notificationsIcon,
timerIcon,
logo,
companiesIcon,
companiesIconBlue,
logout,
logoutRed,
maximizeIcon,
@ -93,91 +99,3 @@ export const icons = {
arrowDown
}
/*
import AddIcon from "./add.svg";
import CalendarIcon from "./Calendar Mark.svg";
import DocummentTextIcon from "./document-text.svg";
import FolderIcon from "./Document.svg";
import EditIcon from "./edit-2.svg";
import GridIcon from "./element-3-white.svg";
import GridBlueIcon from "./element-3.svg";
import ProfilePicture from "./Ellipse 2.svg";
import EyeIcon from "./eye.svg";
import EyeSlashIcon from "./eye-slash.svg";
import CheckboxchedIcon from "./checked.svg";
import CrossIcon from "./cross.svg";
import AddBlueIcon from "./icon-add.svg";
import ArchivesIcon from "./archives.svg";
import NotificationsIcon from "./notifications.svg";
import TimerIcon from "./Line Duotone.svg";
import Logo from "./logo.svg";
import LogoutRed from "./logout-red.svg";
import Logout from "./logout.svg";
import MaximizeIcon from "./maximize-3.svg";
import MenuIcon from "./Menu Dots.svg";
import MessagesIcon from "./message.svg";
import HomeIcon from "./NavItem.svg";
import CompaniesIcon from "./buildings.svg";
import ArrowLeft from "./arrowLeft.svg";
import ArrowRight from "./arrowLeft.svg";
import FilesIcon from "./ph_files.svg";
import PdfIcon from "./prime_file-pdf.svg";
import WordIcon from "./prime_file-word.svg";
import UserIcon from "./profile.svg";
import UserGroup from "./profile-2user.svg";
import UserGroupBlue from "./profile-2user-blue.svg";
import Rectanagle from "./Rectangle.svg";
import SearchIcon from "./Search.svg";
import SettingsIcon from "./setting-2.svg";
import FilterIcon from "./setting-3.svg";
import ShareIcon from "./share.svg";
import StarIcon from "./star.svg";
import ArrowUp from "./Vector.svg";
export const icons = {
AddIcon,
CalendarIcon,
DocummentTextIcon,
FolderIcon,
EditIcon,
GridIcon,
GridBlueIcon,
ProfilePicture,
EyeIcon,
EyeSlashIcon,
CheckboxchedIcon,
CrossIcon,
AddBlueIcon,
ArchivesIcon,<svg width="16" height="16" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="display:var(--theme-toggle-moon-icon-display)"><path d="M2.89998 0.499976C2.89998 0.279062 2.72089 0.0999756 2.49998 0.0999756C2.27906 0.0999756 2.09998 0.279062 2.09998 0.499976V1.09998H1.49998C1.27906 1.09998 1.09998 1.27906 1.09998 1.49998C1.09998 1.72089 1.27906 1.89998 1.49998 1.89998H2.09998V2.49998C2.09998 2.72089 2.27906 2.89998 2.49998 2.89998C2.72089 2.89998 2.89998 2.72089 2.89998 2.49998V1.89998H3.49998C3.72089 1.89998 3.89998 1.72089 3.89998 1.49998C3.89998 1.27906 3.72089 1.09998 3.49998 1.09998H2.89998V0.499976ZM5.89998 3.49998C5.89998 3.27906 5.72089 3.09998 5.49998 3.09998C5.27906 3.09998 5.09998 3.27906 5.09998 3.49998V4.09998H4.49998C4.27906 4.09998 4.09998 4.27906 4.09998 4.49998C4.09998 4.72089 4.27906 4.89998 4.49998 4.89998H5.09998V5.49998C5.09998 5.72089 5.27906 5.89998 5.49998 5.89998C5.72089 5.89998 5.89998 5.72089 5.89998 5.49998V4.89998H6.49998C6.72089 4.89998 6.89998 4.72089 6.89998 4.49998C6.89998 4.27906 6.72089 4.09998 6.49998 4.09998H5.89998V3.49998ZM1.89998 6.49998C1.89998 6.27906 1.72089 6.09998 1.49998 6.09998C1.27906 6.09998 1.09998 6.27906 1.09998 6.49998V7.09998H0.499976C0.279062 7.09998 0.0999756 7.27906 0.0999756 7.49998C0.0999756 7.72089 0.279062 7.89998 0.499976 7.89998H1.09998V8.49998C1.09998 8.72089 1.27906 8.89997 1.49998 8.89997C1.72089 8.89997 1.89998 8.72089 1.89998 8.49998V7.89998H2.49998C2.72089 7.89998 2.89998 7.72089 2.89998 7.49998C2.89998 7.27906 2.72089 7.09998 2.49998 7.09998H1.89998V6.49998ZM8.54406 0.98184L8.24618 0.941586C8.03275 0.917676 7.90692 1.1655 8.02936 1.34194C8.17013 1.54479 8.29981 1.75592 8.41754 1.97445C8.91878 2.90485 9.20322 3.96932 9.20322 5.10022C9.20322 8.37201 6.82247 11.0878 3.69887 11.6097C3.45736 11.65 3.20988 11.6772 2.96008 11.6906C2.74563 11.702 2.62729 11.9535 2.77721 12.1072C2.84551 12.1773 2.91535 12.2458 2.98667 12.3128L3.05883 12.3795L3.31883 12.6045L3.50684 12.7532L3.62796 12.8433L3.81491 12.9742L3.99079 13.089C4.11175 13.1651 4.23536 13.2375 4.36157 13.3059L4.62496 13.4412L4.88553 13.5607L5.18837 13.6828L5.43169 13.7686C5.56564 13.8128 5.70149 13.8529 5.83857 13.8885C5.94262 13.9155 6.04767 13.9401 6.15405 13.9622C6.27993 13.9883 6.40713 14.0109 6.53544 14.0298L6.85241 14.0685L7.11934 14.0892C7.24637 14.0965 7.37436 14.1002 7.50322 14.1002C11.1483 14.1002 14.1032 11.1453 14.1032 7.50023C14.1032 7.25044 14.0893 7.00389 14.0623 6.76131L14.0255 6.48407C13.991 6.26083 13.9453 6.04129 13.8891 5.82642C13.8213 5.56709 13.7382 5.31398 13.6409 5.06881L13.5279 4.80132L13.4507 4.63542L13.3766 4.48666C13.2178 4.17773 13.0353 3.88295 12.8312 3.60423L12.6782 3.40352L12.4793 3.16432L12.3157 2.98361L12.1961 2.85951L12.0355 2.70246L11.8134 2.50184L11.4925 2.24191L11.2483 2.06498L10.9562 1.87446L10.6346 1.68894L10.3073 1.52378L10.1938 1.47176L9.95488 1.3706L9.67791 1.2669L9.42566 1.1846L9.10075 1.09489L8.83599 1.03486L8.54406 0.98184ZM10.4032 5.30023C10.4032 4.27588 10.2002 3.29829 9.83244 2.40604C11.7623 3.28995 13.1032 5.23862 13.1032 7.50023C13.1032 10.593 10.596 13.1002 7.50322 13.1002C6.63646 13.1002 5.81597 12.9036 5.08355 12.5522C6.5419 12.0941 7.81081 11.2082 8.74322 10.0416C8.87963 10.2284 9.10028 10.3497 9.34928 10.3497C9.76349 10.3497 10.0993 10.0139 10.0993 9.59971C10.0993 9.24256 9.84965 8.94373 9.51535 8.86816C9.57741 8.75165 9.63653 8.63334 9.6926 8.51332C9.88358 8.63163 10.1088 8.69993 10.35 8.69993C11.0403 8.69993 11.6 8.14028 11.6 7.44993C11.6 6.75976 11.0406 6.20024 10.3505 6.19993C10.3853 5.90487 10.4032 5.60464 10.4032 5.30023Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
NotificationsIcon,
TimerIcon,
Logo,
CompaniesIcon,
Logout,
LogoutRed,
MaximizeIcon,
MenuIcon,
MessagesIcon,
HomeIcon,
ArrowLeft,
ArrowRight,
FilesIcon,
PdfIcon,
WordIcon,
UserIcon,
UserGroup,
UserGroupBlue,
Rectanagle,
SearchIcon,
SettingsIcon,
FilterIcon,
ShareIcon,
StarIcon,
ArrowUp
};
*/

View File

@ -0,0 +1,8 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.9999 9.54668C23.9199 9.53334 23.8266 9.53334 23.7466 9.54668C21.9066 9.48001 20.4399 7.97334 20.4399 6.10667C20.4399 4.20001 21.9733 2.66667 23.8799 2.66667C25.7866 2.66667 27.3199 4.21334 27.3199 6.10667C27.3066 7.97334 25.8399 9.48001 23.9999 9.54668Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22.6266 19.2534C24.4532 19.56 26.4666 19.24 27.8799 18.2934C29.7599 17.04 29.7599 14.9867 27.8799 13.7334C26.4532 12.7867 24.4132 12.4667 22.5865 12.7867" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.96002 9.54668C8.04002 9.53334 8.13335 9.53334 8.21335 9.54668C10.0533 9.48001 11.52 7.97334 11.52 6.10667C11.52 4.20001 9.98668 2.66667 8.08002 2.66667C6.17335 2.66667 4.64001 4.21334 4.64001 6.10667C4.65335 7.97334 6.12002 9.48001 7.96002 9.54668Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.33337 19.2534C7.50671 19.56 5.49338 19.24 4.08004 18.2934C2.20004 17.04 2.20004 14.9867 4.08004 13.7334C5.50671 12.7867 7.54671 12.4667 9.37337 12.7867" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M15.9999 19.5067C15.9199 19.4933 15.8266 19.4933 15.7466 19.5067C13.9066 19.44 12.4399 17.9333 12.4399 16.0667C12.4399 14.16 13.9733 12.6267 15.8799 12.6267C17.7866 12.6267 19.3199 14.1733 19.3199 16.0667C19.3066 17.9333 17.8399 19.4533 15.9999 19.5067Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.12 23.7067C10.24 24.96 10.24 27.0133 12.12 28.2667C14.2533 29.6933 17.7466 29.6933 19.88 28.2667C21.76 27.0133 21.76 24.96 19.88 23.7067C17.76 22.2933 14.2533 22.2933 12.12 23.7067Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -12,34 +12,53 @@ export default function AdminHeader() {
return (
<>
<nav className="header r-flex-between px-[44px] py-[20px] ">
<p className="name text-[26px]">Bienvenue, <span>Ken B.</span> </p>
<div className="r-flex-between justify-center items-center r-gap-12">
<nav className="header r-flex-between align-items-center ">
<p className="r-m-0 name fs-4 fw-medium">Bienvenue, <span>Ken B.</span> </p>
<div className="r-flex-between justify-content-center align-items-center r-gap-12">
<div className="header-desktop">
<Theme />
{/* <ProfilePicture /> */}
<button type="button" className="icon-border">
</div>
<button type="button" className="icon-border header-desktop">
<Image src={icons.notificationsIcon} alt="Notifications" />
</button>
<div className="relative">
<DropdownMenu.Root open={open} onOpenChange={setOpen}>
<DropdownMenu.Trigger asChild>
<div className="r-flex-between justify-center items-center r-gap-12 cursor-pointer ">
<div className="dropdown">
<div className="r-flex-between dropdown-toggle justify-center items-center r-gap-12 cursor-pointer" data-bs-toggle="dropdown" aria-expanded="false">
<button type="button" className="icon-borderd mobile scale-120" >
<Image src={icons.arrowLeft} alt="options" className={`transition-300 transition-transform duration-300 ${open ? " " : ""}`} />
</button>
<Image src={icons.profilePicture} alt="ProfilePicture" />
<button className="IconButton" aria-label="Customise options">
<Image src={icons.arrowUp} alt="arrowUp" className={`transition-transform duration-300 ${open ? "scale-y-[-1]" : ""}`}/>
<button className="IconButton header-desktop" aria-label="Customise options">
<Image src={icons.arrowUp} alt="arrowUp" className={`transition-300 transition-transform duration-300 ${open ? "" : ""}`} />
</button>
</div>
<ul className="dropdown-menu">
<li className="r-dropdown-item text-[14px]">
<Link href="#" className="d-flex align-items-center ">
<Image src={icons.userIcon} alt="Profil" />
Profil
</Link>
</li>
<li className="r-dropdown-item text-[14px]">
<Link href="#" className="d-flex align-items-center r-danger ">
<Image src={icons.logoutRed} alt="Deconnexion" />
Déconnexion
</Link>
</li>
</ul>
</div>
<div className="position-relative">
<DropdownMenu.Root open={open} onOpenChange={setOpen}>
<DropdownMenu.Trigger asChild>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content className="DropdownMenuContent dropdown-menu r-flex-column r-secondary" sideOffset={0} side="bottom" align="end" >
<DropdownMenu.Item className="DropdownMenuItem dropdown-item text-[14px]">
<Link href="#" className="d-flex items-start ">
<Image src={icons.userIcon} alt="Profil" />
Profil
</Link>
</DropdownMenu.Item>
{/* <DropdownMenu.Item className="DropdownMenuItem dropdown-item flex items-center content-center text-[14px] mobile">
<Theme />
</DropdownMenu.Item> */}
<DropdownMenu.Item className="DropdownMenuItem dropdown-item text-[14px]">
<Link href="#" className="d-flex items-start r-danger ">
<Image src={icons.logoutRed} alt="Deconnexion" />

View File

@ -7,12 +7,13 @@ interface ItemProps {
label: string;
isActive: boolean;
isNavHome?: boolean;
classname?: string
}
export default function NavItem({ link, iconSrc, label, isActive, isNavHome }: ItemProps) {
export default function NavItem({ link, iconSrc, label, isActive, isNavHome, classname }: ItemProps) {
return (
<>
<Link href={link} className={`nav-item r-flex-center ${isActive ? "active" : ""}`} >
<Link href={link} className={`nav-item r-flex-center ${isActive ? "active" : ""} ${classname}`} >
<Image src={iconSrc} alt={label} className={`scale-100 ${isNavHome ? "nav-home" : ""}`} />
</Link>
</>

View File

@ -4,31 +4,44 @@ import { icons } from "#/assets/icons"
import NavItem from "./navItem";
import { usePathname } from "next/navigation";
import Link from "next/link";
import { useState } from "react";
export default function Sidebar() {
const pathname = usePathname();
const [mobileVisible, setmobileVisible] = useState(false)
const handleMobileVisible = ()=> {
setmobileVisible(!mobileVisible)
}
return (
<>
<div className="sidebar-holder min-w-[78px] max-w-[90px] h-[100vh] ">
<div className="sidebar r-m-0 d-flex flex-column pt-[25px] max-w-[90px] h-[100vh] ">
<div className={` ${ mobileVisible? "mobile-flex" : "mobile-none" } sidebar-holder position-relative `}>
<div className="sidebar r-m-0 d-flex flex-column ">
<div className="logo r-flex-center px-[19px] ">
<Image src={icons.logo} alt="Logo" className="scale-95" />
</div>
<div className="nav-menu r-column-center h-max pt-[160px] r-gap-40 ">
<NavItem link="/admin/home" iconSrc={icons.homeIcon} label="Home" isNavHome={true} isActive={(pathname === "/admin/") || (pathname === "/admin/home")} />
<NavItem link="/admin/organizations" iconSrc={icons.companiesIcon} label="Organizations" isActive={pathname.startsWith("/admin/organizations")} />
<NavItem link="/admin/admins" iconSrc={icons.userGroup} label="Admins" isActive={pathname.startsWith("/admin/admins")} />
<NavItem link="/admin/organizations" iconSrc={icons.companiesIcon} label="Organizations" isActive={pathname.startsWith("/admin/organizations")} classname="disabled" />
<NavItem link="/admin/admins" iconSrc={icons.userGroup} label="Admins" isActive={pathname.startsWith("/admin/admins")} classname="disabled" />
</div>
<div className="logout absolute bottom-[40px] left-[28px]">
<div className="logout position-absolute bottom-[40px] left-[28px]">
<Link href="/login" className="cursor-pointer">
<Image src={icons.logout} alt="Logout" />
</Link>
</div>
</div>
</div>
<div onClick={() => handleMobileVisible()} className={`${mobileVisible ? "shifted" : ""} hamburger mobile`}>
{/* <Image src={icons.logo} alt="Logo" className="scale-95" /> */}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-list hamburger-icon" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5"/>
</svg>
</div>
</>
)
}

View File

@ -8,7 +8,7 @@ export default function Theme() {
useEffect(() => {
if (typeof window !== "undefined") {
const savedTheme = localStorage.getItem("theme") ||
const savedTheme = localStorage.getItem("privateDocsTheme") ||
(window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
setTheme(savedTheme);
@ -19,7 +19,7 @@ export default function Theme() {
const handleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
localStorage.setItem("privateDocsTheme", newTheme);
document.body.setAttribute("data-theme", newTheme);
};
@ -30,7 +30,7 @@ export default function Theme() {
const handleChange = (e: MediaQueryListEvent) => {
const newTheme = e.matches ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
localStorage.setItem("privateDocsTheme", newTheme);
document.body.setAttribute("data-theme", newTheme);
};

View File

@ -30,7 +30,7 @@ export default function FloatingLabelInput({
switch(type) {
case 'select':
return (
<div className="relative w-full">
<div className="position-relative w-full">
<select
className="input-form modal-input focus:ring-2 focus:ring-blue-500 outline-none"
name={name}
@ -40,13 +40,13 @@ export default function FloatingLabelInput({
<option key={index} value={option.value}>{option.label}</option>
))}
</select>
{button && <div className="btn-floating-right">{button}</div>}
{button && <div className="btn-floating-right select">{button}</div>}
</div>
);
case 'password':
return (
<div className="relative w-full">
<div className="position-relative w-full">
<input
name={name}
type={showPassword ? "text" : "password"}
@ -66,14 +66,14 @@ export default function FloatingLabelInput({
src={icons.eyeSlashIcon}
width={20}
height={20}
alt=''
alt='show password'
/>
) : (
<Image
src={icons.eyeIcon}
width={20}
height={20}
alt=''
alt='hide password'
/>
)}
</button>
@ -84,14 +84,14 @@ export default function FloatingLabelInput({
case 'search':
return (
<div className="relative w-full">
<div className="position-relative w-full">
<div className='btn-floating-left'>
<Image alt='' src={icons.searchIcon} />
</div>
<input
type="text"
placeholder={placeholder}
className="focus:ring-2 focus:ring-blue-500 outline-none px-10 py-2 w-full text-black border border-[#d1d5dc] rounded-full"
className="search-input focus:ring-2 focus:ring-blue-500 outline-none px-10 py-2 w-full ctext-black border border-[#d1d5dc] rounded-full"
name={name}
defaultValue={defaultValue}
onChange={handleChange}
@ -102,7 +102,7 @@ export default function FloatingLabelInput({
default:
return (
<div className="relative w-full">
<div className="position-relative w-full">
<input
type={type}
placeholder={placeholder}
@ -118,7 +118,7 @@ export default function FloatingLabelInput({
};
return (
<div className="relative">
<div className="position-relative">
<label
htmlFor={name}
className="input-label text-gray-400 text-sm"

View File

@ -43,12 +43,12 @@ export default function Form({
}
return (
<form onSubmit={handleSubmit} className={formClassName}>
<div className="flex justify-center text-black">
<p className="text-3xl font-bold">{title}</p>
<form onSubmit={handleSubmit} className={(formClassName) + " form-container"}>
<div className="form-title d-flex justify-content-center text-black mb-3 ">
<p className="fs-3 fw-bold">{title}</p>
</div>
<div className={`space-y-8 my-2 ${className}`}>
<div className={`d-flex flex-column form-fields ${className}`}>
{
fields.map((item, index) => (
@ -64,13 +64,12 @@ export default function Form({
showPasswordToggle={item.showPasswordToggle}
/>
<span className="text-red-500 text-xs mt-1">{errors[item.name]}</span>
<span className="form-error">{errors[item.name]}</span>
</div>
))
}
</div>
{child}
</form>
)
}

View File

@ -3,14 +3,15 @@ import Image from "next/image";
export default function Header() {
return (
<div className="w-full bg-white shadow-md py-4">
<div className="container mx-auto text-center flex items-center justify-center gap-2">
<div className="d-flex justify-content-center login-header ">
<div className="d-flex justify-content-center align-items-center gap-2">
<Image
src={icons.logo}
alt="Private Docs"
className="text-red-500 h-auto"
height={30}
/>
<p className="text-2xl font-bold text-black">Private Docs</p>
<p className="r-p-m-0 word">Pr<span className="dot"></span>ıvate Docs</p>
</div>
</div>
)

View File

@ -0,0 +1,63 @@
"use client"
import Image from "next/image";
import { icons } from "#/assets/icons";
import { ReactNode, useEffect, useState } from "react";
interface Props {
name: string
label: string
timer: number,
}
export default function SplashScreen({ name, label, timer }: Props) {
const [showSplash, setShowSplash] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => setShowSplash(false), timer);
if (typeof window !== undefined) {
if (!sessionStorage.getItem('sessionInitialized')) {
setShowSplash(true);
// Set session
} else {
setShowSplash(false);
//console.log('Session already exists');
}
const handleUnload = () => sessionStorage.removeItem('sessionInitialized')
window.addEventListener("beforeunload", handleUnload);
return () => {
clearTimeout(timeout)
handleUnload
} // Clean up the timeout on unmount
}
}, [timer]);
return (
<>
{showSplash &&
<div className="splash-screen w-[100vw] h-[100vh] ">
<div className="d-flex justify-content-center align-items-center gap-3">
<Image
src={icons.logo}
alt="Private Docs"
className="text-red-500 h-auto"
height={48}
/>
<p className="r-p-m-0 word">Pr<span className="dot"></span>ıvate Docs</p>
</div>
</div>
}
</>
)
}

View File

@ -32,22 +32,22 @@ export default function Statistics() {
})
const statsData: StatsType[] = [
{ id: 1, title: 'Organisations', value: stats?.companies, icon: icons.companiesIcon, color: 'blue' },
{ id: 2, title: 'Utilisateurs', value: stats?.users, icon: icons.userIcon, color: 'blue' },
{ id: 3, title: 'Documents', value: stats?.documents, icon: icons.docummentTextIcon, color: 'blue' },
{ id: 4, title: 'Stockage', value: stats?.documents_size, icon: icons.archivesIcon, color: 'blue' }
{ id: 1, title: 'Organisations', value: stats?.companies, icon: icons.companiesIconBlue, color: 'blue' },
{ id: 2, title: 'Utilisateurs', value: stats?.users, icon: icons.peopleIcon, color: 'blue' },
{ id: 3, title: 'Documents', value: stats?.documents, icon: icons.docsArchive, color: 'blue' },
{ id: 4, title: 'Stockage', value: (stats?.documents_size + " GB"), icon: icons.maximizeIcon, color: 'blue' }
];
return (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="stats-container r-flex-between r-gap-24 flex-wrap overflow-hidden ">
{statsData.map(({ id, title, value, icon }) => (
<div key={id} className="w-full">
<div className="flex items-center rounded-xl border-2 border-blue-500 p-4 space-x-3">
<div key={id} className="stats flex items-center rounded-xl r-gap-12">
{/* <div className=""> */}
<div
className="flex items-center justify-center rounded-lg bg-[#E9F0FF] bg-opacity-25 p-2"
className="sqarre-bg d-flex items-center justify-center rounded-lg bg-[#E9F0FF] bg-opacity-25 p-2"
style={{ width: '54px', height: '54px' }}
>
<Image
@ -59,10 +59,10 @@ export default function Statistics() {
/>
</div>
<div className="ml-3">
<p className="text-sm text-gray-500 mb-0">{title}</p>
<p className="font-bold text-2xl mb-0">{ status === "loading" && isLoading ? "Chargement..." : value}</p>
</div>
<p className="text-sm fw-semibold text-secondary mb-0">{title}</p>
<p className="fw-bold fs-5 mb-0">{status === "loading" && isLoading ? "Chargement..." : value}</p>
</div>
{/* </div> */}
</div>
))}
</div>

View File

@ -102,30 +102,25 @@ export default function Table<TData, TValue>({
<div className="w-full">
{render()}
<div className="rounded-lg border border-gray-200 w-auto">
<div className="rounded-top">
<div className="overflow-x-auto">
<table className="w-full overflow-x-auto rounded-lg">
<thead className="h-10">
<table className="w-100 overflow-x-auto rounded-1c ">
<thead className="table-head bg-bluegray">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id} className="rounded-lg">
{header
?
<th className="bg-[#E9F0FF] p-3 text-start first:rounded-tl-lg">
<th className=" r-p-m-0 text-start ">
</th>
:
<th className="bg-[#E9F0FF] p-3 text-start first:rounded-tl-lg">
<input
ref={headerCheckboxRef}
checked={!!table.getIsAllPageRowsSelected()}
onChange={(e) => table.toggleAllPageRowsSelected(e.target.checked)}
type="checkbox" name="" id=""
/>
<th className=" r-p-m-0 text-start ">
</th>
}
{headerGroup.headers.map((header) => {
return (
<th key={header.id} className="bg-[#E9F0FF] p-3 text-start last:rounded-tr-lg">
<th key={header.id} className="r-p-m-0 text-start">
{flexRender(
header.column.columnDef.header,
header.getContext()
@ -140,7 +135,7 @@ export default function Table<TData, TValue>({
{table.getRowModel().rows.length ? (
table.getRowModel().rows.map((row) => (
<tr key={row.id} className={clsx('hover:bg-gray-100 border-t border-gray-200', { 'bg-gray-300': row.getIsSelected() })}>
<td className="p-3 text-start">
<td className="r-p-m-0 text-start">
<input
checked={row.getIsSelected()}
onChange={(e) => row.toggleSelected(e.target.checked)}
@ -148,7 +143,7 @@ export default function Table<TData, TValue>({
/>
</td>
{row.getVisibleCells().map((cell) => (
<td key={cell.id} className="p-3 text-start">
<td key={cell.id} className="r-p-m-0 text-start">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
@ -175,7 +170,7 @@ export default function Table<TData, TValue>({
</div>
</div>
<div className="flex items-center justify-end space-x-2 py-4">
<div className="pagination r-flex-center justify-content-end r-gap-2 py-4">
<button
className="hover:bg-gray-300 cursor-pointer px-3 py-1 rounded w-9 h-9"
onClick={() => table.previousPage()}
@ -184,14 +179,14 @@ export default function Table<TData, TValue>({
<Image alt="" src={icons.arrowLeft} className="hover:text-blue-400" />
</button>
<div className="flex space-x-1">
<div className="r-flex r-gap-1">
{getPageNumbers().map((pageNumber) => (
<button
key={pageNumber}
className={clsx(
"px-3 py-1 rounded w-9 h-9",
pageNumber === currentPage
? "bg-[#E9F0FF] text-blue-400"
? "bg-bluegray text-blue-400"
: "hover:bg-gray-300 cursor-pointer"
)}
onClick={() => table.setPageIndex(pageNumber - 1)}
@ -202,7 +197,7 @@ export default function Table<TData, TValue>({
</div>
<button
className="w-9 h-9 hover:bg-gray-300 cursor-pointer hover:text-black px-3 py-1 rounded"
className="w-9 h-9 px-3 py-1 rounded"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>

View File

@ -0,0 +1,9 @@
"use client";
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
export default function Layout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}

View File

@ -30,7 +30,7 @@ export interface FormProps{
export interface StatsType {
id: number;
title: string;
value: number | undefined;
value: number | string | undefined;
icon: string;
color: string;
}

View File

@ -23,6 +23,6 @@
"@/*": ["./src/*"]
}
},
"include": ["svgr.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["svgr.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/assets/icons/final-index.js"],
"exclude": ["node_modules"]
}