Nouveau front
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 902 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
+602
-87
@@ -1,10 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="theme-color" content="#0D2B5E">
|
||||
<title>CYBERUSGATE - Access</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<style>
|
||||
:root {
|
||||
@@ -44,109 +49,574 @@
|
||||
--shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
||||
body { background: var(--gray-1); color: var(--text-main); min-height: 100vh; overflow-x: hidden; transition: 0.3s; }
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--gray-1);
|
||||
color: var(--text-main);
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* SCREENS */
|
||||
.screen { display: none; min-height: 100vh; flex-direction: column; }
|
||||
.screen.active { display: flex; animation: fadeIn 0.3s ease; }
|
||||
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
||||
.screen {
|
||||
display: none;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.screen.active {
|
||||
display: flex;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ======= LOGIN ======= */
|
||||
#screen-login { background: linear-gradient(145deg, #0D2B5E 0%, #1565C0 100%); align-items: center; justify-content: center; padding: 24px; }
|
||||
.login-card { background: var(--white); border-radius: 20px; padding: 32px 24px; width: 100%; max-width: 380px; box-shadow: var(--shadow); text-align: center; }
|
||||
.logo-box { width: 64px; height: 64px; background: var(--blue-pale); border-radius: 16px; display: flex; align-items: center; justify-content: center; margin: 0 auto 16px; }
|
||||
.logo-box svg { width: 32px; height: 32px; fill: var(--blue-main); }
|
||||
.login-card h1 { font-size: 22px; color: var(--text-main); margin-bottom: 8px; }
|
||||
.login-card p { font-size: 14px; color: var(--text-sub); margin-bottom: 32px; }
|
||||
#screen-login {
|
||||
background: linear-gradient(145deg, #0D2B5E 0%, #1565C0 100%);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.role-btn { width: 100%; padding: 16px; border-radius: 12px; border: 2px solid var(--gray-2); background: var(--white); margin-bottom: 16px; cursor: pointer; display: flex; align-items: center; gap: 16px; text-align: left; transition: 0.2s; }
|
||||
.role-btn:active { transform: scale(0.98); border-color: var(--blue-main); background: var(--blue-pale); }
|
||||
.role-icon { width: 48px; height: 48px; border-radius: 50%; background: var(--gray-1); display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: bold; color: var(--blue-main); }
|
||||
.role-text h3 { font-size: 16px; color: var(--text-main); margin-bottom: 4px; }
|
||||
.role-text p { font-size: 12px; color: var(--text-sub); }
|
||||
.login-card {
|
||||
background: var(--white);
|
||||
border-radius: 20px;
|
||||
padding: 32px 24px;
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
box-shadow: var(--shadow);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo-box {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background: var(--blue-pale);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto 16px;
|
||||
}
|
||||
|
||||
.logo-box svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
fill: var(--blue-main);
|
||||
}
|
||||
|
||||
.login-card h1 {
|
||||
font-size: 22px;
|
||||
color: var(--text-main);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.login-card p {
|
||||
font-size: 14px;
|
||||
color: var(--text-sub);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.role-btn {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
border: 2px solid var(--gray-2);
|
||||
background: var(--white);
|
||||
margin-bottom: 16px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
text-align: left;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.role-btn:active {
|
||||
transform: scale(0.98);
|
||||
border-color: var(--blue-main);
|
||||
background: var(--blue-pale);
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: var(--gray-1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: var(--blue-main);
|
||||
}
|
||||
|
||||
.role-text h3 {
|
||||
font-size: 16px;
|
||||
color: var(--text-main);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.role-text p {
|
||||
font-size: 12px;
|
||||
color: var(--text-sub);
|
||||
}
|
||||
|
||||
/* ======= APP HEADER & NAV ======= */
|
||||
.app-header { background: var(--blue-dark); padding: 48px 20px 20px; display: flex; align-items: center; justify-content: space-between; position: sticky; top: 0; z-index: 100; }
|
||||
.user-badge { display: flex; align-items: center; gap: 12px; }
|
||||
.avatar { width: 44px; height: 44px; border-radius: 50%; background: var(--blue-light); border: 2px solid rgba(255,255,255,0.2); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; }
|
||||
.header-info h2 { font-size: 16px; color: white; }
|
||||
.header-info p { font-size: 12px; color: rgba(255,255,255,0.7); }
|
||||
.logout-btn { background: rgba(255,255,255,0.1); border: none; color: white; padding: 8px 12px; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; }
|
||||
.app-header {
|
||||
background: var(--blue-dark);
|
||||
padding: 48px 20px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.nav-tabs { display: flex; background: var(--white); border-bottom: 1px solid var(--gray-2); position: sticky; top: 112px; z-index: 99; }
|
||||
.nav-tab { flex: 1; padding: 14px 4px; border: none; background: transparent; font-size: 11px; font-weight: 700; color: var(--gray-3); text-transform: uppercase; cursor: pointer; border-bottom: 3px solid transparent; transition: 0.2s; display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||||
.nav-tab svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||||
.nav-tab.active { color: var(--blue-main); border-bottom-color: var(--blue-main); }
|
||||
.user-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tab-content { padding: 20px; display: none; flex-direction: column; gap: 16px; padding-bottom: 100px;}
|
||||
.tab-content.active { display: flex; animation: fadeIn 0.3s; }
|
||||
.avatar {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background: var(--blue-light);
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-info h2 {
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-info p {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
background: var(--white);
|
||||
border-bottom: 1px solid var(--gray-2);
|
||||
position: sticky;
|
||||
top: 112px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.nav-tab {
|
||||
flex: 1;
|
||||
padding: 14px 4px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: var(--gray-3);
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-bottom: 3px solid transparent;
|
||||
transition: 0.2s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.nav-tab svg {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
stroke: currentColor;
|
||||
fill: none;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.nav-tab.active {
|
||||
color: var(--blue-main);
|
||||
border-bottom-color: var(--blue-main);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 20px;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: flex;
|
||||
animation: fadeIn 0.3s;
|
||||
}
|
||||
|
||||
/* ======= UI COMPONENTS ======= */
|
||||
.card { background: var(--white); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow); }
|
||||
.card-title { font-size: 16px; font-weight: 700; margin-bottom: 16px; display: flex; align-items: center; justify-content: space-between;}
|
||||
.btn { padding: 14px; border-radius: 8px; font-size: 15px; font-weight: 600; cursor: pointer; border: none; text-align: center; width: 100%; display: flex; justify-content: center; align-items: center; gap: 8px; transition: 0.2s; }
|
||||
.btn-primary { background: var(--blue-main); color: white; }
|
||||
.btn-primary:active { background: var(--blue-dark); transform: scale(0.98); }
|
||||
.btn-outline { background: transparent; border: 2px solid var(--blue-main); color: var(--blue-main); }
|
||||
.card {
|
||||
background: var(--white);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 14px;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--blue-main);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
background: var(--blue-dark);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
border: 2px solid var(--blue-main);
|
||||
color: var(--blue-main);
|
||||
}
|
||||
|
||||
/* BADGE COMPONENT (USER) */
|
||||
.virtual-badge { background: linear-gradient(135deg, var(--blue-dark), var(--blue-main)); border-radius: 16px; padding: 24px; color: white; text-align: center; position: relative; overflow: hidden; box-shadow: 0 10px 24px rgba(21,101,192,0.3); margin-bottom: 16px;}
|
||||
.virtual-badge .company { font-size: 12px; opacity: 0.8; letter-spacing: 1px; margin-bottom: 16px; text-transform: uppercase;}
|
||||
.virtual-badge .nfc-icon { width: 80px; height: 80px; margin: 0 auto 16px; border: 3px solid rgba(255,255,255,0.3); border-radius: 50%; display: flex; align-items: center; justify-content: center; animation: pulse 2s infinite; cursor: pointer;}
|
||||
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(255,255,255,0.4); } 70% { box-shadow: 0 0 0 20px rgba(255,255,255,0); } 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0); } }
|
||||
.virtual-badge h3 { font-size: 20px; margin-bottom: 4px; }
|
||||
.virtual-badge p { font-size: 14px; opacity: 0.9; }
|
||||
.virtual-badge {
|
||||
background: linear-gradient(135deg, var(--blue-dark), var(--blue-main));
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 24px rgba(21, 101, 192, 0.3);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.virtual-badge .company {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.virtual-badge .nfc-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto 16px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: pulse 2s infinite;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.virtual-badge h3 {
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.virtual-badge p {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ADMIN UI */
|
||||
.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
|
||||
.stat-box { background: var(--white); padding: 16px; border-radius: 12px; box-shadow: var(--shadow); border-left: 4px solid var(--blue-main); }
|
||||
.stat-box .num { font-size: 24px; font-weight: bold; color: var(--text-main); }
|
||||
.stat-box .lbl { font-size: 12px; color: var(--text-sub); margin-top: 4px; text-transform: uppercase;}
|
||||
.stat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.user-list-item { display: flex; align-items: center; justify-content: space-between; padding: 16px; border-bottom: 1px solid var(--gray-2); cursor: pointer; }
|
||||
.user-list-item:last-child { border-bottom: none; }
|
||||
.user-list-item .info h4 { font-size: 15px; margin-bottom: 4px; }
|
||||
.user-list-item .info p { font-size: 12px; color: var(--text-sub); }
|
||||
.stat-box {
|
||||
background: var(--white);
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
border-left: 4px solid var(--blue-main);
|
||||
}
|
||||
|
||||
.stat-box .num {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: var(--text-main);
|
||||
}
|
||||
|
||||
.stat-box .lbl {
|
||||
font-size: 12px;
|
||||
color: var(--text-sub);
|
||||
margin-top: 4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.user-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--gray-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-list-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.user-list-item .info h4 {
|
||||
font-size: 15px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.user-list-item .info p {
|
||||
font-size: 12px;
|
||||
color: var(--text-sub);
|
||||
}
|
||||
|
||||
/* BADGE MANAGEMENT CARD */
|
||||
.badge-mgmt-card { border: 1px solid var(--gray-2); border-radius: 12px; padding: 16px; margin-bottom: 12px; background: var(--gray-1); }
|
||||
.badge-mgmt-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
|
||||
.badge-mgmt-header h4 { font-size: 14px; }
|
||||
.badge-mgmt-card {
|
||||
border: 1px solid var(--gray-2);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
background: var(--gray-1);
|
||||
}
|
||||
|
||||
.badge-mgmt-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.badge-mgmt-header h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* TOGGLE */
|
||||
.toggle { width: 44px; height: 24px; background: var(--gray-3); border-radius: 12px; position: relative; cursor: pointer; transition: 0.3s; }
|
||||
.toggle.on { background: var(--green); }
|
||||
.toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: white; transition: 0.3s; }
|
||||
.toggle.on::after { left: 22px; }
|
||||
.toggle {
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
background: var(--gray-3);
|
||||
border-radius: 12px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.toggle.on {
|
||||
background: var(--green);
|
||||
}
|
||||
|
||||
.toggle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background: white;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.toggle.on::after {
|
||||
left: 22px;
|
||||
}
|
||||
|
||||
/* SELECT */
|
||||
select.select-slot { width: 100%; padding: 10px; border-radius: 8px; border: 1px solid var(--gray-3); background: var(--white); color: var(--text-main); font-size: 13px; outline: none; }
|
||||
select.select-slot {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--gray-3);
|
||||
background: var(--white);
|
||||
color: var(--text-main);
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* MODALS */
|
||||
.modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 1000; align-items: center; justify-content: center; backdrop-filter: blur(3px); opacity: 0; transition: 0.3s; }
|
||||
.modal-overlay.open { display: flex; opacity: 1; }
|
||||
.modal-box { background: var(--white); border-radius: 20px; padding: 24px; width: 90%; max-width: 360px; transform: scale(0.9); transition: 0.3s; text-align: center;}
|
||||
.modal-overlay.open .modal-box { transform: scale(1); }
|
||||
.qr-placeholder { width: 200px; height: 200px; margin: 20px auto; background: white; border: 4px solid var(--blue-main); border-radius: 12px; display: flex; align-items: center; justify-content: center; position: relative;}
|
||||
.qr-placeholder img { width: 100%; height: 100%; object-fit: contain; }
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 1000;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
backdrop-filter: blur(3px);
|
||||
opacity: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.modal-overlay.open {
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal-box {
|
||||
background: var(--white);
|
||||
border-radius: 20px;
|
||||
padding: 24px;
|
||||
width: 90%;
|
||||
max-width: 360px;
|
||||
transform: scale(0.9);
|
||||
transition: 0.3s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-overlay.open .modal-box {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.qr-placeholder {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 20px auto;
|
||||
background: white;
|
||||
border: 4px solid var(--blue-main);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.qr-placeholder img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* TOAST */
|
||||
.toast { position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%) translateY(20px); background: #263238; color: white; padding: 14px 24px; border-radius: 30px; font-size: 14px; font-weight: bold; opacity: 0; transition: 0.3s; z-index: 9999; pointer-events: none; box-shadow: 0 4px 12px rgba(0,0,0,0.3); }
|
||||
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(20px);
|
||||
background: #263238;
|
||||
color: white;
|
||||
padding: 14px 24px;
|
||||
border-radius: 30px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
transition: 0.3s;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.toast.show {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
|
||||
/* Biometric animation */
|
||||
.bio-icon { color: var(--blue-main); margin-bottom: 16px; animation: pulseBio 2s infinite; }
|
||||
@keyframes pulseBio { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
|
||||
.bio-icon {
|
||||
color: var(--blue-main);
|
||||
margin-bottom: 16px;
|
||||
animation: pulseBio 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulseBio {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="dark-mode">
|
||||
|
||||
<!-- ===== LOGIN SCREEN ===== -->
|
||||
<div id="screen-login" class="screen active">
|
||||
<div class="login-card">
|
||||
<div class="logo-box">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1>CYBERUSGATE</h1>
|
||||
<p>Système de contrôle d'accès</p>
|
||||
@@ -185,11 +655,16 @@
|
||||
<!-- USER NAV -->
|
||||
<nav class="nav-tabs" id="nav-user" style="display:none;">
|
||||
<button class="nav-tab active" onclick="switchTab('user-badge', this)">
|
||||
<svg viewBox="0 0 24 24"><rect x="2" y="5" width="20" height="14" rx="3"/><path d="M8 12h.01M12 12h.01M16 12h.01"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect x="2" y="5" width="20" height="14" rx="3" />
|
||||
<path d="M8 12h.01M12 12h.01M16 12h.01" />
|
||||
</svg>
|
||||
Mon Badge
|
||||
</button>
|
||||
<button class="nav-tab" onclick="switchTab('user-add', this)">
|
||||
<svg viewBox="0 0 24 24"><path d="M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM21 14v7m-3-3h6"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM21 14v7m-3-3h6" />
|
||||
</svg>
|
||||
Scanner QR
|
||||
</button>
|
||||
</nav>
|
||||
@@ -197,15 +672,26 @@
|
||||
<!-- ADMIN NAV -->
|
||||
<nav class="nav-tabs" id="nav-admin" style="display:none;">
|
||||
<button class="nav-tab active" onclick="switchTab('admin-dash', this)">
|
||||
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect x="3" y="3" width="7" height="7" />
|
||||
<rect x="14" y="3" width="7" height="7" />
|
||||
<rect x="14" y="14" width="7" height="7" />
|
||||
<rect x="3" y="14" width="7" height="7" />
|
||||
</svg>
|
||||
Infrastructure
|
||||
</button>
|
||||
<button class="nav-tab" onclick="switchTab('admin-users', this)">
|
||||
<svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75" />
|
||||
</svg>
|
||||
Badges
|
||||
</button>
|
||||
<button class="nav-tab" onclick="switchTab('admin-qr', this)">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 4v16m8-8H4"/></svg>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
Générer QR
|
||||
</button>
|
||||
</nav>
|
||||
@@ -223,14 +709,21 @@
|
||||
<div id="tab-user-add" class="tab-content">
|
||||
<div class="card" style="text-align: center;">
|
||||
<h2 style="margin-bottom:10px;">Ajouter un badge</h2>
|
||||
<p style="font-size:14px; color:var(--text-sub); margin-bottom:24px;">Demandez à votre administrateur système de générer un QR code d'invitation pour provisionner votre téléphone.</p>
|
||||
<p style="font-size:14px; color:var(--text-sub); margin-bottom:24px;">Demandez à votre administrateur système de
|
||||
générer un QR code d'invitation pour provisionner votre téléphone.</p>
|
||||
|
||||
<div style="width:200px; height:200px; background:var(--gray-2); border-radius:16px; margin:0 auto 24px; display:flex; align-items:center; justify-content:center; border:2px dashed var(--gray-4);">
|
||||
<svg viewBox="0 0 24 24" style="width:48px; fill:none; stroke:var(--gray-4); stroke-width:2;"><path d="M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4z"/><path d="M14 14l6 6M20 14l-6 6"/></svg>
|
||||
<div
|
||||
style="width:200px; height:200px; background:var(--gray-2); border-radius:16px; margin:0 auto 24px; display:flex; align-items:center; justify-content:center; border:2px dashed var(--gray-4);">
|
||||
<svg viewBox="0 0 24 24" style="width:48px; fill:none; stroke:var(--gray-4); stroke-width:2;">
|
||||
<path d="M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4z" />
|
||||
<path d="M14 14l6 6M20 14l-6 6" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" onclick="simulateScanQR()">
|
||||
<svg viewBox="0 0 24 24" width="20" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 7V5a2 2 0 012-2h2M17 3h2a2 2 0 012 2v2M21 17v2a2 2 0 01-2 2h-2M7 21H5a2 2 0 01-2-2v-2"/></svg>
|
||||
<svg viewBox="0 0 24 24" width="20" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M3 7V5a2 2 0 012-2h2M17 3h2a2 2 0 012 2v2M21 17v2a2 2 0 01-2 2h-2M7 21H5a2 2 0 01-2-2v-2" />
|
||||
</svg>
|
||||
Simuler le Scan du QR
|
||||
</button>
|
||||
</div>
|
||||
@@ -243,25 +736,41 @@
|
||||
|
||||
<div id="tab-admin-dash" class="tab-content">
|
||||
<div class="stat-grid">
|
||||
<div class="stat-box"><div class="num" id="stat-machines">190</div><div class="lbl">Équipements</div></div>
|
||||
<div class="stat-box" style="border-color:var(--green);"><div class="num" id="stat-users">30</div><div class="lbl">Utilisateurs</div></div>
|
||||
<div class="stat-box" style="border-color:var(--orange);"><div class="num" id="stat-badges">--</div><div class="lbl">Badges Actifs</div></div>
|
||||
<div class="stat-box" style="border-color:var(--red);"><div class="num" id="stat-invites">--</div><div class="lbl">QR Actifs</div></div>
|
||||
<div class="stat-box">
|
||||
<div class="num" id="stat-machines">190</div>
|
||||
<div class="lbl">Équipements</div>
|
||||
</div>
|
||||
<div class="stat-box" style="border-color:var(--green);">
|
||||
<div class="num" id="stat-users">30</div>
|
||||
<div class="lbl">Utilisateurs</div>
|
||||
</div>
|
||||
<div class="stat-box" style="border-color:var(--orange);">
|
||||
<div class="num" id="stat-badges">--</div>
|
||||
<div class="lbl">Badges Actifs</div>
|
||||
</div>
|
||||
<div class="stat-box" style="border-color:var(--red);">
|
||||
<div class="num" id="stat-invites">--</div>
|
||||
<div class="lbl">QR Actifs</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">État du système</div>
|
||||
<div style="font-size:13px; color:var(--text-sub); display:flex; flex-direction:column; gap:12px;">
|
||||
<div style="display:flex; justify-content:space-between;"><span>Synchro Active Directory</span><span style="color:var(--green);font-weight:bold;">Opérationnelle</span></div>
|
||||
<div style="display:flex; justify-content:space-between;"><span>Chiffrement AES-256</span><span style="color:var(--green);font-weight:bold;">Actif</span></div>
|
||||
<div style="display:flex; justify-content:space-between;"><span>Contrôleurs de Domaine</span><span style="color:var(--green);font-weight:bold;">En ligne</span></div>
|
||||
<div style="display:flex; justify-content:space-between;"><span>Synchro Active Directory</span><span
|
||||
style="color:var(--green);font-weight:bold;">Opérationnelle</span></div>
|
||||
<div style="display:flex; justify-content:space-between;"><span>Chiffrement AES-256</span><span
|
||||
style="color:var(--green);font-weight:bold;">Actif</span></div>
|
||||
<div style="display:flex; justify-content:space-between;"><span>Contrôleurs de Domaine</span><span
|
||||
style="color:var(--green);font-weight:bold;">En ligne</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-admin-users" class="tab-content">
|
||||
<div class="card" style="padding:0; overflow:hidden;">
|
||||
<div style="padding:16px; background:var(--gray-2); font-weight:bold; font-size:14px;">Annuaire Utilisateurs</div>
|
||||
<div style="padding:16px; background:var(--gray-2); font-weight:bold; font-size:14px;">Annuaire Utilisateurs
|
||||
</div>
|
||||
<div id="admin-user-list">
|
||||
<!-- Generated via JS -->
|
||||
</div>
|
||||
@@ -271,7 +780,8 @@
|
||||
<div id="tab-admin-qr" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-title">Générateur d'accès sécurisé</div>
|
||||
<p style="font-size:13px; color:var(--text-sub); margin-bottom:20px;">Générez un QR Code temporaire. L'utilisateur devra le scanner avec son application pour provisionner son e-badge.</p>
|
||||
<p style="font-size:13px; color:var(--text-sub); margin-bottom:20px;">Générez un QR Code temporaire.
|
||||
L'utilisateur devra le scanner avec son application pour provisionner son e-badge.</p>
|
||||
|
||||
<button class="btn btn-primary" onclick="generateInviteQR()">Créer une invitation NFC</button>
|
||||
</div>
|
||||
@@ -298,7 +808,8 @@
|
||||
</svg>
|
||||
</div>
|
||||
<h2 style="margin-bottom:8px; font-size:18px;">Face ID / Touch ID</h2>
|
||||
<p style="font-size:13px; color:var(--text-sub); margin-bottom:24px;">Confirmez votre identité pour libérer l'accès NFC.</p>
|
||||
<p style="font-size:13px; color:var(--text-sub); margin-bottom:24px;">Confirmez votre identité pour libérer
|
||||
l'accès NFC.</p>
|
||||
|
||||
<button class="btn btn-primary" onclick="confirmBiometric()" style="margin-bottom:12px;">
|
||||
S'authentifier
|
||||
@@ -326,7 +837,10 @@
|
||||
<div class="modal-box">
|
||||
<h2>QR d'Invitation</h2>
|
||||
<div class="qr-placeholder">
|
||||
<svg width="150" height="150" viewBox="0 0 24 24" fill="var(--text-main)"><path d="M3 3h8v8H3zm2 2v4h4V5zm8-2h8v8h-8zm2 2v4h4V5zM3 13h8v8H3zm2 2v4h4v-4zm13-2h2v2h-2zm-2 2h2v2h-2zm2 2h2v2h-2zm-4 0h2v2h-2zm2 2h2v2h-2zm-4-4h2v2h-2zm2-2h2v2h-2z"/></svg>
|
||||
<svg width="150" height="150" viewBox="0 0 24 24" fill="var(--text-main)">
|
||||
<path
|
||||
d="M3 3h8v8H3zm2 2v4h4V5zm8-2h8v8h-8zm2 2v4h4V5zM3 13h8v8H3zm2 2v4h4v-4zm13-2h2v2h-2zm-2 2h2v2h-2zm2 2h2v2h-2zm-4 0h2v2h-2zm2 2h2v2h-2zm-4-4h2v2h-2zm2-2h2v2h-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p style="font-weight:bold; color:var(--green); margin-bottom:4px;" id="qr-expiry">Expire dans 14:59</p>
|
||||
<p style="font-size:12px; color:var(--text-sub); margin-bottom:20px;" id="qr-creator">Créé par: --</p>
|
||||
@@ -609,4 +1123,5 @@ function renderActiveInvites() {
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
Reference in New Issue
Block a user