feat(core): restructure auth, routing, and role-based dashboards
@@ -6,7 +6,7 @@
|
|||||||
#### A real-time map-based reporting system for campus infrastructure issues, built to improve visibility, accountability, and resolution efficiency.
|
#### A real-time map-based reporting system for campus infrastructure issues, built to improve visibility, accountability, and resolution efficiency.
|
||||||
|
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
|
|
||||||
> **🥰 Like this project? Please consider giving it a Star (🌟) on GitHub to show us your appreciation. Thank you!**
|
> **🥰 Like this project? Please consider giving it a Star (🌟) on GitHub to show us your appreciation. Thank you!**
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ SET FOREIGN_KEY_CHECKS = 0;
|
|||||||
DROP TABLE IF EXISTS
|
DROP TABLE IF EXISTS
|
||||||
`translations`,
|
`translations`,
|
||||||
`password_resets`,
|
`password_resets`,
|
||||||
`videos`,
|
|
||||||
`contributors`,
|
`contributors`,
|
||||||
`users`,
|
`users`,
|
||||||
`languages`;
|
`languages`;
|
||||||
|
|||||||
@@ -18,3 +18,15 @@ MAIL_FROM_NAME = "Your Mail From Name Here"
|
|||||||
MAIL_TO = "Your Mail To Address Here"
|
MAIL_TO = "Your Mail To Address Here"
|
||||||
MAX_VISIBLE_CONTRIBUTORS = "Your Maximum Visible Contributors Here. Use: 11(default)"
|
MAX_VISIBLE_CONTRIBUTORS = "Your Maximum Visible Contributors Here. Use: 11(default)"
|
||||||
PROJECT_START_YEAR = "Your Project Start Year Here. Use: 2025(default)"
|
PROJECT_START_YEAR = "Your Project Start Year Here. Use: 2025(default)"
|
||||||
|
|
||||||
|
|
||||||
|
HELPDESK_EMAIL= "Your Helpdesk Email Here"
|
||||||
|
HELPDESK_PHONE= "Your Helpdesk Phone Here"
|
||||||
|
MANAGEMENT_EMAIL= "Your Management Email Here"
|
||||||
|
MANAGEMENT_PHONE= "Your Management Phone Here"
|
||||||
|
HEALTH_EMAIL= "Your Health Email Here"
|
||||||
|
HEALTH_PHONE= "Your Health Phone Here"
|
||||||
|
LIBRARY_EMAIL= "Your Library Email Here"
|
||||||
|
LIBRARY_PHONE= "Your Library Phone Here"
|
||||||
|
SECURITY_EMAIL= "Your Security Email Here"
|
||||||
|
SECURITY_PHONE= "Your Security Phone Here"
|
||||||
@@ -1,83 +1,39 @@
|
|||||||
<nav class="fixed top-0 left-0 right-0 px-7 pb-1 bg-black z-10 flex justify-between items-center h-[3.8em]">
|
<?php
|
||||||
|
$current_email = $_SESSION['user_email'];
|
||||||
|
$user_initial = strtoupper($current_email[0]);
|
||||||
|
?>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<header class="w-full bg-neutral-900/95 border-b border-neutral-800 px-6 py-4 flex items-center justify-between backdrop-blur-sm sticky top-0 z-20">
|
||||||
<img src="./assets/images/icons/menu.svg" class="h-[1.1rem] -mr-1 w-auto cursor-pointer" id="menu-icon"
|
|
||||||
alt="menu-icon">
|
<div class="flex items-center gap-5">
|
||||||
<img src="./assets/images/logos/steamstube-logo.svg" class="h-8 ml-7 cursor-pointer" alt="steamstube-logo"
|
|
||||||
id="domain-logo">
|
<div class="flex items-center gap-3">
|
||||||
<span class="text-[1.3rem] font-youtube ml-0.5 text-gray-200 cursor-pointer" id="domain-name">
|
<div class="w-8 h-8 rounded-lg bg-blue-500/10 flex items-center justify-center border border-blue-500/20 shadow-[0_0_15px_rgba(59,130,246,0.1)]">
|
||||||
<?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?>
|
<svg class="w-5 h-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
</span>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||||
<?php if (!empty($_ENV['BETA']) && filter_var($_ENV['BETA'], FILTER_VALIDATE_BOOLEAN)): ?>
|
</svg>
|
||||||
<span
|
</div>
|
||||||
class="text-[0.6rem] font-youtube uppercase ml-[0.1rem] -mt-2 px-1 py-0.5 rounded text-pink-700 pointer-events-none">beta</span>
|
<h2 class="text-xl font-bold text-white tracking-tight"> <?php echo htmlspecialchars($_ENV['DOMAIN']); ?> Dashboard</h2>
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
</div>
|
||||||
class="flex flex-1 justify-center items-center px-8 mt-1 ml-auto mr-auto max-[1100px]:justify-start max-[750px]:hidden">
|
|
||||||
<div class="flex items-center w-full max-w-[41rem] border-2 border-neutral-900 rounded-full px-5 py-[0.5rem]">
|
<div class="flex items-center gap-4">
|
||||||
<img src="./assets/images/icons/search.svg" class="h-[1.2rem] mr-2" alt="search-icon">
|
|
||||||
<input type="text"
|
<div class="text-right">
|
||||||
placeholder="Search <?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?> or paste your code..."
|
<div class="text-sm font-semibold text-white">
|
||||||
class="flex-1 placeholder:text-gray-400 font-light text-gray-200 bg-transparent border-none outline-none text-sm tracking-wide truncate min-w-0">
|
<?php echo htmlspecialchars($current_email); ?>
|
||||||
<button class="ml-2 cursor-pointer">
|
</div>
|
||||||
<img src="./assets/images/icons/search-filter-icon.svg" class="h-5" alt="search-filter-icon">
|
<div class="text-xs text-neutral-500 font-medium uppercase tracking-wide">
|
||||||
</button>
|
<?php echo ($is_admin ?? false) ? 'Administrator' : 'User'; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center mt-0 relative">
|
|
||||||
<button class="hidden max-[750px]:inline-flex items-center justify-center cursor-pointer" id="mobileSearchBtn">
|
|
||||||
<img src="./assets/images/icons/mobile-search-icon.svg" class="h-5 w-auto pl-5" alt="mobile-search-icon">
|
|
||||||
</button>
|
|
||||||
<div id="mobileSearchOverlay"
|
|
||||||
class="hidden fixed top-0 left-0 right-0 bg-black px-5 py-3 items-center z-50 transition-transform duration-300 transform -translate-y-full">
|
|
||||||
<div class="flex items-center w-full border-2 border-neutral-900 rounded-full px-4 py-2 bg-black">
|
|
||||||
<input type="text" id="mobileSearchInput"
|
|
||||||
placeholder="Search <?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?> or paste your code..."
|
|
||||||
class="flex-1 text-[1rem] text-gray-200 bg-transparent border-none outline-none tracking-wide placeholder:text-gray-400 placeholder:font-light text-sm placeholder:tracking-normal truncate">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="hidden max-[750px]:inline-flex items-center justify-center -ml-2 relative left-7 cursor-pointer"
|
|
||||||
id="moreOptionsBtn">
|
|
||||||
<img src="./assets/images/icons/more-options-icon.svg" class="h-5 w-auto" alt="more-options-icon">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="hidden absolute top-[1.4rem] left-[-4.2rem] bg-black text-gray-200 rounded-xl shadow-2xl shadow-black/40 w-36 py-2 z-50 opacity-0 transform scale-95 transition-all duration-200 ease-out"
|
|
||||||
id="moreOptionsMenu">
|
|
||||||
<button
|
<button
|
||||||
class="flex items-center w-full px-4 py-2 text-base font-light text-gray-200 no-underline cursor-pointer hover:bg-[#332631] hover:rounded-lg max-[56.25rem]:text-sm"><img
|
onclick="window.location.href='./pages/account.php'"
|
||||||
src="./assets/images/icons/upload.svg" class="h-5 mr-2" alt="upload-icon">
|
class="w-10 h-10 rounded-full bg-neutral-800 border border-neutral-700 hover:border-blue-500/50 hover:shadow-[0_0_15px_rgba(59,130,246,0.3)] transition-all duration-300 flex items-center justify-center text-neutral-300 hover:text-white font-bold text-sm"
|
||||||
<span>Uploads</span>
|
>
|
||||||
</button>
|
<?php echo $user_initial; ?>
|
||||||
<button
|
|
||||||
class="flex items-center w-full px-4 py-2 text-base font-light text-gray-200 no-underline cursor-pointer hover:bg-[#332631] hover:rounded-lg max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/reminders.svg" class="h-5 mr-2" alt="reminders-icon">
|
|
||||||
<span>Reminders</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="flex items-center w-full px-4 py-2 text-base font-light text-gray-200 no-underline cursor-pointer hover:bg-[#332631] hover:rounded-lg max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/settings.svg" class="h-5 mr-2" alt="settings-icon">
|
|
||||||
<span>Settings</span>
|
|
||||||
</button>
|
|
||||||
<button onclick="window.location.href='./core/auth/auth_check.php'"
|
|
||||||
class="flex items-center w-full px-4 py-2 text-base font-light text-gray-200 no-underline cursor-pointer hover:bg-[#332631] hover:rounded-lg max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/default-user.png" class="h-5 mr-2" alt="default-user-icon">
|
|
||||||
<span>Account</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</header>
|
||||||
<div class="flex items-center max-[750px]:hidden">
|
|
||||||
<button class="ml-2 cursor-pointer"><img src="./assets/images/icons/upload.svg" class="h-5 w-auto"
|
|
||||||
alt="upload-icon"></button>
|
|
||||||
<button class="ml-8 cursor-pointer"><img src="./assets/images/icons/reminders.svg" class="h-5 w-auto"
|
|
||||||
alt="reminders-icon"></button>
|
|
||||||
<button class="ml-8 cursor-pointer"><img src="./assets/images/icons/settings.svg" class="h-5 w-auto"
|
|
||||||
alt="settings-icon"></button>
|
|
||||||
<button onclick="window.location.href='./core/auth/auth_check.php'" class="ml-8 cursor-pointer"><img
|
|
||||||
src="./assets/images/icons/default-user.png" class="h-5 w-auto" alt="default-user-icon"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
@@ -1,302 +1,71 @@
|
|||||||
<div
|
<?php
|
||||||
class="sidebar group fixed top-[3.6rem] left-0 z-[9999] h-[calc(100vh-3.6rem)] w-[14.375rem] overflow-y-auto overflow-x-hidden bg-black pb-[25%] pr-[0.9375rem] pl-[0.9375rem] pt-[0.3125rem] group-[.small-sidebar]:w-[4.375rem] group-[.small-sidebar]:overflow-y-hidden max-[31.25rem]:group-[.small-sidebar]:hidden">
|
$activeClass = 'bg-blue-500/10 text-blue-400 shadow-[0_0_15px_rgba(59,130,246,0.1)] border border-blue-500/20';
|
||||||
|
$inactiveClass = 'text-neutral-400 hover:text-white hover:bg-neutral-800/60 border border-transparent transition-all duration-200';
|
||||||
|
?>
|
||||||
|
|
||||||
<div class="shortcut-links">
|
<aside class="w-64 bg-neutral-900/95 border-r border-neutral-800 flex flex-col h-screen">
|
||||||
<button id="home-btn"
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.526rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/home-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/home-fill-icon.svg">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Home</p>
|
|
||||||
</button>
|
|
||||||
<button id="trending-btn"
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/trending-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/trending-fill-icon.svg">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Trending</p>
|
|
||||||
</button>
|
|
||||||
<hr
|
|
||||||
class="sidebar-hr my-[0.3125rem] ml-[1%] h-[0.0625rem] w-[99%] border-0 bg-neutral-700 transition-width duration-300 ease-in-out group-[.small-sidebar]:w-full max-[56.25rem]:w-[99%]">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="shortcut-links">
|
<nav class="flex-1 px-4 py-6 space-y-2 overflow-y-auto" id="sidebar-nav">
|
||||||
<button id="watched-btn"
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/watched-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/watched-fill-icon.svg">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Watched</p>
|
|
||||||
</button>
|
|
||||||
<button id="favourites-btn"
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/favourites-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/favourites-fill-icon.svg">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Favourites</p>
|
|
||||||
</button>
|
|
||||||
<button id="followings-btn"
|
|
||||||
class="icon-btn categories-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/followings-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/followings-fill-icon.svg">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Followings</p>
|
|
||||||
<div
|
|
||||||
class="right-side absolute right-0 mr-[0.375rem] flex items-center bg-transparent ml-auto group-[.small-sidebar]:hidden">
|
|
||||||
<div class="divider mx-[0.625rem] h-[1.3rem] w-[0.0625rem] bg-neutral-700"></div>
|
|
||||||
<img src="./assets/images/icons/arrow-down.svg" class="arrow-icon h-[1.3rem] w-auto">
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown hidden flex-col">
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 active:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/users/apple.jpg"
|
|
||||||
class="icon block h-[1.5rem] w-[1.5rem] rounded-full object-cover max-[56.25rem]:h-[1.3rem] max-[56.25rem]:w-[1.3rem]">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
@apple</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 active:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/users/cumatozz.jpg"
|
|
||||||
class="icon block h-[1.5rem] w-[1.5rem] rounded-full object-cover max-[56.25rem]:h-[1.3rem] max-[56.25rem]:w-[1.3rem]">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
@cumatozz</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 active:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/users/johnny-sins.jpg"
|
|
||||||
class="icon block h-[1.5rem] w-[1.5rem] rounded-full object-cover max-[56.25rem]:h-[1.3rem] max-[56.25rem]:w-[1.3rem]">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
@johnny_sins</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 active:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/users/sweetie-fox.jpg"
|
|
||||||
class="icon block h-[1.5rem] w-[1.5rem] rounded-full object-cover max-[56.25rem]:h-[1.3rem] max-[56.25rem]:w-[1.3rem]">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
@sweetie_fox</p>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<hr
|
|
||||||
class="sidebar-hr my-[0.3125rem] ml-[1%] h-[0.0625rem] w-[99%] border-0 bg-neutral-700 transition-width duration-300 ease-in-out group-[.small-sidebar]:w-full max-[56.25rem]:w-[99%]">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="shortcut-links">
|
<?php if (!$is_admin): ?>
|
||||||
<button id="categories-btn"
|
|
||||||
class="icon-btn categories-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/categories-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/categories-fill-icon.svg" alt="Categories icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Categories</p>
|
|
||||||
<div
|
|
||||||
class="right-side absolute right-0 mr-[0.375rem] flex items-center bg-transparent ml-auto group-[.small-sidebar]:hidden">
|
|
||||||
<div class="divider mx-[0.625rem] h-[1.3rem] w-[0.0625rem] bg-neutral-700"></div>
|
|
||||||
<img src="./assets/images/icons/arrow-down.svg" class="arrow-icon h-[1.3rem] w-auto">
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown hidden flex-col">
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/straight-gender-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/straight-gender-fill-icon.svg" alt="Male icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Straight</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/gay-gender-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/gay-gender-fill-icon.svg" alt="Male icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Gay</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/trans-gender-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/trans-gender-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Trans</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/lesbian-gender-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/lesbian-gender-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Lesbian</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/bisexual-gender-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/bisexual-gender-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Bisexual</p>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<button id="fan-picks-btn"
|
|
||||||
class="icon-btn categories-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-icon.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-fill-icon.svg" alt="Fan Pick's icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Fan Picks’</p>
|
|
||||||
<div
|
|
||||||
class="right-side absolute right-0 mr-[0.375rem] flex items-center bg-transparent ml-auto group-[.small-sidebar]:hidden">
|
|
||||||
<div class="divider mx-[0.625rem] h-[1.3rem] w-[0.0625rem] bg-neutral-700"></div>
|
|
||||||
<img src="./assets/images/icons/arrow-down.svg" class="arrow-icon h-[1.3rem] w-auto">
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown fan-picks-dropdown hidden flex-col group-[.small-sidebar]:!hidden">
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Male icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Teen (18+)</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
MILF</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Male icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Anal</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Hardcore BDSM</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Threesome</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Hentai</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
JAV</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Russian</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Korean</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Chinese</p>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
|
||||||
<img src="./assets/images/icons/fan-pick's-sub-con.svg"
|
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
|
||||||
data-hover="./assets/images/icons/fan-pick's-sub-fill-icon.svg" alt="Female icon">
|
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Indian</p>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<hr
|
|
||||||
class="sidebar-hr my-[0.3125rem] ml-[1%] h-[0.0625rem] w-[99%] border-0 bg-neutral-700 transition-width duration-300 ease-in-out group-[.small-sidebar]:w-full max-[56.25rem]:w-[99%]">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="shortcut-links">
|
<a href="?page=overview"
|
||||||
<p
|
class="group flex items-center px-4 py-3 text-sm font-medium rounded-xl <?php echo $page === 'overview' ? $activeClass : $inactiveClass; ?>">
|
||||||
class="sidebar-title my-1 ml-[0.625rem] whitespace-nowrap text-gray-200 text-base max-[56.25rem]:text-sm group-[.small-sidebar]:hidden">
|
<svg class="w-5 h-5 mr-3 <?php echo $page === 'overview' ? 'text-blue-400' : 'text-neutral-500 group-hover:text-white'; ?> transition-colors"
|
||||||
More from <?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></p>
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<button id="the-originals-btn"
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
|
||||||
<img src="./assets/images/icons/the-st-originals-icon.svg"
|
</svg>
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
Overview
|
||||||
data-hover="./assets/images/icons/the-st-originals-fill-icon.svg">
|
</a>
|
||||||
<p
|
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
<a href="?page=reports"
|
||||||
The ST Originals</p>
|
class="group flex items-center px-4 py-3 text-sm font-medium rounded-xl <?php echo $page === 'reports' ? $activeClass : $inactiveClass; ?>">
|
||||||
</button>
|
<svg class="w-5 h-5 mr-3 <?php echo $page === 'reports' ? 'text-blue-400' : 'text-neutral-500 group-hover:text-white'; ?> transition-colors"
|
||||||
<button id="trust-support-btn"
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
class="icon-btn relative flex w-full cursor-pointer items-center justify-start gap-[0.9375rem] border-none bg-transparent py-[0.525rem] pr-[0.25rem] pl-[0.75rem] text-base font-light text-gray-200 no-underline hover:rounded-[0.625rem] hover:bg-neutral-900 [&.active]:rounded-[0.625rem] [&.active]:bg-neutral-900 group-[.small-sidebar]:w-full group-[.small-sidebar]:justify-center group-[.small-sidebar]:p-[0.75rem] max-[56.25rem]: max-[56.25rem]:text-sm">
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
<img src="./assets/images/icons/trust-icon.svg"
|
d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||||
class="icon block h-[1.3rem] w-auto bg-transparent max-[56.25rem]:h-[1.125rem]"
|
</svg>
|
||||||
data-hover="./assets/images/icons/trust-fill-icon.svg">
|
Reports
|
||||||
<p
|
</a>
|
||||||
class="label m-0 block min-w-0 max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-transparent group-[.small-sidebar]:hidden">
|
|
||||||
Trust & Support</p>
|
<?php endif; ?>
|
||||||
</button>
|
|
||||||
</div>
|
<?php if ($is_admin): ?>
|
||||||
</div>
|
|
||||||
|
<a href="?page=status-board"
|
||||||
|
class="group flex items-center px-4 py-3 text-sm font-medium rounded-xl <?php echo $page === 'status-board' ? $activeClass : $inactiveClass; ?>">
|
||||||
|
<svg class="w-5 h-5 mr-3 <?php echo $page === 'status-board' ? 'text-blue-400' : 'text-neutral-500 group-hover:text-white'; ?> transition-colors"
|
||||||
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||||
|
</svg>
|
||||||
|
Status Board
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="?page=activity-logs"
|
||||||
|
class="group flex items-center px-4 py-3 text-sm font-medium rounded-xl <?php echo $page === 'activity-logs' ? $activeClass : $inactiveClass; ?>">
|
||||||
|
<svg class="w-5 h-5 mr-3 <?php echo $page === 'activity-logs' ? 'text-blue-400' : 'text-neutral-500 group-hover:text-white'; ?> transition-colors"
|
||||||
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
Activity Logs
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="?page=admin"
|
||||||
|
class="group flex items-center px-4 py-3 text-sm font-medium rounded-xl <?php echo $page === 'admin' ? $activeClass : $inactiveClass; ?>">
|
||||||
|
<svg class="w-5 h-5 mr-3 <?php echo $page === 'admin' ? 'text-blue-400' : 'text-neutral-500 group-hover:text-white'; ?> transition-colors"
|
||||||
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
System Admin
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
244
src/assets/admin/_activity_logs.php
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
<section class="space-y-6">
|
||||||
|
<header>
|
||||||
|
<h1 class="text-2xl font-semibold text-white">Activity Logs</h1>
|
||||||
|
<p class="mt-1 text-sm text-neutral-400">Recent system and user activities</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-neutral-400 mb-1.5">Event Type</label>
|
||||||
|
<select class="w-full bg-neutral-900 border border-neutral-700 text-white text-sm rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
|
<option>All</option>
|
||||||
|
<option>Reports</option>
|
||||||
|
<option>Status Changes</option>
|
||||||
|
<option>Admin Actions</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-neutral-400 mb-1.5">Severity</label>
|
||||||
|
<select class="w-full bg-neutral-900 border border-neutral-700 text-white text-sm rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
|
<option>All</option>
|
||||||
|
<option>Info</option>
|
||||||
|
<option>Warning</option>
|
||||||
|
<option>Critical</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-neutral-400 mb-1.5">Date Range</label>
|
||||||
|
<select class="w-full bg-neutral-900 border border-neutral-700 text-white text-sm rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
|
<option>Today</option>
|
||||||
|
<option>Last 7 days</option>
|
||||||
|
<option>Last 30 days</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs font-medium text-neutral-400 mb-1.5">Search</label>
|
||||||
|
<input type="text" placeholder="Search activity…" class="w-full bg-neutral-900 border border-neutral-700 text-white placeholder-neutral-500 text-sm rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Timestamp</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Actor</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Action</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Related Entity</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Severity</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 14:32:15</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">admin@system</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Updated service configuration</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">API Gateway - US-East</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Info</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 14:28:43</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">System</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Service health check failed</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">Database - EU-West</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Warning</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 14:15:22</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">john.doe@company.com</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Generated monthly report</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">Report #1247</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Info</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 13:58:09</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">System</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Critical alert triggered</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">Load Balancer - APAC</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-900 text-red-200">Critical</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 13:45:31</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">admin@system</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Modified user permissions</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">User: jane.smith@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Info</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 13:22:17</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">System</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Backup completed successfully</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">All Services</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Info</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 12:58:44</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">mark.wilson@company.com</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Updated service status</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">CDN - US-West</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Info</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">2025-12-27 12:31:05</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">System</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">High memory usage detected</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">Cache Server - EU-Central</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Warning</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden bg-neutral-800 rounded-lg border border-neutral-700 p-12">
|
||||||
|
<div class="flex flex-col items-center justify-center text-center">
|
||||||
|
<svg class="w-16 h-16 text-neutral-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||||
|
</svg>
|
||||||
|
<h3 class="text-lg font-medium text-white mb-1">No activity logs available</h3>
|
||||||
|
<p class="text-sm text-neutral-400">System and user actions will appear here</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden bg-neutral-800 rounded-lg border border-neutral-700 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Timestamp</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Actor</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Action</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Related Entity</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">Severity</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-28"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-48"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-36"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-24"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-56"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-40"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-36"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-44"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-20"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-52"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-44"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-28"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-48"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-40"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
438
src/assets/admin/_admin.php
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
<section class="space-y-6">
|
||||||
|
<header>
|
||||||
|
<h1 class="text-2xl font-semibold text-white">Admin Panel</h1>
|
||||||
|
<p class="mt-1 text-sm text-neutral-400">System management and administrative controls</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium text-neutral-400">Total Users</p>
|
||||||
|
<p class="mt-2 text-3xl font-semibold text-white">1,247</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-12 h-12 bg-blue-900 rounded-lg flex items-center justify-center">
|
||||||
|
<svg class="w-6 h-6 text-blue-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-4 text-xs text-neutral-500">Active: 1,189 | Suspended: 58</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium text-neutral-400">Pending Reports</p>
|
||||||
|
<p class="mt-2 text-3xl font-semibold text-white">34</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-12 h-12 bg-yellow-900 rounded-lg flex items-center justify-center">
|
||||||
|
<svg class="w-6 h-6 text-yellow-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-4 text-xs text-neutral-500">High: 8 | Medium: 15 | Low: 11</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium text-neutral-400">Active Incidents</p>
|
||||||
|
<p class="mt-2 text-3xl font-semibold text-white">7</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-12 h-12 bg-red-900 rounded-lg flex items-center justify-center">
|
||||||
|
<svg class="w-6 h-6 text-red-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-4 text-xs text-neutral-500">Critical: 2 | Warning: 5</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium text-neutral-400">System Health</p>
|
||||||
|
<p class="mt-2 text-3xl font-semibold text-green-400">98.5%</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-12 h-12 bg-green-900 rounded-lg flex items-center justify-center">
|
||||||
|
<svg class="w-6 h-6 text-green-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-4 text-xs text-neutral-500">All services operational</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700">
|
||||||
|
<div class="px-6 py-4 border-b border-neutral-700">
|
||||||
|
<h2 class="text-lg font-semibold text-white">User Management</h2>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
User ID</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Name</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Email</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Role</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Status</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#1001</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">John Anderson</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">john.anderson@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-900 text-purple-200">Admin</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-900 text-green-200">Active</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 mr-3">View</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Disable</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#1002</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">Sarah Mitchell</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">sarah.mitchell@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Moderator</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-900 text-green-200">Active</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 mr-3">View</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Disable</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#1003</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">Michael Chen</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">michael.chen@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-neutral-700 text-neutral-300">User</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-900 text-green-200">Active</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 mr-3">View</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Disable</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#1004</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">Emily Rodriguez</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">emily.rodriguez@company.com
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-neutral-700 text-neutral-300">User</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-900 text-red-200">Suspended</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 mr-3">View</button>
|
||||||
|
<button class="text-green-400 hover:text-green-300">Enable</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#1005</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-white">David Thompson</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">david.thompson@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Moderator</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-900 text-green-200">Active</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 mr-3">View</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Disable</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700">
|
||||||
|
<div class="px-6 py-4 border-b border-neutral-700">
|
||||||
|
<h2 class="text-lg font-semibold text-white">Report Moderation</h2>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Report ID</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Title</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Submitted By</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Priority</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Status</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#2045</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-white">Database Connection Issues</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">alex.kim@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-900 text-red-200">High</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Pending</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-green-400 hover:text-green-300 mr-2">Approve</button>
|
||||||
|
<button class="text-orange-400 hover:text-orange-300 mr-2">Escalate</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#2044</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-white">API Response Time Degradation</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">maria.santos@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Medium</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Pending</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-green-400 hover:text-green-300 mr-2">Approve</button>
|
||||||
|
<button class="text-orange-400 hover:text-orange-300 mr-2">Escalate</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#2043</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-white">UI Rendering Bug</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">james.wilson@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-900 text-blue-200">Low</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Pending</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-green-400 hover:text-green-300 mr-2">Approve</button>
|
||||||
|
<button class="text-orange-400 hover:text-orange-300 mr-2">Escalate</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="hover:bg-neutral-750">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-300">#2042</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-white">Memory Leak in Production</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-neutral-400">lisa.park@company.com</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-900 text-red-200">High</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-900 text-yellow-200">Pending</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
<button class="text-green-400 hover:text-green-300 mr-2">Approve</button>
|
||||||
|
<button class="text-orange-400 hover:text-orange-300 mr-2">Escalate</button>
|
||||||
|
<button class="text-red-400 hover:text-red-300">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700">
|
||||||
|
<div class="px-6 py-4 border-b border-neutral-700">
|
||||||
|
<h2 class="text-lg font-semibold text-white">System Controls</h2>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 space-y-4">
|
||||||
|
<div class="flex items-center justify-between p-4 bg-neutral-900 rounded-lg border border-neutral-700">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-sm font-medium text-white">Maintenance Mode</h3>
|
||||||
|
<p class="mt-1 text-xs text-neutral-400">Enable maintenance mode to perform system updates</p>
|
||||||
|
</div>
|
||||||
|
<label class="relative inline-flex items-center cursor-pointer">
|
||||||
|
<input type="checkbox" class="sr-only peer">
|
||||||
|
<div
|
||||||
|
class="w-11 h-6 bg-neutral-700 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-neutral-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600">
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<button
|
||||||
|
class="flex items-center justify-center px-4 py-3 bg-neutral-900 border border-neutral-700 rounded-lg text-sm font-medium text-white hover:bg-neutral-750 transition-colors">
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
Clear Cache
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="flex items-center justify-center px-4 py-3 bg-neutral-900 border border-neutral-700 rounded-lg text-sm font-medium text-white hover:bg-neutral-750 transition-colors">
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
Force Status Refresh
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="flex items-center justify-center px-4 py-3 bg-yellow-900 border border-yellow-700 rounded-lg text-sm font-medium text-yellow-200 hover:bg-yellow-800 transition-colors">
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
Restart Services
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden bg-neutral-800 rounded-lg border border-neutral-700 p-12">
|
||||||
|
<div class="flex flex-col items-center justify-center text-center">
|
||||||
|
<svg class="w-16 h-16 text-neutral-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
<h3 class="text-lg font-medium text-white mb-1">No data available</h3>
|
||||||
|
<p class="text-sm text-neutral-400">Administrative data will appear here when available</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden bg-neutral-800 rounded-lg border border-neutral-700 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
User ID</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Name</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Email</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Role</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Status</th>
|
||||||
|
<th class="px-6 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">
|
||||||
|
Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-32"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-48"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-24"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-28"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-44"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-24"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="animate-pulse">
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-36"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-52"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded-full w-16"></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-24"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
296
src/assets/admin/_status_board.php
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
<div class="space-y-6">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 pb-4 border-b border-neutral-800">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-2xl font-bold text-white">Status Board</h1>
|
||||||
|
<p class="text-sm text-neutral-400 mt-1">Live infrastructure and service health</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-4 text-xs">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
<span class="text-neutral-300">Operational</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-yellow-500"></div>
|
||||||
|
<span class="text-neutral-300">Degraded</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-red-500"></div>
|
||||||
|
<span class="text-neutral-300">Outage</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Global Status Summary -->
|
||||||
|
<section>
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<span class="text-sm text-neutral-400">Overall System</span>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
</div>
|
||||||
|
<div class="text-2xl font-bold text-white">Operational</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<span class="text-sm text-neutral-400">Services Operational</span>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
</div>
|
||||||
|
<div class="text-2xl font-bold text-white">12/14</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<span class="text-sm text-neutral-400">Active Incidents</span>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-yellow-500"></div>
|
||||||
|
</div>
|
||||||
|
<div class="text-2xl font-bold text-white">2</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<span class="text-sm text-neutral-400">Regions Affected</span>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
</div>
|
||||||
|
<div class="text-2xl font-bold text-white">0/8</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Services Status Grid -->
|
||||||
|
<section>
|
||||||
|
<h2 class="text-lg font-semibold text-white mb-4">Services Status</h2>
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Power Grid</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">Operational</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">Running normally</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 2 minutes ago</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Water Supply</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">Operational</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">Running normally</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 5 minutes ago</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Network Infrastructure</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-yellow-500/10 text-yellow-400 border border-yellow-500/20">Degraded</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">Partial outage in Zone C</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 1 minute ago</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Road Network</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">Operational</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">All routes clear</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 3 minutes ago</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-red-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Public Transit</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-red-500/10 text-red-400 border border-red-500/20">Outage</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">Service suspended on Line 5</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 8 minutes ago</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="flex items-start justify-between mb-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
|
<h3 class="font-semibold text-white">Emergency Services</h3>
|
||||||
|
</div>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">Operational</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-400 mb-2">All systems nominal</p>
|
||||||
|
<p class="text-xs text-neutral-500">Last updated: 1 minute ago</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Location / Region Status -->
|
||||||
|
<section>
|
||||||
|
<h2 class="text-lg font-semibold text-white mb-4">Regional Status</h2>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="text-left px-4 py-3 text-xs font-semibold text-neutral-300 uppercase tracking-wider">Region / Area</th>
|
||||||
|
<th class="text-left px-4 py-3 text-xs font-semibold text-neutral-300 uppercase tracking-wider">Affected Services</th>
|
||||||
|
<th class="text-left px-4 py-3 text-xs font-semibold text-neutral-300 uppercase tracking-wider">Status</th>
|
||||||
|
<th class="text-left px-4 py-3 text-xs font-semibold text-neutral-300 uppercase tracking-wider">Last Update</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3 text-sm text-white whitespace-nowrap">North District</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-400">None</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex items-center gap-2 px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
Operational
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-500 whitespace-nowrap">2 minutes ago</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3 text-sm text-white whitespace-nowrap">South District</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-400">None</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex items-center gap-2 px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
Operational
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-500 whitespace-nowrap">4 minutes ago</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3 text-sm text-white whitespace-nowrap">East District</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-400">Network, Transit</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex items-center gap-2 px-2 py-1 text-xs font-medium rounded bg-yellow-500/10 text-yellow-400 border border-yellow-500/20">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-yellow-500"></div>
|
||||||
|
Degraded
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-500 whitespace-nowrap">1 minute ago</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3 text-sm text-white whitespace-nowrap">West District</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-400">None</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex items-center gap-2 px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
Operational
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-500 whitespace-nowrap">3 minutes ago</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3 text-sm text-white whitespace-nowrap">Central District</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-400">None</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex items-center gap-2 px-2 py-1 text-xs font-medium rounded bg-green-500/10 text-green-400 border border-green-500/20">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
||||||
|
Operational
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-4 py-3 text-sm text-neutral-500 whitespace-nowrap">5 minutes ago</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Incident Snapshot -->
|
||||||
|
<section>
|
||||||
|
<h2 class="text-lg font-semibold text-white mb-4">Active Incidents</h2>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 divide-y divide-neutral-700">
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3 mb-2">
|
||||||
|
<h3 class="font-semibold text-white">Network connectivity issues in Zone C</h3>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-yellow-500/10 text-yellow-400 border border-yellow-500/20 self-start">High</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3 text-sm">
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-blue-500/10 text-blue-400 border border-blue-500/20">Investigating</span>
|
||||||
|
<span class="text-neutral-500">15 minutes ago</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3 mb-2">
|
||||||
|
<h3 class="font-semibold text-white">Transit Line 5 service disruption</h3>
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-red-500/10 text-red-400 border border-red-500/20 self-start">Critical</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3 text-sm">
|
||||||
|
<span class="px-2 py-1 text-xs font-medium rounded bg-orange-500/10 text-orange-400 border border-orange-500/20">Identified</span>
|
||||||
|
<span class="text-neutral-500">32 minutes ago</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Loading State (Hidden by default) -->
|
||||||
|
<div class="space-y-6 hidden" data-loading-state>
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-1/2 mb-3"></div>
|
||||||
|
<div class="h-8 bg-neutral-700 rounded w-3/4"></div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-1/2 mb-3"></div>
|
||||||
|
<div class="h-8 bg-neutral-700 rounded w-3/4"></div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-1/2 mb-3"></div>
|
||||||
|
<div class="h-8 bg-neutral-700 rounded w-3/4"></div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-1/2 mb-3"></div>
|
||||||
|
<div class="h-8 bg-neutral-700 rounded w-3/4"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded w-1/3 mb-3"></div>
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-full mb-2"></div>
|
||||||
|
<div class="h-3 bg-neutral-700 rounded w-1/4"></div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4 animate-pulse">
|
||||||
|
<div class="h-5 bg-neutral-700 rounded w-1/3 mb-3"></div>
|
||||||
|
<div class="h-4 bg-neutral-700 rounded w-full mb-2"></div>
|
||||||
|
<div class="h-3 bg-neutral-700 rounded w-1/4"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-4">
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div class="h-10 bg-neutral-700 rounded animate-pulse"></div>
|
||||||
|
<div class="h-10 bg-neutral-700 rounded animate-pulse"></div>
|
||||||
|
<div class="h-10 bg-neutral-700 rounded animate-pulse"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Empty State for Incidents -->
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 p-12 text-center hidden" data-empty-incidents>
|
||||||
|
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-500/10 mb-4">
|
||||||
|
<svg class="w-8 h-8 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<p class="text-lg font-semibold text-white mb-1">No active incidents</p>
|
||||||
|
<p class="text-sm text-neutral-400">All systems are operating normally</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 43 KiB |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "SteamsTube",
|
"name": "Infra-UNI",
|
||||||
"short_name": "SteamsTube",
|
"short_name": "Infra-UNI",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/web-app-manifest-192x192.png",
|
"src": "/web-app-manifest-192x192.png",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"theme_color": "#171717",
|
"theme_color": "#ffffff",
|
||||||
"background_color": "#171717",
|
"background_color": "#ffffff",
|
||||||
"display": "standalone"
|
"display": "standalone"
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 18 KiB |
BIN
src/assets/images/preview/infra-xodivorce-in-preview.png
Normal file
|
After Width: | Height: | Size: 612 KiB |
18
src/assets/js/account_config.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
function copyToClipboard(text, btnId) {
|
||||||
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
|
const btn = document.getElementById(btnId);
|
||||||
|
const icon = btn.querySelector('svg');
|
||||||
|
|
||||||
|
// Success State
|
||||||
|
btn.classList.add('bg-green-500/20', 'text-green-400', 'border-green-500/50');
|
||||||
|
btn.classList.remove('text-neutral-400');
|
||||||
|
icon.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>';
|
||||||
|
|
||||||
|
// Revert
|
||||||
|
setTimeout(() => {
|
||||||
|
btn.classList.remove('bg-green-500/20', 'text-green-400', 'border-green-500/50');
|
||||||
|
btn.classList.add('text-neutral-400');
|
||||||
|
icon.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>';
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
100
src/assets/js/dashboard_config.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
async function loadDashboardMetrics() {
|
||||||
|
// TODO: Replace with actual API call
|
||||||
|
// const response = await fetch('/api/dashboard/metrics');
|
||||||
|
// const data = await response.json();
|
||||||
|
|
||||||
|
// Placeholder for future implementation
|
||||||
|
const metricsData = {
|
||||||
|
totalReports: null,
|
||||||
|
activeIssues: null,
|
||||||
|
resolvedIssues: null,
|
||||||
|
criticalAlerts: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update DOM with API data
|
||||||
|
document.querySelector('[data-value="total-reports"]').textContent =
|
||||||
|
metricsData.totalReports !== null ? metricsData.totalReports : "—";
|
||||||
|
document.querySelector('[data-value="active-issues"]').textContent =
|
||||||
|
metricsData.activeIssues !== null ? metricsData.activeIssues : "—";
|
||||||
|
document.querySelector('[data-value="resolved-issues"]').textContent =
|
||||||
|
metricsData.resolvedIssues !== null ? metricsData.resolvedIssues : "—";
|
||||||
|
document.querySelector('[data-value="critical-alerts"]').textContent =
|
||||||
|
metricsData.criticalAlerts !== null ? metricsData.criticalAlerts : "—";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRecentActivity() {
|
||||||
|
// TODO: Replace with actual API call
|
||||||
|
// const response = await fetch('/api/activity/recent');
|
||||||
|
// const activities = await response.json();
|
||||||
|
|
||||||
|
const activities = [];
|
||||||
|
|
||||||
|
const listContainer = document.getElementById("activity-list");
|
||||||
|
const skeleton = document.getElementById("activity-skeleton");
|
||||||
|
const empty = document.getElementById("activity-empty");
|
||||||
|
const items = document.getElementById("activity-items");
|
||||||
|
|
||||||
|
skeleton.classList.add("hidden");
|
||||||
|
|
||||||
|
if (activities.length === 0) {
|
||||||
|
listContainer.setAttribute("data-status", "empty");
|
||||||
|
empty.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
listContainer.setAttribute("data-status", "loaded");
|
||||||
|
items.classList.remove("hidden");
|
||||||
|
|
||||||
|
// Render activity items
|
||||||
|
activities.forEach((activity) => {
|
||||||
|
const item = createActivityItem(activity);
|
||||||
|
items.appendChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createActivityItem(activity) {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = "px-6 py-4 flex items-start space-x-4";
|
||||||
|
div.setAttribute("data-activity-id", activity.id);
|
||||||
|
|
||||||
|
const statusColors = {
|
||||||
|
critical: "bg-red-400",
|
||||||
|
warning: "bg-yellow-400",
|
||||||
|
info: "bg-blue-400",
|
||||||
|
success: "bg-green-400",
|
||||||
|
};
|
||||||
|
|
||||||
|
div.innerHTML = `
|
||||||
|
<div class="w-2 h-2 mt-2 rounded-full ${
|
||||||
|
statusColors[activity.severity] || "bg-gray-600"
|
||||||
|
}"></div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p class="text-sm text-gray-200">${activity.message}</p>
|
||||||
|
<div class="mt-1 flex items-center space-x-3">
|
||||||
|
<span class="text-xs text-gray-500">${
|
||||||
|
activity.timestamp
|
||||||
|
}</span>
|
||||||
|
<span class="px-2 py-0.5 text-xs font-medium rounded ${getBadgeClass(
|
||||||
|
activity.status
|
||||||
|
)}">${activity.status}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBadgeClass(status) {
|
||||||
|
const classes = {
|
||||||
|
new: "bg-blue-900/40 text-blue-400",
|
||||||
|
"in-progress": "bg-yellow-900/40 text-yellow-400",
|
||||||
|
resolved: "bg-green-900/40 text-green-400",
|
||||||
|
closed: "bg-gray-800 text-gray-400",
|
||||||
|
};
|
||||||
|
return classes[status] || "bg-gray-800 text-gray-400";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize dashboard on page load
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
loadDashboardMetrics();
|
||||||
|
setTimeout(() => loadRecentActivity(), 500);
|
||||||
|
});
|
||||||
96
src/assets/users/_overview.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<div class="max-w-6xl mx-auto w-full">
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
||||||
|
|
||||||
|
<div class="group bg-neutral-800 rounded-lg border border-neutral-700/50 p-4 shadow-sm hover:border-blue-500/30 transition-all duration-300 flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xs font-semibold text-neutral-400 uppercase tracking-wider group-hover:text-blue-400 transition-colors">Total Reports</h3>
|
||||||
|
<p class="text-2xl font-bold text-white mt-1">128</p>
|
||||||
|
<p class="text-[10px] text-neutral-500 mt-1">All submissions overview</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-blue-500/10 rounded-lg group-hover:bg-blue-500/20 transition-colors">
|
||||||
|
<svg class="w-6 h-6 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group bg-neutral-800 rounded-lg border border-neutral-700/50 p-4 shadow-sm hover:border-yellow-500/30 transition-all duration-300 flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xs font-semibold text-neutral-400 uppercase tracking-wider group-hover:text-yellow-400 transition-colors">Active Issues</h3>
|
||||||
|
<p class="text-2xl font-bold text-white mt-1">42</p>
|
||||||
|
<p class="text-[10px] text-neutral-500 mt-1">In progress / Open</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-yellow-500/10 rounded-lg group-hover:bg-yellow-500/20 transition-colors">
|
||||||
|
<svg class="w-6 h-6 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group bg-neutral-800 rounded-lg border border-neutral-700/50 p-4 shadow-sm hover:border-green-500/30 transition-all duration-300 flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xs font-semibold text-neutral-400 uppercase tracking-wider group-hover:text-green-400 transition-colors">Resolved</h3>
|
||||||
|
<p class="text-2xl font-bold text-white mt-1">86</p>
|
||||||
|
<p class="text-[10px] text-neutral-500 mt-1">Successfully closed</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-green-500/10 rounded-lg group-hover:bg-green-500/20 transition-colors">
|
||||||
|
<svg class="w-6 h-6 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-lg border border-neutral-700 overflow-hidden shadow-sm">
|
||||||
|
<div class="px-4 py-3 border-b border-neutral-700 flex items-center justify-between bg-neutral-900/30">
|
||||||
|
<h3 class="text-sm font-semibold text-white">Recent Activity</h3>
|
||||||
|
<button class="text-xs text-blue-400 hover:text-blue-300 font-medium transition-colors">View All</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="divide-y divide-neutral-700/50">
|
||||||
|
|
||||||
|
<div class="px-4 py-3 hover:bg-neutral-700/30 transition-colors flex items-center gap-3">
|
||||||
|
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-green-500/10 border border-green-500/20 flex items-center justify-center">
|
||||||
|
<svg class="w-4 h-4 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0 grid gap-0.5">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<p class="text-sm font-medium text-neutral-200 truncate">
|
||||||
|
Issue <span class="text-white hover:underline cursor-pointer">#1231</span> Resolved
|
||||||
|
</p>
|
||||||
|
<span class="text-[10px] text-neutral-500 whitespace-nowrap">2h ago</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-neutral-500 truncate">Water leakage in park • <span>23/v/kpc-cst/33</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-4 py-3 hover:bg-neutral-700/30 transition-colors flex items-center gap-3">
|
||||||
|
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-blue-500/10 border border-blue-500/20 flex items-center justify-center">
|
||||||
|
<svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0 grid gap-0.5">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<p class="text-sm font-medium text-neutral-200 truncate">Issue 1234 submitted</p>
|
||||||
|
<span class="text-[10px] text-neutral-500 whitespace-nowrap">5h ago</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-neutral-500 truncate">Pothole on Main Street • <span>23/v/kpc-cst/36</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-4 py-3 hover:bg-neutral-700/30 transition-colors flex items-center gap-3">
|
||||||
|
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-yellow-500/10 border border-yellow-500/20 flex items-center justify-center">
|
||||||
|
<svg class="w-4 h-4 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0 grid gap-0.5">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<p class="text-sm font-medium text-neutral-200 truncate">Status: In Progress</p>
|
||||||
|
<span class="text-[10px] text-neutral-500 whitespace-nowrap">1d ago</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-neutral-500 truncate">Broken Street Light • <span>23/v/kpc-cst/37</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
511
src/assets/users/_reports.php
Normal file
@@ -0,0 +1,511 @@
|
|||||||
|
<?php
|
||||||
|
function words($text, $limit = 4) {
|
||||||
|
$w = preg_split('/\s+/', trim($text));
|
||||||
|
return count($w) > $limit
|
||||||
|
? implode(' ', array_slice($w, 0, $limit)) . '…'
|
||||||
|
: $text;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="max-w-7xl mx-auto space-y-6">
|
||||||
|
|
||||||
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-2xl md:text-3xl font-bold text-white tracking-tight">Campus Reports</h1>
|
||||||
|
<p class="mt-1 text-sm text-neutral-400">Manage facility and infrastructure issues</p>
|
||||||
|
</div>
|
||||||
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')"
|
||||||
|
class="w-full sm:w-auto px-5 py-2.5 bg-blue-600 hover:bg-blue-700 text-white text-sm font-semibold rounded-lg shadow-lg shadow-blue-900/20 transition-all flex items-center justify-center gap-2 group">
|
||||||
|
<svg class="w-4 h-4 transition-transform group-hover:rotate-90" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||||
|
</svg>
|
||||||
|
Create Report
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-800 rounded-xl border border-neutral-700 p-4 shadow-sm">
|
||||||
|
<div class="flex flex-col lg:flex-row gap-4 justify-between">
|
||||||
|
<div class="flex overflow-x-auto pb-2 lg:pb-0 gap-2 no-scrollbar">
|
||||||
|
<button
|
||||||
|
class="px-4 py-2 bg-blue-600/10 text-blue-400 border border-blue-600/20 text-sm font-medium rounded-lg whitespace-nowrap">All
|
||||||
|
Reports</button>
|
||||||
|
<button
|
||||||
|
class="px-4 py-2 hover:bg-neutral-700 text-neutral-400 hover:text-white text-sm font-medium rounded-lg transition-colors whitespace-nowrap">Open</button>
|
||||||
|
<button
|
||||||
|
class="px-4 py-2 hover:bg-neutral-700 text-neutral-400 hover:text-white text-sm font-medium rounded-lg transition-colors whitespace-nowrap">In
|
||||||
|
Progress</button>
|
||||||
|
<button
|
||||||
|
class="px-4 py-2 hover:bg-neutral-700 text-neutral-400 hover:text-white text-sm font-medium rounded-lg transition-colors whitespace-nowrap">Resolved</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col sm:flex-row gap-3">
|
||||||
|
<div class="relative min-w-[200px]">
|
||||||
|
<select
|
||||||
|
class="w-full appearance-none px-4 py-2 bg-neutral-900 border border-neutral-700 rounded-lg text-sm text-neutral-300 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 transition-all cursor-pointer">
|
||||||
|
<option>Last 7 days</option>
|
||||||
|
<option>Last 30 days</option>
|
||||||
|
<option>Last 90 days</option>
|
||||||
|
<option>All time</option>
|
||||||
|
</select>
|
||||||
|
<svg class="absolute right-3 top-2.5 h-4 w-4 text-neutral-500 pointer-events-none" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative w-full sm:w-64">
|
||||||
|
<input type="text" placeholder="Search reports..."
|
||||||
|
class="w-full pl-10 pr-4 py-2 bg-neutral-900 border border-neutral-700 rounded-lg text-sm text-white placeholder-neutral-500 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 transition-all">
|
||||||
|
<svg class="absolute left-3 top-2.5 h-4 w-4 text-neutral-500" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 md:hidden">
|
||||||
|
<div
|
||||||
|
class="bg-neutral-800 hover:bg-neutral-750 transition-colors duration-200 rounded-xl border border-neutral-700 p-4 space-y-3 group cursor-default">
|
||||||
|
<div class="flex justify-between items-start">
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-xs font-mono text-neutral-500 hover:text-blue-400 hover:underline cursor-pointer transition-colors">#1234</span>
|
||||||
|
<h3 class="font-semibold text-white mt-1">Pothole on Main Street</h3>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="inline-flex px-2.5 py-1 text-xs font-medium rounded-full bg-blue-900/30 text-blue-400 border border-blue-700/50">Open</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2 text-sm text-neutral-400">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
Main St. & 4th Ave
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-2 py-2 border-t border-b border-neutral-700/50">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Category</p>
|
||||||
|
<p class="text-sm text-neutral-300">Road Damage</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Priority</p>
|
||||||
|
<p class="text-sm text-red-400 font-medium">High</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between pt-1">
|
||||||
|
<div class="flex items-center gap-2 text-xs text-neutral-500">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
Dec 15, 2024
|
||||||
|
</div>
|
||||||
|
<button class="text-blue-400 text-sm font-medium hover:text-blue-300 transition-colors">View Details
|
||||||
|
→</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-neutral-800 hover:bg-neutral-750 transition-colors duration-200 rounded-xl border border-neutral-700 p-4 space-y-3 group cursor-default">
|
||||||
|
<div class="flex justify-between items-start">
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-xs font-mono text-neutral-500 hover:text-blue-400 hover:underline cursor-pointer transition-colors">#1233</span>
|
||||||
|
<h3 class="font-semibold text-white mt-1">Broken street light</h3>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="inline-flex px-2.5 py-1 text-xs font-medium rounded-full bg-yellow-900/30 text-yellow-500 border border-yellow-700/50">In
|
||||||
|
Progress</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2 text-sm text-neutral-400">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
Sector 7 Park
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-2 py-2 border-t border-b border-neutral-700/50">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Category</p>
|
||||||
|
<p class="text-sm text-neutral-300">Street Lighting</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Priority</p>
|
||||||
|
<p class="text-sm text-orange-400 font-medium">Medium</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between pt-1">
|
||||||
|
<div class="flex items-center gap-2 text-xs text-neutral-500">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
Dec 14, 2024
|
||||||
|
</div>
|
||||||
|
<button class="text-blue-400 text-sm font-medium hover:text-blue-300 transition-colors">View Details
|
||||||
|
→</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-neutral-800 hover:bg-neutral-750 transition-colors duration-200 rounded-xl border border-neutral-700 p-4 space-y-3 group cursor-default">
|
||||||
|
<div class="flex justify-between items-start">
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-xs font-mono text-neutral-500 hover:text-blue-400 hover:underline cursor-pointer transition-colors">#1232</span>
|
||||||
|
<h3 class="font-semibold text-white mt-1">Water leakage in park</h3>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="inline-flex px-2.5 py-1 text-xs font-medium rounded-full bg-green-900/30 text-green-400 border border-green-700/50">Resolved</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2 text-sm text-neutral-400">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
Central Park Zone B
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-2 py-2 border-t border-b border-neutral-700/50">
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Category</p>
|
||||||
|
<p class="text-sm text-neutral-300">Water Supply</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-xs text-neutral-500">Priority</p>
|
||||||
|
<p class="text-sm text-green-400 font-medium">Low</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between pt-1">
|
||||||
|
<div class="flex items-center gap-2 text-xs text-neutral-500">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
Dec 12, 2024
|
||||||
|
</div>
|
||||||
|
<button class="text-blue-400 text-sm font-medium hover:text-blue-300 transition-colors">View Details
|
||||||
|
→</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden md:block bg-neutral-800 rounded-xl border border-neutral-700 overflow-hidden shadow-sm">
|
||||||
|
<div class="overflow-x-auto custom-scrollbar">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead class="bg-neutral-900/50 border-b border-neutral-700">
|
||||||
|
<tr>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
ID</th>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Title</th>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Category</th>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Status</th>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Priority</th>
|
||||||
|
<th
|
||||||
|
class="px-6 py-4 text-center text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Image</th>
|
||||||
|
<th
|
||||||
|
class="px-6 py-4 text-center text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
G-Map</th>
|
||||||
|
<th class="px-6 py-4 text-left text-xs font-semibold text-neutral-400 uppercase tracking-wider">
|
||||||
|
Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-700/50">
|
||||||
|
<tr class="hover:bg-neutral-700/30 transition-colors duration-200 group">
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 text-sm font-mono text-neutral-500 group-hover:text-neutral-300 hover:text-blue-400 hover:underline cursor-pointer transition-colors">
|
||||||
|
#1234</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="text-sm font-medium text-white ">Pothole on Main Street</div>
|
||||||
|
<div class="text-xs text-neutral-500 mt-0.5">Reported by <span>23/v/kpc-cst/36</span></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Road Damage</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 text-xs font-medium rounded-full bg-blue-900/30 text-blue-400 border border-blue-700/50">
|
||||||
|
<span class="w-1.5 h-1.5 mr-1.5 bg-blue-400 rounded-full"></span>
|
||||||
|
Open
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-red-400 font-medium">High</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-neutral-400 hover:text-white transition-colors"
|
||||||
|
title="View Image">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-blue-500 hover:text-blue-400 transition-colors"
|
||||||
|
title="View Map">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-400">Dec 15, 2024</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="hover:bg-neutral-700/30 transition-colors duration-200 group">
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 text-sm font-mono text-neutral-500 group-hover:text-neutral-300 hover:text-blue-400 hover:underline cursor-pointer transition-colors">
|
||||||
|
#1233</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="text-sm font-medium text-white">Broken street light</div>
|
||||||
|
<div class="text-xs text-neutral-500 mt-0.5">Reported by <span>23/v/kpc-cst/37</span></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Street Lighting</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 text-xs font-medium rounded-full bg-yellow-900/30 text-yellow-500 border border-yellow-700/50">
|
||||||
|
<span class="w-1.5 h-1.5 mr-1.5 bg-yellow-500 rounded-full animate-pulse"></span>
|
||||||
|
In Progress
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-orange-400 font-medium">Medium</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-neutral-400 hover:text-white transition-colors"
|
||||||
|
title="View Image">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-blue-500 hover:text-blue-400 transition-colors"
|
||||||
|
title="View Map">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-400">Dec 14, 2024</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="hover:bg-neutral-700/30 transition-colors duration-200 group">
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 text-sm font-mono text-neutral-500 group-hover:text-neutral-300 hover:text-blue-400 hover:underline cursor-pointer transition-colors">
|
||||||
|
#1232</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<div class="text-sm font-medium text-white">Water leakage in park</div>
|
||||||
|
<div class="text-xs text-neutral-500 mt-0.5">Reported by <span>23/v/kpc-cst/33</span></div>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-300">Water Supply</td>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center px-2.5 py-0.5 text-xs font-medium rounded-full bg-green-900/30 text-green-400 border border-green-700/50">
|
||||||
|
<span class="w-1.5 h-1.5 mr-1.5 bg-green-400 rounded-full"></span>
|
||||||
|
Resolved
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-green-400 font-medium">Low</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-neutral-400 hover:text-white transition-colors"
|
||||||
|
title="View Image">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-center">
|
||||||
|
<button class="p-2 hover:bg-neutral-700 rounded-lg text-blue-500 hover:text-blue-400 transition-colors"
|
||||||
|
title="View Map">
|
||||||
|
<svg class="h-5 w-5 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 text-sm text-neutral-400">Dec 12, 2024</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-neutral-900 border-t border-neutral-700 px-6 py-4 flex items-center justify-between">
|
||||||
|
<span class="text-sm text-neutral-400">Showing <span class="text-white font-medium">1-3</span> of <span
|
||||||
|
class="text-white font-medium">128</span></span>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button
|
||||||
|
class="px-3 py-1 bg-neutral-800 hover:bg-neutral-700 border border-neutral-700 rounded-lg text-sm transition-colors disabled:opacity-50"
|
||||||
|
disabled>Previous</button>
|
||||||
|
<button
|
||||||
|
class="px-3 py-1 bg-neutral-800 hover:bg-neutral-700 border border-neutral-700 rounded-lg text-sm transition-colors">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="createModal" class="hidden fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog"
|
||||||
|
aria-modal="true">
|
||||||
|
<div class="flex items-end sm:items-center justify-center min-h-full p-4 text-center sm:p-0">
|
||||||
|
<div class="fixed inset-0 bg-neutral-900/80 backdrop-blur-sm transition-opacity" aria-hidden="true"
|
||||||
|
onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="relative bg-neutral-800 rounded-2xl border border-neutral-700 text-left shadow-2xl transform transition-all sm:my-8 sm:w-full sm:max-w-2xl">
|
||||||
|
<div class="px-6 py-4 border-b border-neutral-700 flex justify-between items-center">
|
||||||
|
<h2 class="text-xl font-semibold text-white">Create Report</h2>
|
||||||
|
<button onclick="document.getElementById('createModal').classList.add('hidden')"
|
||||||
|
class="text-neutral-400 hover:text-white transition-colors">
|
||||||
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-6 py-6 space-y-6">
|
||||||
|
<form>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div class="col-span-1 md:col-span-2">
|
||||||
|
<label class="block text-sm font-medium text-neutral-300 mb-2">Report Title <span class="text-red-500">*</span></label>
|
||||||
|
<input type="text" required
|
||||||
|
class="w-full px-4 py-2.5 bg-neutral-900 border border-neutral-700 rounded-lg text-white placeholder-neutral-500 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 transition-all"
|
||||||
|
placeholder="E.g., Large pothole near school">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-neutral-300 mb-2">Category <span class="text-red-500">*</span></label>
|
||||||
|
<div class="relative">
|
||||||
|
<select required
|
||||||
|
class="w-full px-4 py-2.5 bg-neutral-900 border border-neutral-700 rounded-lg text-white appearance-none focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all cursor-pointer">
|
||||||
|
<option value="" disabled selected>Select a category...</option>
|
||||||
|
<option>WiFi & Network Issue</option>
|
||||||
|
<option>Electrical Issue</option>
|
||||||
|
<option>Water & Plumbing</option>
|
||||||
|
<option>HVAC (AC/Heating)</option>
|
||||||
|
<option>Furniture & Fixtures</option>
|
||||||
|
<option>Cleaning & Janitorial</option>
|
||||||
|
<option>Security & Safety</option>
|
||||||
|
<option>Road & Pathway Damage</option>
|
||||||
|
<option>Other</option>
|
||||||
|
</select>
|
||||||
|
<svg class="absolute right-3 top-3 h-4 w-4 text-neutral-500 pointer-events-none"
|
||||||
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-neutral-300 mb-2">Priority <span class="text-red-500">*</span></label>
|
||||||
|
<div class="flex bg-neutral-900 rounded-lg p-1 border border-neutral-700">
|
||||||
|
<label class="flex-1 text-center cursor-pointer">
|
||||||
|
<input type="radio" name="priority" class="sr-only peer">
|
||||||
|
<span
|
||||||
|
class="block px-2 py-1.5 rounded-md text-sm text-neutral-400 peer-checked:bg-neutral-800 peer-checked:text-green-400 peer-checked:shadow-sm transition-all">Low</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex-1 text-center cursor-pointer">
|
||||||
|
<input type="radio" name="priority" class="sr-only peer">
|
||||||
|
<span
|
||||||
|
class="block px-2 py-1.5 rounded-md text-sm text-neutral-400 peer-checked:bg-neutral-800 peer-checked:text-white peer-checked:shadow-sm transition-all">Med</span>
|
||||||
|
</label>
|
||||||
|
<label class="flex-1 text-center cursor-pointer">
|
||||||
|
<input type="radio" name="priority" class="sr-only peer" checked>
|
||||||
|
<span
|
||||||
|
class="block px-2 py-1.5 rounded-md text-sm text-neutral-400 peer-checked:bg-neutral-800 peer-checked:text-white peer-checked:shadow-sm transition-all">High</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6">
|
||||||
|
<div class="flex justify-between items-center mb-2">
|
||||||
|
<label class="block text-sm font-medium text-neutral-300">Location <span class="text-red-500">*</span></label>
|
||||||
|
<button type="button" class="text-xs text-blue-400 hover:text-blue-300 flex items-center gap-1">
|
||||||
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
Use Current Location
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative mb-3">
|
||||||
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<svg class="h-4 w-4 text-neutral-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<input type="text" required
|
||||||
|
class="w-full pl-10 pr-4 py-2.5 bg-neutral-900 border border-neutral-700 rounded-lg text-white placeholder-neutral-500 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 transition-all text-sm"
|
||||||
|
placeholder="Paste Google Maps link or enter address...">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6">
|
||||||
|
<label class="block text-sm font-medium text-neutral-300 mb-2">Evidence <span class="text-red-500">*</span></label>
|
||||||
|
<div class="relative">
|
||||||
|
<input type="file" required id="file-upload" class="hidden">
|
||||||
|
<label for="file-upload"
|
||||||
|
class="block border-2 border-dashed border-neutral-700 rounded-xl p-8 text-center hover:border-blue-500/50 hover:bg-neutral-900/50 transition-all cursor-pointer group">
|
||||||
|
<div
|
||||||
|
class="w-12 h-12 bg-neutral-800 rounded-full flex items-center justify-center mx-auto mb-3 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="h-6 w-6 text-neutral-400 group-hover:text-blue-400" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-300 font-medium">Click to upload or drag and drop</p>
|
||||||
|
<p class="text-xs text-neutral-500 mt-1"> PNG, JPG, JPEG (max. 2MB)</p>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-6 py-4 border-t border-neutral-700 bg-neutral-800/50 flex flex-col sm:flex-row sm:items-center justify-between gap-4 rounded-b-2xl">
|
||||||
|
<span class="text-xs text-neutral-500 order-2 sm:order-1 text-center sm:text-left">
|
||||||
|
<span class="text-red-500">*</span> All fields marked above are required
|
||||||
|
</span>
|
||||||
|
<div class="flex gap-3 order-1 sm:order-2 w-full sm:w-auto justify-end">
|
||||||
|
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')"
|
||||||
|
class="px-5 py-2 text-neutral-300 hover:text-white text-sm font-medium transition-colors">Cancel</button>
|
||||||
|
<button type="submit"
|
||||||
|
class="px-5 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg shadow-lg shadow-blue-900/20 transition-all">Submit
|
||||||
|
Report</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
<?php
|
|
||||||
function numberToWords($num)
|
|
||||||
{
|
|
||||||
$words = [
|
|
||||||
0 => 'Zero',
|
|
||||||
1 => 'One',
|
|
||||||
2 => 'Two',
|
|
||||||
3 => 'Three',
|
|
||||||
4 => 'Four',
|
|
||||||
5 => 'Five',
|
|
||||||
6 => 'Six',
|
|
||||||
7 => 'Seven',
|
|
||||||
8 => 'Eight',
|
|
||||||
9 => 'Nine',
|
|
||||||
10 => 'Ten',
|
|
||||||
11 => 'Eleven',
|
|
||||||
12 => 'Twelve',
|
|
||||||
13 => 'Thirteen',
|
|
||||||
14 => 'Fourteen',
|
|
||||||
15 => 'Fifteen',
|
|
||||||
16 => 'Sixteen',
|
|
||||||
17 => 'Seventeen',
|
|
||||||
18 => 'Eighteen',
|
|
||||||
19 => 'Nineteen',
|
|
||||||
20 => 'Twenty',
|
|
||||||
30 => 'Thirty',
|
|
||||||
40 => 'Forty',
|
|
||||||
50 => 'Fifty',
|
|
||||||
60 => 'Sixty',
|
|
||||||
70 => 'Seventy',
|
|
||||||
80 => 'Eighty',
|
|
||||||
90 => 'Ninety'
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($num <= 20) return $words[$num];
|
|
||||||
if ($num < 100) {
|
|
||||||
$tens = intval($num / 10) * 10;
|
|
||||||
$ones = $num % 10;
|
|
||||||
return $words[$tens] . ($ones ? ' ' . $words[$ones] : '');
|
|
||||||
}
|
|
||||||
return strval($num);
|
|
||||||
}
|
|
||||||
|
|
||||||
function timeAgo($datetime)
|
|
||||||
{
|
|
||||||
$now = new DateTime();
|
|
||||||
$time = new DateTime($datetime);
|
|
||||||
$diff = $now->diff($time);
|
|
||||||
$isFuture = $time > $now;
|
|
||||||
|
|
||||||
if ($diff->y >= 10) return 'A decade ago';
|
|
||||||
if ($diff->y > 0) return ($diff->y == 1 ? 'A' : numberToWords($diff->y)) . ' year' . ($diff->y > 1 ? 's' : '') . ' ago';
|
|
||||||
if ($diff->m > 0) return ($diff->m == 1 ? 'A' : numberToWords($diff->m)) . ' month' . ($diff->m > 1 ? 's' : '') . ' ago';
|
|
||||||
if ($diff->d >= 7) {
|
|
||||||
$weeks = floor($diff->d / 7);
|
|
||||||
return ($weeks == 1 ? 'A' : numberToWords($weeks)) . ' week' . ($weeks > 1 ? 's' : '') . ' ago';
|
|
||||||
}
|
|
||||||
if ($diff->d > 1) return numberToWords($diff->d) . ' days ago';
|
|
||||||
if ($diff->d == 1) return $isFuture ? 'The next day' : 'The previous day';
|
|
||||||
if ($diff->h > 0) return numberToWords($diff->h) . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago';
|
|
||||||
if ($diff->i > 0) return numberToWords($diff->i) . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago';
|
|
||||||
if ($diff->s > 0) return numberToWords($diff->s) . ' second' . ($diff->s > 1 ? 's' : '') . ' ago';
|
|
||||||
return 'Just now';
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDuration($duration)
|
|
||||||
{
|
|
||||||
$parts = explode(':', $duration);
|
|
||||||
if (count($parts) == 2) {
|
|
||||||
$minutes = intval($parts[0]);
|
|
||||||
$seconds = intval($parts[1]);
|
|
||||||
if ($minutes > 0 && $seconds > 0) return $minutes . 'm ' . $seconds . 's';
|
|
||||||
if ($minutes > 0) return $minutes . 'm';
|
|
||||||
return $seconds . ' s';
|
|
||||||
} elseif (count($parts) == 3) {
|
|
||||||
$hours = intval($parts[0]);
|
|
||||||
$minutes = intval($parts[1]);
|
|
||||||
$seconds = intval($parts[2]);
|
|
||||||
$result = '';
|
|
||||||
if ($hours > 0) $result .= $hours . 'h';
|
|
||||||
if ($minutes > 0) $result .= ($result ? ' ' : '') . $minutes . 'm';
|
|
||||||
if ($seconds > 0) $result .= ($result ? ' ' : '') . $seconds . 's';
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
return $duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatViews($num)
|
|
||||||
{
|
|
||||||
if ($num >= 1000000000) return round($num / 1000000000, 1) . 'B';
|
|
||||||
if ($num >= 1000000) return round($num / 1000000, 1) . 'M';
|
|
||||||
if ($num >= 1000) return round($num / 1000, 1) . 'k';
|
|
||||||
return $num;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
require __DIR__ . '/vendor/autoload.php';
|
require __DIR__ . './../core/vendor/autoload.php';
|
||||||
|
|
||||||
use Dotenv\Dotenv;
|
use Dotenv\Dotenv;
|
||||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__));
|
$dotenv = Dotenv::createImmutable(dirname(__DIR__));
|
||||||
$dotenv->load();
|
$dotenv->load();
|
||||||
|
?>
|
||||||
@@ -1,726 +0,0 @@
|
|||||||
<?php
|
|
||||||
// A raw translation file
|
|
||||||
// Array of translations per language
|
|
||||||
$texts = [
|
|
||||||
'English (United Kingdom)' => [
|
|
||||||
'sign_in' => 'Sign in',
|
|
||||||
'continue_to' => 'to continue to',
|
|
||||||
'email_placeholder' => 'Email or username',
|
|
||||||
'forgot_email' => 'Forgot the email?',
|
|
||||||
'guest_mode' => 'Not your desktop? Use Private Browsing windows to sign in.',
|
|
||||||
'learn_more' => 'Learn more about the Guest mode',
|
|
||||||
'create_account' => 'Create an account',
|
|
||||||
'next' => 'Confirm',
|
|
||||||
'help' => 'Support',
|
|
||||||
'privacy' => 'Privacy Policy',
|
|
||||||
'terms' => 'Terms of Service',
|
|
||||||
'bug' => 'Found a bug? Help us fix it'
|
|
||||||
],
|
|
||||||
|
|
||||||
'English (United States)' => [
|
|
||||||
'sign_in' => 'Log in',
|
|
||||||
'continue_to' => 'to continue to',
|
|
||||||
'email_placeholder' => 'Email or username',
|
|
||||||
'forgot_email' => 'Forgot your email?',
|
|
||||||
'guest_mode' => 'Not your personal computer? Use Incognito mode to sign in.',
|
|
||||||
'learn_more' => 'Learn more about using Guest mode',
|
|
||||||
'create_account' => 'Create account',
|
|
||||||
'next' => 'Continue',
|
|
||||||
'help' => 'Help',
|
|
||||||
'privacy' => 'Privacy',
|
|
||||||
'terms' => 'Terms',
|
|
||||||
'bug' => 'Spotted a bug? Help us fix it'
|
|
||||||
],
|
|
||||||
|
|
||||||
'Español (España)' => [
|
|
||||||
'sign_in' => 'Iniciar sesión',
|
|
||||||
'continue_to' => 'para continuar a',
|
|
||||||
'email_placeholder' => 'Correo electrónico o usuario',
|
|
||||||
'forgot_email' => '¿Olvidaste el correo?',
|
|
||||||
'guest_mode' => '¿No es tu escritorio? Usa ventanas de navegación privada para iniciar sesión.',
|
|
||||||
'learn_more' => 'Más información sobre el modo invitado',
|
|
||||||
'create_account' => 'Crear una cuenta',
|
|
||||||
'next' => 'Confirmar',
|
|
||||||
'help' => 'Soporte',
|
|
||||||
'privacy' => 'Política de privacidad',
|
|
||||||
'terms' => 'Términos de servicio',
|
|
||||||
'bug' => "¿Encontraste un error?\nAyúdanos a solucionarlo"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Español (Latinoamérica)' => [
|
|
||||||
'sign_in' => 'Iniciar sesión',
|
|
||||||
'continue_to' => 'para continuar a',
|
|
||||||
'email_placeholder' => 'Correo electrónico o usuario',
|
|
||||||
'forgot_email' => '¿Olvidaste tu correo?',
|
|
||||||
'guest_mode' => '¿No es tu computadora? Usa ventanas de navegación privada para iniciar sesión.',
|
|
||||||
'learn_more' => 'Más información sobre el modo invitado',
|
|
||||||
'create_account' => 'Crear una cuenta',
|
|
||||||
'next' => 'Confirmar',
|
|
||||||
'help' => 'Soporte',
|
|
||||||
'privacy' => 'Política de privacidad',
|
|
||||||
'terms' => 'Términos de servicio',
|
|
||||||
'bug' => "¿Encontraste un error?\nAyúdanos a solucionarlo"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Français (Canada)' => [
|
|
||||||
'sign_in' => 'Se connecter',
|
|
||||||
'continue_to' => 'pour continuer vers',
|
|
||||||
'email_placeholder' => 'Courriel ou nom d’utilisateur',
|
|
||||||
'forgot_email' => 'Courriel oublié ?',
|
|
||||||
'guest_mode' => 'Ce n’est pas votre bureau ? Utilisez des fenêtres de navigation privée pour vous connecter.',
|
|
||||||
'learn_more' => 'En savoir plus sur le mode invité',
|
|
||||||
'create_account' => 'Créer un compte',
|
|
||||||
'next' => 'Confirmer',
|
|
||||||
'help' => 'Support',
|
|
||||||
'privacy' => 'Politique de confidentialité',
|
|
||||||
'terms' => 'Conditions d’utilisation',
|
|
||||||
'bug' => "Vous avez trouvé un bogue?\nAidez-nous à le corriger"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Français (France)' => [
|
|
||||||
'sign_in' => 'Se connecter',
|
|
||||||
'continue_to' => 'pour continuer vers',
|
|
||||||
'email_placeholder' => 'Courriel ou nom d’utilisateur',
|
|
||||||
'forgot_email' => 'Courriel oublié ?',
|
|
||||||
'guest_mode' => 'Ce n’est pas votre bureau ? Utilisez des fenêtres de navigation privée pour vous connecter.',
|
|
||||||
'learn_more' => 'En savoir plus sur le mode invité',
|
|
||||||
'create_account' => 'Créer un compte',
|
|
||||||
'next' => 'Confirmer',
|
|
||||||
'help' => 'Support',
|
|
||||||
'privacy' => 'Politique de confidentialité',
|
|
||||||
'terms' => 'Conditions d’utilisation',
|
|
||||||
'bug' => "Vous avez trouvé un bogue?\nAidez-nous à le corriger"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Deutsch' => [
|
|
||||||
'sign_in' => 'Anmelden',
|
|
||||||
'continue_to' => 'um fortzufahren zu',
|
|
||||||
'email_placeholder' => 'E-Mail oder Benutzername',
|
|
||||||
'forgot_email' => 'E-Mail vergessen?',
|
|
||||||
'guest_mode' => 'Nicht dein Desktop? Verwende Privatfenster zum Anmelden.',
|
|
||||||
'learn_more' => 'Mehr über den Gastmodus erfahren',
|
|
||||||
'create_account' => 'Ein Konto erstellen',
|
|
||||||
'next' => 'Bestätigen',
|
|
||||||
'help' => 'Support',
|
|
||||||
'privacy' => 'Datenschutzrichtlinie',
|
|
||||||
'terms' => 'Nutzungsbedingungen',
|
|
||||||
'bug' => "Fehler gefunden?\nHelfen Sie uns, ihn zu beheben"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Gaeilge' => [
|
|
||||||
'sign_in' => 'Sínigh isteach',
|
|
||||||
'continue_to' => 'chun leanúint ar aghaidh chuig',
|
|
||||||
'email_placeholder' => 'Ríomhphost nó ainm úsáideora',
|
|
||||||
'forgot_email' => 'Ar dhearmad tú do ríomhphost?',
|
|
||||||
'guest_mode' => 'Ní do dheasc é seo? Úsáid fuinneoga brabhsála príobháideacha chun síniú isteach.',
|
|
||||||
'learn_more' => 'Foghlaim níos mó faoi mhodh an aíochtaí',
|
|
||||||
'create_account' => 'Cuir cuntas ar bun',
|
|
||||||
'next' => 'Dearbhaigh',
|
|
||||||
'help' => 'Tacaíocht',
|
|
||||||
'privacy' => 'Polasaí Príobháideachta',
|
|
||||||
'terms' => 'Téarmaí Seirbhíse',
|
|
||||||
'bug' => "Ar aimsigh tú fabht?\nCabhraigh linn é a cheartú"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Indonesian' => [
|
|
||||||
'sign_in' => 'Masuk',
|
|
||||||
'continue_to' => 'untuk melanjutkan ke',
|
|
||||||
'email_placeholder' => 'Email atau nama pengguna',
|
|
||||||
'forgot_email' => 'Lupa email?',
|
|
||||||
'guest_mode' => 'Bukan desktop Anda? Gunakan jendela Penjelajahan Pribadi untuk masuk.',
|
|
||||||
'learn_more' => 'Pelajari lebih lanjut tentang mode Tamu',
|
|
||||||
'create_account' => 'Buat akun',
|
|
||||||
'next' => 'Konfirmasi',
|
|
||||||
'help' => 'Bantuan',
|
|
||||||
'privacy' => 'Kebijakan Privasi',
|
|
||||||
'terms' => 'Syarat Layanan',
|
|
||||||
'bug' => "Menemukan bug? Bantu kami memperbaikinya"
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
'Italiano' => [
|
|
||||||
'sign_in' => 'Accedi',
|
|
||||||
'continue_to' => 'per continuare a',
|
|
||||||
'email_placeholder' => 'Email o nome utente',
|
|
||||||
'forgot_email' => 'Hai dimenticato l’email?',
|
|
||||||
'guest_mode' => 'Non è il tuo desktop? Usa finestre di navigazione privata per accedere.',
|
|
||||||
'learn_more' => 'Ulteriori informazioni sulla modalità ospite',
|
|
||||||
'create_account' => 'Crea un account',
|
|
||||||
'next' => 'Conferma',
|
|
||||||
'help' => 'Supporto',
|
|
||||||
'privacy' => 'Informativa sulla privacy',
|
|
||||||
'terms' => 'Termini di servizio',
|
|
||||||
'bug' => "Hai trovato un bug? Aiutaci a risolverlo"
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
'Melayu' => [
|
|
||||||
'sign_in' => 'Log masuk',
|
|
||||||
'continue_to' => 'untuk terus ke',
|
|
||||||
'email_placeholder' => 'Emel atau nama pengguna',
|
|
||||||
'forgot_email' => 'Lupa emel?',
|
|
||||||
'guest_mode' => 'Bukan desktop anda? Gunakan tetingkap Penyemakan Imbas Peribadi untuk log masuk.',
|
|
||||||
'learn_more' => 'Ketahui lebih lanjut mengenai mod Tetamu',
|
|
||||||
'create_account' => 'Buat akaun',
|
|
||||||
'next' => 'Sahkan',
|
|
||||||
'help' => 'Sokongan',
|
|
||||||
'privacy' => 'Dasar Privasi',
|
|
||||||
'terms' => 'Terma Perkhidmatan',
|
|
||||||
'bug' => "Jumpa pepijat? Bantu kami membetulkannya"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Nederlands' => [
|
|
||||||
'sign_in' => 'Inloggen',
|
|
||||||
'continue_to' => 'om door te gaan naar',
|
|
||||||
'email_placeholder' => 'E-mail of gebruikersnaam',
|
|
||||||
'forgot_email' => 'E-mail vergeten?',
|
|
||||||
'guest_mode' => 'Niet jouw desktop? Gebruik privévensters om in te loggen.',
|
|
||||||
'learn_more' => 'Meer informatie over de gastmodus',
|
|
||||||
'create_account' => 'Maak een account aan',
|
|
||||||
'next' => 'Bevestigen',
|
|
||||||
'help' => 'Ondersteuning',
|
|
||||||
'privacy' => 'Privacybeleid',
|
|
||||||
'terms' => 'Gebruiksvoorwaarden',
|
|
||||||
'bug' => "Bug gevonden? Help ons dit op te lossen"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Norsk' => [
|
|
||||||
'sign_in' => 'Logg inn',
|
|
||||||
'continue_to' => 'for å fortsette til',
|
|
||||||
'email_placeholder' => 'E-post eller brukernavn',
|
|
||||||
'forgot_email' => 'Glemt e-post?',
|
|
||||||
'guest_mode' => 'Ikke din desktop? Bruk privat vindu for å logge inn.',
|
|
||||||
'learn_more' => 'Lær mer om gjestemodus',
|
|
||||||
'create_account' => 'Opprett en konto',
|
|
||||||
'next' => 'Bekreft',
|
|
||||||
'help' => 'Støtte',
|
|
||||||
'privacy' => 'Personvern',
|
|
||||||
'terms' => 'Vilkår for bruk',
|
|
||||||
'bug' => "Fant du en feil? Hjelp oss å fikse den",
|
|
||||||
],
|
|
||||||
|
|
||||||
"O‘zbek" => [
|
|
||||||
'sign_in' => 'Kirish',
|
|
||||||
'continue_to' => 'davom ettirish uchun',
|
|
||||||
'email_placeholder' => 'Email yoki foydalanuvchi nomi',
|
|
||||||
'forgot_email' => 'Emailni unutdingizmi?',
|
|
||||||
'guest_mode' => 'Sizning desktopingiz emasmi? Maxfiy brauzer oynasidan foydalaning.',
|
|
||||||
'learn_more' => 'Mehmon rejimi haqida batafsil ma’lumot',
|
|
||||||
'create_account' => 'Hisob yaratish',
|
|
||||||
'next' => 'Tasdiqlash',
|
|
||||||
'help' => 'Yordam',
|
|
||||||
'privacy' => 'Maxfiylik siyosati',
|
|
||||||
'terms' => 'Xizmat shartlari',
|
|
||||||
'bug' => "Xato topdingizmi? Uni tuzatishda yordam bering",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Português (Brasil)' => [
|
|
||||||
'sign_in' => 'Entrar',
|
|
||||||
'continue_to' => 'para continuar para',
|
|
||||||
'email_placeholder' => 'Email ou nome de usuário',
|
|
||||||
'forgot_email' => 'Esqueceu o email?',
|
|
||||||
'guest_mode' => 'Não é seu desktop? Use janelas de navegação privada para entrar.',
|
|
||||||
'learn_more' => 'Saiba mais sobre o modo convidado',
|
|
||||||
'create_account' => 'Criar uma conta',
|
|
||||||
'next' => 'Confirmar',
|
|
||||||
'help' => 'Suporte',
|
|
||||||
'privacy' => 'Política de Privacidade',
|
|
||||||
'terms' => 'Termos de Serviço',
|
|
||||||
'bug' => "Encontrou um bug? Ajude-nos a corrigi-lo",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Português (Portugal)' => [
|
|
||||||
'sign_in' => 'Iniciar sessão',
|
|
||||||
'continue_to' => 'para continuar para',
|
|
||||||
'email_placeholder' => 'Email ou nome de utilizador',
|
|
||||||
'forgot_email' => 'Esqueceu o email?',
|
|
||||||
'guest_mode' => 'Não é o seu desktop? Utilize janelas de navegação privada para iniciar sessão.',
|
|
||||||
'learn_more' => 'Saiba mais sobre o modo convidado',
|
|
||||||
'create_account' => 'Criar uma conta',
|
|
||||||
'next' => 'Confirmar',
|
|
||||||
'help' => 'Suporte',
|
|
||||||
'privacy' => 'Política de Privacidade',
|
|
||||||
'terms' => 'Termos de Serviço',
|
|
||||||
'bug' => "Encontrou um bug? Ajude-nos a corrigi-lo",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Română' => [
|
|
||||||
'sign_in' => 'Conectare',
|
|
||||||
'continue_to' => 'pentru a continua către',
|
|
||||||
'email_placeholder' => 'Email sau nume de utilizator',
|
|
||||||
'forgot_email' => 'Ai uitat emailul?',
|
|
||||||
'guest_mode' => 'Nu este desktopul tău? Folosește ferestre private pentru a te conecta.',
|
|
||||||
'learn_more' => 'Aflați mai multe despre modul oaspete',
|
|
||||||
'create_account' => 'Creează un cont',
|
|
||||||
'next' => 'Confirmă',
|
|
||||||
'help' => 'Suport',
|
|
||||||
'privacy' => 'Politica de confidențialitate',
|
|
||||||
'terms' => 'Termeni de serviciu',
|
|
||||||
'bug' => "Ai găsit un bug? Ajută-ne să îl reparăm",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Svenska' => [
|
|
||||||
'sign_in' => 'Logga in',
|
|
||||||
'continue_to' => 'för att fortsätta till',
|
|
||||||
'email_placeholder' => 'E-post eller användarnamn',
|
|
||||||
'forgot_email' => 'Glömt e-post?',
|
|
||||||
'guest_mode' => 'Inte din desktop? Använd privata fönster för att logga in.',
|
|
||||||
'learn_more' => 'Läs mer om gästläget',
|
|
||||||
'create_account' => 'Skapa ett konto',
|
|
||||||
'next' => 'Bekräfta',
|
|
||||||
'help' => 'Support',
|
|
||||||
'privacy' => 'Sekretesspolicy',
|
|
||||||
'terms' => 'Användarvillkor',
|
|
||||||
'bug' => "Hittade du en bugg? Hjälp oss att åtgärda den",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Tiếng Việt' => [
|
|
||||||
'sign_in' => 'Đăng nhập',
|
|
||||||
'continue_to' => 'để tiếp tục tới',
|
|
||||||
'email_placeholder' => 'Email hoặc tên người dùng',
|
|
||||||
'forgot_email' => 'Quên email?',
|
|
||||||
'guest_mode' => 'Không phải desktop của bạn? Sử dụng cửa sổ ẩn danh để đăng nhập.',
|
|
||||||
'learn_more' => 'Tìm hiểu thêm về chế độ khách',
|
|
||||||
'create_account' => 'Tạo tài khoản',
|
|
||||||
'next' => 'Xác nhận',
|
|
||||||
'help' => 'Hỗ trợ',
|
|
||||||
'privacy' => 'Chính sách bảo mật',
|
|
||||||
'terms' => 'Điều khoản dịch vụ',
|
|
||||||
'bug' => "Bạn phát hiện lỗi? Giúp chúng tôi sửa nó"
|
|
||||||
],
|
|
||||||
|
|
||||||
'Türkçe' => [
|
|
||||||
'sign_in' => 'Oturum aç',
|
|
||||||
'continue_to' => 'devam etmek için',
|
|
||||||
'email_placeholder' => 'E-posta veya kullanıcı adı',
|
|
||||||
'forgot_email' => 'E-postayı unuttunuz mu?',
|
|
||||||
'guest_mode' => 'Masaüstünüz mü değil? Özel tarama pencerelerini kullanarak oturum açın.',
|
|
||||||
'learn_more' => 'Misafir modu hakkında daha fazla bilgi edinin',
|
|
||||||
'create_account' => 'Hesap oluştur',
|
|
||||||
'next' => 'Onayla',
|
|
||||||
'help' => 'Destek',
|
|
||||||
'privacy' => 'Gizlilik Politikası',
|
|
||||||
'terms' => 'Hizmet Şartları',
|
|
||||||
'bug' => "Bir hata mı buldunuz? Düzeltmemize yardımcı olun",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Ελληνικά' => [
|
|
||||||
'sign_in' => 'Σύνδεση',
|
|
||||||
'continue_to' => 'για να συνεχίσετε στο',
|
|
||||||
'email_placeholder' => 'Email ή όνομα χρήστη',
|
|
||||||
'forgot_email' => 'Ξεχάσατε το email;',
|
|
||||||
'guest_mode' => 'Δεν είναι ο υπολογιστής σας; Χρησιμοποιήστε παράθυρα ιδιωτικής περιήγησης για σύνδεση.',
|
|
||||||
'learn_more' => 'Μάθετε περισσότερα για τη λειτουργία επισκέπτη',
|
|
||||||
'create_account' => 'Δημιουργία λογαριασμού',
|
|
||||||
'next' => 'Επιβεβαίωση',
|
|
||||||
'help' => 'Υποστήριξη',
|
|
||||||
'privacy' => 'Πολιτική Απορρήτου',
|
|
||||||
'terms' => 'Όροι Υπηρεσίας',
|
|
||||||
'bug' => "Βρήκατε σφάλμα; Βοηθήστε μας να το διορθώσουμε"
|
|
||||||
],
|
|
||||||
|
|
||||||
'қазақ тілі' => [
|
|
||||||
'sign_in' => 'Кіру',
|
|
||||||
'continue_to' => 'жалғастыру үшін',
|
|
||||||
'email_placeholder' => 'Электрондық пошта немесе пайдаланушы аты',
|
|
||||||
'forgot_email' => 'Электрондық поштаны ұмыттыңыз ба?',
|
|
||||||
'guest_mode' => 'Сіздің жұмыс үстеліңіз емес пе? Жеке терезелерді қолданып кіріңіз.',
|
|
||||||
'learn_more' => 'Қонақ режимі туралы көбірек біліңіз',
|
|
||||||
'create_account' => 'Тіркелгі жасау',
|
|
||||||
'next' => 'Растау',
|
|
||||||
'help' => 'Қолдау',
|
|
||||||
'privacy' => 'Құпиялылық саясаты',
|
|
||||||
'terms' => 'Қызмет көрсету шарттары',
|
|
||||||
'bug' => "Қате таптыңыз ба? Оны түзетуге көмектесіңіз"
|
|
||||||
],
|
|
||||||
|
|
||||||
'монгол' => [
|
|
||||||
'sign_in' => 'Нэвтрэх',
|
|
||||||
'continue_to' => 'үргэлжлүүлэх',
|
|
||||||
'email_placeholder' => 'Имэйл эсвэл хэрэглэгчийн нэр',
|
|
||||||
'forgot_email' => 'Имэйл мартсан уу?',
|
|
||||||
'guest_mode' => 'Таны ширээний компьютер биш үү? Хувийн цонх ашиглан нэвтэрнэ үү.',
|
|
||||||
'learn_more' => 'Зочны горимын талаар дэлгэрэнгүй',
|
|
||||||
'create_account' => 'Данс үүсгэх',
|
|
||||||
'next' => 'Баталгаажуулах',
|
|
||||||
'help' => 'Тусламж',
|
|
||||||
'privacy' => 'Нууцлалын бодлого',
|
|
||||||
'terms' => 'Үйлчилгээний нөхцөл',
|
|
||||||
'bug' => "Алдаа илэрсэн үү? Үүнийг засахад туслаач",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Русский' => [
|
|
||||||
'sign_in' => 'Войти',
|
|
||||||
'continue_to' => 'чтобы продолжить на',
|
|
||||||
'email_placeholder' => 'Электронная почта или имя пользователя',
|
|
||||||
'forgot_email' => 'Забыли электронную почту?',
|
|
||||||
'guest_mode' => 'Это не ваш рабочий стол? Используйте приватные окна для входа.',
|
|
||||||
'learn_more' => 'Подробнее о режиме гостя',
|
|
||||||
'create_account' => 'Создать аккаунт',
|
|
||||||
'next' => 'Подтвердить',
|
|
||||||
'help' => 'Поддержка',
|
|
||||||
'privacy' => 'Политика конфиденциальности',
|
|
||||||
'terms' => 'Условия обслуживания',
|
|
||||||
'bug' => "Нашли ошибку?\nПомогите нам её исправить",
|
|
||||||
],
|
|
||||||
|
|
||||||
'Українська' => [
|
|
||||||
'sign_in' => 'Увійти',
|
|
||||||
'continue_to' => 'щоб продовжити на',
|
|
||||||
'email_placeholder' => 'Електронна пошта або ім’я користувача',
|
|
||||||
'forgot_email' => 'Забули електронну пошту?',
|
|
||||||
'guest_mode' => 'Це не ваш робочий стіл? Використовуйте приватні вікна для входу.',
|
|
||||||
'learn_more' => 'Дізнатися більше про режим гостя',
|
|
||||||
'create_account' => 'Створити обліковий запис',
|
|
||||||
'next' => 'Підтвердити',
|
|
||||||
'help' => 'Підтримка',
|
|
||||||
'privacy' => 'Політика конфіденційності',
|
|
||||||
'terms' => 'Умови обслуговування',
|
|
||||||
'bug' => "Знайшли помилку?\nДопоможіть нам її виправити"
|
|
||||||
],
|
|
||||||
|
|
||||||
'ქართული' => [
|
|
||||||
'sign_in' => 'შესვლა',
|
|
||||||
'continue_to' => 'საგრძელებლად',
|
|
||||||
'email_placeholder' => 'ელ.ფოსტა ან მომხმარებლის სახელი',
|
|
||||||
'forgot_email' => 'ელ.ფოსტა დაგავიწყდა?',
|
|
||||||
'guest_mode' => 'ეს შენი დესკტოპი არ არის? გამოიყენეთ კერძო ბრაუზერის ფანჯრები შესასვლელად.',
|
|
||||||
'learn_more' => 'გაიგე მეტი სტუმრის რეჟიმის შესახებ',
|
|
||||||
'create_account' => 'ანგარიშის შექმნა',
|
|
||||||
'next' => 'დადასტურება',
|
|
||||||
'help' => 'მხარდაჭერა',
|
|
||||||
'privacy' => "კონფიდენციალურობის\nპოლიტიკა",
|
|
||||||
'terms' => 'სერვისის პირობები',
|
|
||||||
'bug' => "იპოვნეთ შეცდომა?\nდაგვეხმარეთ მისი გამოსწორებაში"
|
|
||||||
],
|
|
||||||
|
|
||||||
'հայերեն' => [
|
|
||||||
'sign_in' => 'Մուտք գործել',
|
|
||||||
'continue_to' => 'շարունակելու համար դեպի',
|
|
||||||
'email_placeholder' => 'Էլ.փոստ կամ օգտվողի անուն',
|
|
||||||
'forgot_email' => 'Մոռացե՞լ եք էլ.փոստը',
|
|
||||||
'guest_mode' => 'ԴՁեր աշխատասեղանի մոտ չե՞ք: Օգտագործեք մասնավոր զննարկիչ մուտք գործելու համար:',
|
|
||||||
'learn_more' => 'Իմանալ ավելին «Հյուրի» ռեժիմի մասին',
|
|
||||||
'create_account' => 'Ստեղծել հաշիվ',
|
|
||||||
'next' => 'Հաստատել',
|
|
||||||
'help' => 'Աջակցություն',
|
|
||||||
'privacy' => "Գաղտնիության\nքաղաքականություն",
|
|
||||||
'terms' => "Ծառայության\nպայմաններ",
|
|
||||||
'bug' => "Սխալ գտա՞ք։\nՕգնեք մեզ այն շտկել"
|
|
||||||
],
|
|
||||||
|
|
||||||
'اردو' => [
|
|
||||||
'sign_in' => 'لاگ ان',
|
|
||||||
'continue_to' => 'جاری رکھنے کے لیے',
|
|
||||||
'email_placeholder' => 'ای میل یا صارف نام',
|
|
||||||
'forgot_email' => 'ای میل بھول گئے؟',
|
|
||||||
'guest_mode' => 'یہ آپ کا ڈیسک ٹاپ نہیں ہے؟ سائن ان کرنے کے لیے پرائیویٹ براؤزنگ ونڈوز استعمال کریں۔',
|
|
||||||
'learn_more' => 'مہمان موڈ کے بارے میں مزید جانیں',
|
|
||||||
'create_account' => 'اکاؤنٹ بنائیں',
|
|
||||||
'next' => 'تصدیق کریں',
|
|
||||||
'help' => 'مدد',
|
|
||||||
'privacy' => 'پرائیویسی پالیسی',
|
|
||||||
'terms' => 'سروس کی شرائط',
|
|
||||||
'bug' => "کیا آپ نے کوئی خرابی دیکھی؟ ہماری مدد کریں اسے درست کرنے میں"
|
|
||||||
],
|
|
||||||
|
|
||||||
'العربية' => [
|
|
||||||
'sign_in' => 'تسجيل الدخول',
|
|
||||||
'continue_to' => 'للإستمرار إلى',
|
|
||||||
'email_placeholder' => 'البريد الإلكتروني أو اسم المستخدم',
|
|
||||||
'forgot_email' => 'نسيت البريد الإلكتروني؟',
|
|
||||||
'guest_mode' => 'ليس سطح المكتب الخاص بك؟ استخدم نوافذ التصفح الخاصة لتسجيل الدخول.',
|
|
||||||
'learn_more' => 'تعرف على المزيد حول وضع الضيف',
|
|
||||||
'create_account' => 'إنشاء حساب',
|
|
||||||
'next' => 'تأكيد',
|
|
||||||
'help' => 'الدعم',
|
|
||||||
'privacy' => 'سياسة الخصوصية',
|
|
||||||
'terms' => 'شروط الخدمة',
|
|
||||||
'bug' => "هل وجدت خطأً؟ ساعدنا في إصلاحه"
|
|
||||||
],
|
|
||||||
|
|
||||||
'हिन्दी' => [
|
|
||||||
'sign_in' => 'साइन इन',
|
|
||||||
'continue_to' => 'जारी रखने के लिए',
|
|
||||||
'email_placeholder' => 'ईमेल या उपयोगकर्ता नाम',
|
|
||||||
'forgot_email' => 'ईमेल भूल गए?',
|
|
||||||
'guest_mode' => 'यह आपका डेस्कटॉप नहीं है? साइन इन करने के लिए प्राइवेट ब्राउज़िंग विंडो का उपयोग करें।',
|
|
||||||
'learn_more' => 'गेस्ट मोड के बारे में और जानें',
|
|
||||||
'create_account' => 'खाता बनाएं',
|
|
||||||
'next' => 'पुष्टि करें',
|
|
||||||
'help' => 'सहायता',
|
|
||||||
'privacy' => 'गोपनीयता नीति',
|
|
||||||
'terms' => 'सेवा की शर्तें',
|
|
||||||
'bug' => "क्या आपको कोई बग मिला? हमारी मदद करें इसे ठीक करने में"
|
|
||||||
],
|
|
||||||
|
|
||||||
'অসমীয়া' => [
|
|
||||||
'sign_in' => 'সাইন ইন',
|
|
||||||
'continue_to' => 'অগ্ৰগতি কৰিবলৈ',
|
|
||||||
'email_placeholder' => 'ইমেইল বা ব্যৱহাৰকাৰীৰ নাম',
|
|
||||||
'forgot_email' => 'ইমেইল পাহৰি গ’ল?',
|
|
||||||
'guest_mode' => 'এয়া আপোনাৰ ডেস্কটপ নহয়? সাইন ইন কৰিবলৈ ব্যক্তিগত ব্ৰাউজিং উইণ্ডো ব্যৱহাৰ কৰক।',
|
|
||||||
'learn_more' => 'গেষ্ট মোডৰ বিষয়ে বেছি জানক',
|
|
||||||
'create_account' => 'একাউণ্ট বনাওক',
|
|
||||||
'next' => 'নিশ্চিত কৰক',
|
|
||||||
'help' => 'সহায়',
|
|
||||||
'privacy' => 'গোপনীয়তা নীতি',
|
|
||||||
'terms' => 'সেৱাৰ চৰ্তাৱলী',
|
|
||||||
'bug' => "আপুনি কোনো ত্ৰুটি পাইলেনে? আমাক ইয়াক ঠিক কৰিবলৈ সহায় কৰক"
|
|
||||||
],
|
|
||||||
|
|
||||||
'বাংলা (India)' => [
|
|
||||||
'sign_in' => 'সাইন ইন',
|
|
||||||
'continue_to' => 'চালিয়ে যেতে',
|
|
||||||
'email_placeholder' => 'ইমেল বা ব্যবহারকারীর নাম',
|
|
||||||
'forgot_email' => 'ইমেল ভুলে গেছেন?',
|
|
||||||
'guest_mode' => 'এটি আপনার ডেস্কটপ নয়? সাইন ইন করার জন্য প্রাইভেট ব্রাউজিং উইন্ডো ব্যবহার করুন।',
|
|
||||||
'learn_more' => 'গেস্ট মোড সম্পর্কে আরও জানুন',
|
|
||||||
'create_account' => 'একাউন্ট তৈরি করুন',
|
|
||||||
'next' => 'নিশ্চিত করুন',
|
|
||||||
'help' => 'সাহায্য',
|
|
||||||
'privacy' => 'গোপনীয়তা নীতি',
|
|
||||||
'terms' => 'সার্ভিসের শর্তাবলী',
|
|
||||||
'bug' => "কোনও ত্ৰুটি দেখেছেন? আমাদের সেটি ঠিক করতে সাহায্য করুন"
|
|
||||||
],
|
|
||||||
|
|
||||||
'বাংলা (Bangladesh)' => [
|
|
||||||
'sign_in' => 'সাইন ইন',
|
|
||||||
'continue_to' => 'চালিয়ে যেতে',
|
|
||||||
'email_placeholder' => 'ইমেল বা ব্যবহারকারীর নাম',
|
|
||||||
'forgot_email' => 'ইমেল ভুলে গেছেন?',
|
|
||||||
'guest_mode' => 'এটি আপনার ডেস্কটপ নয়? সাইন ইন করার জন্য প্রাইভেট ব্রাউজিং উইন্ডো ব্যবহার করুন।',
|
|
||||||
'learn_more' => 'গেস্ট মোড সম্পর্কে আরও জানুন',
|
|
||||||
'create_account' => 'একাউন্ট তৈরি করুন',
|
|
||||||
'next' => 'নিশ্চিত করুন',
|
|
||||||
'help' => 'সাহায্য',
|
|
||||||
'privacy' => 'গোপনীয়তা নীতি',
|
|
||||||
'terms' => 'সার্ভিসের শর্তাবলী',
|
|
||||||
'bug' => "কোনও ত্ৰুটি দেখেছেন? আমাদের সেটি ঠিক করতে সাহায্য করুন"
|
|
||||||
],
|
|
||||||
|
|
||||||
'ਪੰਜਾਬੀ' => [
|
|
||||||
'sign_in' => 'ਸਾਈਨ ਇਨ',
|
|
||||||
'continue_to' => 'ਜਾਰੀ ਰੱਖਣ ਲਈ',
|
|
||||||
'email_placeholder' => 'ਈਮੇਲ ਜਾਂ ਉਪਭੋਗਤਾ ਨਾਮ',
|
|
||||||
'forgot_email' => 'ਈਮੇਲ ਭੁੱਲ ਗਏ?',
|
|
||||||
'guest_mode' => 'ਇਹ ਤੁਹਾਡਾ ਡੈਸਕਟਾਪ ਨਹੀਂ ਹੈ? ਸਾਈਨ ਇਨ ਕਰਨ ਲਈ ਪ੍ਰਾਈਵੇਟ ਬ੍ਰਾਉਜ਼ਿੰਗ ਵਰਤੋਂ।',
|
|
||||||
'learn_more' => 'ਗੈਸਟ ਮੋਡ ਬਾਰੇ ਹੋਰ ਜਾਣੋ',
|
|
||||||
'create_account' => 'ਖਾਤਾ ਬਣਾਓ',
|
|
||||||
'next' => 'ਪੁਸ਼ਟੀ ਕਰੋ',
|
|
||||||
'help' => 'ਮਦਦ',
|
|
||||||
'privacy' => 'ਪ੍ਰਾਈਵੇਸੀ',
|
|
||||||
'terms' => 'ਸ਼ਰਤਾਂ',
|
|
||||||
'bug' => "ਕੀ ਤੁਸੀਂ ਕੋਈ ਬੱਗ ਲੱਭਿਆ? ਸਾਡੇ ਨੂੰ ਇਸਨੂੰ ਠੀਕ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰੋ"
|
|
||||||
],
|
|
||||||
|
|
||||||
'ગુજરાતી' => [
|
|
||||||
'sign_in' => 'સાઇન ઇન',
|
|
||||||
'continue_to' => 'ચાલુ રાખવા માટે',
|
|
||||||
'email_placeholder' => 'ઇમેલ અથવા વપરાશકર્તા નામ',
|
|
||||||
'forgot_email' => 'ઇમેલ ભૂલી ગયા?',
|
|
||||||
'guest_mode' => 'આ તમારું ડેસ્કટોપ નથી? સાઇન ઇન કરવા માટે પ્રાઇવેટ બ્રાઉઝિંગ વાપરો.',
|
|
||||||
'learn_more' => 'ગેસ્ટ મોડ વિશે વધુ જાણો',
|
|
||||||
'create_account' => 'એકાઉન્ટ બનાવો',
|
|
||||||
'next' => 'સંદેશની પુષ્ટિ કરો',
|
|
||||||
'help' => 'મદદ',
|
|
||||||
'privacy' => 'ગોપનીયતા',
|
|
||||||
'terms' => 'શરતો',
|
|
||||||
'bug' => "શું તમને કોઈ ભૂલ મળી? અમને તેને સુધારવામાં મદદ કરો"
|
|
||||||
],
|
|
||||||
|
|
||||||
'ଓଡ଼ିଆ' => [
|
|
||||||
'sign_in' => 'ସାଇନ୍ ଇନ୍',
|
|
||||||
'continue_to' => 'ଚାଲୁ ରଖିବା ପାଇଁ',
|
|
||||||
'email_placeholder' => 'ଇମେଲ୍ କିମ୍ବା ବ୍ୟବହାରକାରୀ ନାମ',
|
|
||||||
'forgot_email' => 'ଇମେଲ୍ ଭୁଲିଗଲେ?',
|
|
||||||
'guest_mode' => 'ଏହା ଆପଣଙ୍କର ଡେସ୍କଟପ୍ ନୁହେଁ? ସାଇନ୍ ଇନ୍ କରିବା ପାଇଁ ପ୍ରାଇଭେଟ୍ ବ୍ରାଉଜିଂ ୱିଣ୍ଡୋ ବ୍ୟବହାର କରନ୍ତୁ।',
|
|
||||||
'learn_more' => 'ଗେଷ୍ଟ୍ ମୋଡ୍ ବିଷୟରେ ଅଧିକ ଜାଣନ୍ତୁ',
|
|
||||||
'create_account' => 'ଏକ ଖାତା ତିଆରି କରନ୍ତୁ',
|
|
||||||
'next' => 'ନିଶ୍ଚିତ କରନ୍ତୁ',
|
|
||||||
'help' => 'ସହାୟତା',
|
|
||||||
'privacy' => 'ଗୋପନୀୟତା',
|
|
||||||
'terms' => 'ସେବା ନୀତି',
|
|
||||||
'bug' => "ଆପଣ କିଛି ତ୍ରୁଟି ଦେଖିଛନ୍ତି? ଆମକୁ ଏହା ଠିକ କରିବାରେ ସାହାଯ୍ୟ କରନ୍ତୁ"
|
|
||||||
],
|
|
||||||
|
|
||||||
'தமிழ்' => [
|
|
||||||
'sign_in' => 'சைன் இன்',
|
|
||||||
'continue_to' => 'தொடர திரும்ப',
|
|
||||||
'email_placeholder' => 'மின்னஞ்சல் அல்லது பயனர் பெயர்',
|
|
||||||
'forgot_email' => 'மின்னஞ்சல் மறந்துவிட்டீர்களா?',
|
|
||||||
'guest_mode' => 'இது உங்கள் டெஸ்க்டாப் அல்லவா? சைன் இன் செய்ய தனிப்பட்ட பிரௌசிங் பயன்படுத்தவும்.',
|
|
||||||
'learn_more' => 'கெஸ்ட் மோடு பற்றி மேலும் அறிக',
|
|
||||||
'create_account' => 'கணக்கு உருவாக்கவும்',
|
|
||||||
'next' => 'தொடரவும்',
|
|
||||||
'help' => 'உதவி',
|
|
||||||
'privacy' => 'தனியுரிமை',
|
|
||||||
'terms' => 'சேவை நிபந்தனைகள்',
|
|
||||||
'bug' => "பிழை கண்டறிந்தீர்களா? அதை சரி செய்ய எங்களுக்கு உதவுங்கள்"
|
|
||||||
],
|
|
||||||
|
|
||||||
'తెలుగు' => [
|
|
||||||
'sign_in' => 'సైన్ ఇన్',
|
|
||||||
'continue_to' => 'కొనసాగడానికి',
|
|
||||||
'email_placeholder' => 'ఇమెయిల్ లేదా యూజర్ పేరు',
|
|
||||||
'forgot_email' => 'ఇమెయిల్ మర్చిపోయారా?',
|
|
||||||
'guest_mode' => 'ఇది మీ డెస్క్టాప్ కాదు? సైన్ ఇన్ చేసేందుకు ప్రైవేట్ బ్రౌజింగ్ విండో ఉపయోగించండి.',
|
|
||||||
'learn_more' => 'అతిథి మోడ్ గురించి మరింత తెలుసుకోండి',
|
|
||||||
'create_account' => 'ఖాతా సృష్టించండి',
|
|
||||||
'next' => 'తదుపరి',
|
|
||||||
'help' => 'సహాయం',
|
|
||||||
'privacy' => 'గోప్యతా విధానం',
|
|
||||||
'terms' => 'సేవా నిబంధనలు',
|
|
||||||
'bug' => "దోషం కనపడిందా? దాన్ని సరిచేయడంలో మాకు సహాయపడండి"
|
|
||||||
],
|
|
||||||
|
|
||||||
'ಕನ್ನಡ' => [
|
|
||||||
'sign_in' => 'ಸೈನ್ ಇನ್',
|
|
||||||
'continue_to' => 'ಮುಂದುವರಿಸಲು',
|
|
||||||
'email_placeholder' => 'ಇಮೇಲ್ ಅಥವಾ ಬಳಕೆದಾರ ಹೆಸರು',
|
|
||||||
'forgot_email' => 'ಇಮೇಲ್ ಮರೆತಿದ್ದೀರಾ?',
|
|
||||||
'guest_mode' => 'ಇದು ನಿಮ್ಮ ಡೆಸ್ಕ್ಟಾಪ್ ಅಲ್ಲವೇ? ಸೈನ್ ಇನ್ ಮಾಡಲು ಪ್ರೈವೇಟ್ ಬ್ರೌಸಿಂಗ್ ಬಳಸಿ.',
|
|
||||||
'learn_more' => 'ಅತಿಥಿ ಮೋಡ್ ಬಗ್ಗೆ ಹೆಚ್ಚು ತಿಳಿಯಿರಿ',
|
|
||||||
'create_account' => 'ಖಾತೆ ರಚಿಸಿ',
|
|
||||||
'next' => 'ಮುಂದುವರಿಸಿ',
|
|
||||||
'help' => 'ಸಹಾಯ',
|
|
||||||
'privacy' => 'ಗೊಪ್ಯತೆ',
|
|
||||||
'terms' => 'ಸೇವೆ ನಿಯಮಗಳು',
|
|
||||||
'bug' => "ನೀವು ಒಂದು ದೋಷ ಕಂಡಿದ್ದೀರಾ? ಇದನ್ನು ಸರಿಪಡಿಸಲು ನಮಗೆ ಸಹಾಯ ಮಾಡಿ"
|
|
||||||
],
|
|
||||||
|
|
||||||
'മലയാളം' => [
|
|
||||||
'sign_in' => 'സൈൻ ഇൻ',
|
|
||||||
'continue_to' => 'തുടരാൻ',
|
|
||||||
'email_placeholder' => 'ഇമെയിൽ അല്ലെങ്കിൽ ഉപയോക്തൃനാമം',
|
|
||||||
'forgot_email' => 'ഇമെയിൽ മറന്നോ?',
|
|
||||||
'guest_mode' => 'ഇത് നിങ്ങളുടെ ഡെസ്ക്ടോപ്പ് അല്ലേ? സൈൻ ഇൻ ചെയ്യാൻ പ്രൈവറ്റ് ബ്രൗസിംഗ് ഉപയോഗിക്കുക.',
|
|
||||||
'learn_more' => 'ഗസ്റ്റ് മോഡ് ഉപയോഗത്തെ കുറിച്ച് കൂടുതൽ അറിയുക',
|
|
||||||
'create_account' => 'അക്കൗണ്ട് സൃഷ്ടിക്കുക',
|
|
||||||
'next' => 'തുടരുക',
|
|
||||||
'help' => 'സഹായം',
|
|
||||||
'privacy' => 'സ്വകാര്യത',
|
|
||||||
'terms' => 'നിയമങ്ങൾ',
|
|
||||||
'bug' => "ഒരു പിശക് കണ്ടോ? ദയവായി അത് ശരിയാക്കാൻ ഞങ്ങളെ സഹായിക്കുക"
|
|
||||||
],
|
|
||||||
|
|
||||||
'سنڌي' => [
|
|
||||||
'sign_in' => 'سائن ان',
|
|
||||||
'continue_to' => 'جاري رکڻ لاءِ',
|
|
||||||
'email_placeholder' => 'ايميل يا يوزر نالو',
|
|
||||||
'forgot_email' => 'ايميل وساري وياسين؟',
|
|
||||||
'guest_mode' => 'ڇا هي توهان جو ڪمپيوٽر ناهي؟ سائن ان ڪرڻ لاءِ پرائيويٽ برائوزنگ استعمال ڪريو.',
|
|
||||||
'learn_more' => 'گيسٽ موڊ بابت وڌيڪ ڄاڻو',
|
|
||||||
'create_account' => 'اڪائونٽ ٺاهيو',
|
|
||||||
'next' => 'اڳتي وڌو',
|
|
||||||
'help' => 'مدد',
|
|
||||||
'privacy' => 'رازداري',
|
|
||||||
'terms' => 'شرطن',
|
|
||||||
'bug' => 'ڇا توهان کي ڪو بگ مليو؟ ان کي درست ڪرڻ ۾ اسان جي مدد ڪريو'
|
|
||||||
],
|
|
||||||
|
|
||||||
'मराठी' => [
|
|
||||||
'sign_in' => 'साइन इन',
|
|
||||||
'continue_to' => 'सुरू ठेवण्यासाठी',
|
|
||||||
'email_placeholder' => 'ईमेल किंवा वापरकर्तानाव',
|
|
||||||
'forgot_email' => 'ईमेल विसरलात?',
|
|
||||||
'guest_mode' => 'हे तुमचे डेस्कटॉप नाही? साइन इन करण्यासाठी प्रायव्हेट ब्राउझिंग वापरा.',
|
|
||||||
'learn_more' => 'गेस्ट मोडबद्दल अधिक जाणून घ्या',
|
|
||||||
'create_account' => 'खाते तयार करा',
|
|
||||||
'next' => 'सुरू ठेवा',
|
|
||||||
'help' => 'सहाय्य',
|
|
||||||
'privacy' => 'गोपनीयता',
|
|
||||||
'terms' => 'अटी',
|
|
||||||
'bug' => 'तुम्हाला एखादी बग सापडली का? ती दुरुस्त करण्यात आमची मदत करा'
|
|
||||||
],
|
|
||||||
|
|
||||||
'नेपाली' => [
|
|
||||||
'sign_in' => 'साइन इन',
|
|
||||||
'continue_to' => 'जारी राख्न',
|
|
||||||
'email_placeholder' => 'इमेल वा प्रयोगकर्ता नाम',
|
|
||||||
'forgot_email' => 'इमेल बिर्सनुभयो?',
|
|
||||||
'guest_mode' => 'यो तपाईंको डेस्कटप होइन? साइन इन गर्न प्राइभेट ब्राउजिङ प्रयोग गर्नुहोस्।',
|
|
||||||
'learn_more' => 'गेस्ट मोडको बारेमा जान्नुहोस्',
|
|
||||||
'create_account' => 'खाता सिर्जना गर्नुहोस्',
|
|
||||||
'next' => 'जारी राख्नुहोस्',
|
|
||||||
'help' => 'सहायता',
|
|
||||||
'privacy' => 'गोपनीयता',
|
|
||||||
'terms' => 'सर्तहरू',
|
|
||||||
'bug' => 'के तपाईँले कुनै बग फेला पार्नुभयो? कृपया यसलाई सच्याउन हामीलाई मद्दत गर्नुहोस्'
|
|
||||||
],
|
|
||||||
|
|
||||||
'ไทย' => [
|
|
||||||
'sign_in' => 'เข้าสู่ระบบ',
|
|
||||||
'continue_to' => 'ดำเนินการต่อไปยัง',
|
|
||||||
'email_placeholder' => 'อีเมลหรือชื่อผู้ใช้',
|
|
||||||
'forgot_email' => 'ลืมอีเมลใช่ไหม?',
|
|
||||||
'guest_mode' => 'นี่ไม่ใช่เดสก์ท็อปของคุณ? ใช้หน้าต่างการท่องเว็บส่วนตัวเพื่อลงชื่อเข้าใช้',
|
|
||||||
'learn_more' => 'เรียนรู้เพิ่มเติมเกี่ยวกับโหมดผู้เยี่ยมชม',
|
|
||||||
'create_account' => 'สร้างบัญชี',
|
|
||||||
'next' => 'ดำเนินการต่อ',
|
|
||||||
'help' => 'ช่วยเหลือ',
|
|
||||||
'privacy' => 'ความเป็นส่วนตัว',
|
|
||||||
'terms' => 'ข้อกำหนด',
|
|
||||||
'bug' => 'พบข้อผิดพลาด? โปรดช่วยเราแก้ไข'
|
|
||||||
],
|
|
||||||
|
|
||||||
'한국어' => [
|
|
||||||
'sign_in' => '로그인',
|
|
||||||
'continue_to' => '계속 진행',
|
|
||||||
'email_placeholder' => '이메일 또는 사용자 이름',
|
|
||||||
'forgot_email' => '이메일을 잊으셨나요?',
|
|
||||||
'guest_mode' => '데스크톱이 아닌가요? 개인 정보 보호 브라우징 창을 사용하여 로그인하세요.',
|
|
||||||
'learn_more' => '게스트 모드에 대해 자세히 알아보기',
|
|
||||||
'create_account' => '계정 만들기',
|
|
||||||
'next' => '계속',
|
|
||||||
'help' => '도움말',
|
|
||||||
'privacy' => '개인정보',
|
|
||||||
'terms' => '약관',
|
|
||||||
'bug' => '버그를 발견하셨나요? 수정하는 데 도움을 주세요'
|
|
||||||
],
|
|
||||||
|
|
||||||
'日本語' => [
|
|
||||||
'sign_in' => 'サインイン',
|
|
||||||
'continue_to' => '次へ進む',
|
|
||||||
'email_placeholder' => 'メールアドレスまたはユーザー名',
|
|
||||||
'forgot_email' => 'メールアドレスをお忘れですか?',
|
|
||||||
'guest_mode' => 'デスクトップではありませんか?プライベートブラウジングウィンドウでサインインしてください。',
|
|
||||||
'learn_more' => 'ゲストモードについて詳しく',
|
|
||||||
'create_account' => 'アカウント作成',
|
|
||||||
'next' => '続行',
|
|
||||||
'help' => 'ヘルプ',
|
|
||||||
'privacy' => 'プライバシー',
|
|
||||||
'terms' => '利用規約',
|
|
||||||
'bug' => 'バグを見つけましたか?修正にご協力ください'
|
|
||||||
],
|
|
||||||
|
|
||||||
'简体中文' => [
|
|
||||||
'sign_in' => '登录',
|
|
||||||
'continue_to' => '继续至',
|
|
||||||
'email_placeholder' => '邮箱或用户名',
|
|
||||||
'forgot_email' => '忘记邮箱?',
|
|
||||||
'guest_mode' => '不是您的桌面?请使用隐私浏览窗口登录。',
|
|
||||||
'learn_more' => '了解更多访客模式信息',
|
|
||||||
'create_account' => '创建账户',
|
|
||||||
'next' => '继续',
|
|
||||||
'help' => '帮助',
|
|
||||||
'privacy' => '隐私',
|
|
||||||
'terms' => '条款',
|
|
||||||
'bug' => '发现错误了吗?请帮助我们修复它'
|
|
||||||
],
|
|
||||||
|
|
||||||
'繁體中文' => [
|
|
||||||
'sign_in' => '登入',
|
|
||||||
'continue_to' => '繼續至',
|
|
||||||
'email_placeholder' => '電子郵件或用戶名',
|
|
||||||
'forgot_email' => '忘記電子郵件?',
|
|
||||||
'guest_mode' => '不是您的桌面?請使用隱私瀏覽視窗登入。',
|
|
||||||
'learn_more' => '了解更多訪客模式資訊',
|
|
||||||
'create_account' => '建立帳號',
|
|
||||||
'next' => '繼續',
|
|
||||||
'help' => '幫助',
|
|
||||||
'privacy' => '隱私',
|
|
||||||
'terms' => '條款',
|
|
||||||
'bug' => '發現錯誤了嗎?請幫助我們修復它'
|
|
||||||
],
|
|
||||||
];
|
|
||||||
64
src/core/router.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user_id'])) {
|
||||||
|
header('Location: ./pages/sign_in_email.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_admin = $_SESSION['is_admin'] ?? false;
|
||||||
|
$page = $_GET['page'] ?? 'overview';
|
||||||
|
|
||||||
|
$routes = [
|
||||||
|
'overview' => [
|
||||||
|
'role' => 'user',
|
||||||
|
'label' => 'Overview',
|
||||||
|
'icon' => 'home',
|
||||||
|
'file' => './assets/users/_overview.php',
|
||||||
|
'nav' => true,
|
||||||
|
],
|
||||||
|
'reports' => [
|
||||||
|
'role' => 'user',
|
||||||
|
'label' => 'Reports',
|
||||||
|
'icon' => 'file-text',
|
||||||
|
'file' => './assets/users/_reports.php',
|
||||||
|
'nav' => true,
|
||||||
|
],
|
||||||
|
'status-board' => [
|
||||||
|
'role' => 'admin',
|
||||||
|
'label' => 'Status Board',
|
||||||
|
'icon' => 'activity',
|
||||||
|
'file' => './assets/admin/_status_board.php',
|
||||||
|
'nav' => true,
|
||||||
|
],
|
||||||
|
'activity-logs' => [
|
||||||
|
'role' => 'admin',
|
||||||
|
'label' => 'Activity Logs',
|
||||||
|
'icon' => 'clock',
|
||||||
|
'file' => './assets/admin/_activity_logs.php',
|
||||||
|
'nav' => true,
|
||||||
|
],
|
||||||
|
'admin' => [
|
||||||
|
'role' => 'admin',
|
||||||
|
'label' => 'Admin',
|
||||||
|
'icon' => 'settings',
|
||||||
|
'file' => './assets/admin/_admin.php',
|
||||||
|
'nav' => true,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!isset($routes[$page])) {
|
||||||
|
$page = $is_admin ? 'status-board' : 'overview';
|
||||||
|
}
|
||||||
|
|
||||||
|
$routeRole = $routes[$page]['role'];
|
||||||
|
|
||||||
|
if (
|
||||||
|
($routeRole === 'admin' && !$is_admin) ||
|
||||||
|
($routeRole === 'user' && $is_admin)
|
||||||
|
) {
|
||||||
|
$page = $is_admin ? 'status-board' : 'overview';
|
||||||
|
}
|
||||||
|
|
||||||
|
$current_route = $routes[$page];
|
||||||
|
?>
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<?php
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
// Initialize the application
|
|
||||||
include '../init.php';
|
|
||||||
include '../connection.php';
|
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
|
|
||||||
session_unset();
|
|
||||||
session_destroy();
|
|
||||||
header("Location: " . $_SERVER['PHP_SELF']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_logged_in = isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
|
|
||||||
$user_id = $_SESSION['user_id'] ?? null;
|
|
||||||
|
|
||||||
$username = 'Unknown';
|
|
||||||
$email = 'Unknown';
|
|
||||||
$password_hash = '';
|
|
||||||
$password_plain = $_SESSION['user_password_plain'] ?? null;
|
|
||||||
|
|
||||||
if ($user_id) {
|
|
||||||
$stmt = $conn->prepare("SELECT username, email, password_hash FROM users WHERE id = ? LIMIT 1");
|
|
||||||
if ($stmt) {
|
|
||||||
$stmt->bind_param("i", $user_id);
|
|
||||||
$stmt->execute();
|
|
||||||
$stmt->bind_result($db_username, $db_email, $db_password_hash);
|
|
||||||
$stmt->fetch();
|
|
||||||
if (!empty($db_username))
|
|
||||||
$username = $db_username;
|
|
||||||
if (!empty($db_email))
|
|
||||||
$email = $db_email;
|
|
||||||
$password_hash = $db_password_hash;
|
|
||||||
$stmt->close();
|
|
||||||
} else {
|
|
||||||
die("Database error: " . htmlspecialchars($conn->error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>Account Test Page</title>
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
||||||
<link rel="stylesheet" href="../../src/output.css">
|
|
||||||
<style>
|
|
||||||
.kv {
|
|
||||||
min-width: 160px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-row {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-item {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 min-h-screen flex items-center justify-center p-6">
|
|
||||||
<div class="w-full max-w-4xl">
|
|
||||||
<div class="bg-black border border-neutral-800 rounded-3xl p-8 shadow-2xl">
|
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-8 gap-4">
|
|
||||||
<h1 class="text-3xl font-bold text-white">Account Info — Test</h1>
|
|
||||||
<div class="text-lg text-gray-400">
|
|
||||||
Status:
|
|
||||||
<span class="<?php echo $is_logged_in ? 'text-green-400' : 'text-red-400'; ?>">
|
|
||||||
<?php echo $is_logged_in ? 'Logged in ✅' : 'Not logged in ❌'; ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">Username</div>
|
|
||||||
<div class="flex-1 text-lg card-item"><?php echo htmlspecialchars($username); ?></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">Email</div>
|
|
||||||
<div class="flex-1 text-lg card-item"><?php echo htmlspecialchars($email); ?></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">Password</div>
|
|
||||||
<div class="flex-1 card-item">
|
|
||||||
<?php if ($password_plain !== null): ?>
|
|
||||||
<div class="relative">
|
|
||||||
<input id="plainPwd" type="password" readonly
|
|
||||||
value="<?php echo htmlspecialchars($password_plain); ?>"
|
|
||||||
class="w-full bg-transparent border border-neutral-700 rounded-md px-4 py-3 text-lg text-gray-200 focus:outline-none" />
|
|
||||||
<button id="togglePwd" type="button"
|
|
||||||
class="absolute right-2 top-1/2 -translate-y-1/2 bg-neutral-800 px-3 py-1 rounded text-sm hover:bg-neutral-700">
|
|
||||||
Show
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p class="mt-2 text-sm text-yellow-300">Plaintext available from session for testing purposes
|
|
||||||
only.</p>
|
|
||||||
<?php else: ?>
|
|
||||||
<div class="text-gray-400 text-sm">Plaintext not stored, password hashed(secure).</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">Password Hash</div>
|
|
||||||
<div class="flex-1 text-sm break-all card-item"><?php echo htmlspecialchars($password_hash); ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">User ID</div>
|
|
||||||
<div class="flex-1 text-lg card-item"><?php echo htmlspecialchars($user_id ?? '—'); ?></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 bg-neutral-900 rounded-2xl flex items-center gap-4 card-row">
|
|
||||||
<div class="kv text-gray-400">Session Data</div>
|
|
||||||
<div class="flex-1 text-sm text-gray-400 card-item">
|
|
||||||
<?php echo htmlspecialchars(json_encode(array_intersect_key($_SESSION, array_flip(['user_id', 'user_name', 'user_email'])))); ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-8 flex gap-4 justify-start flex-wrap">
|
|
||||||
<form method="get" action="" class="inline">
|
|
||||||
<button type="submit" name="action" value="logout"
|
|
||||||
class="px-6 py-3 rounded-full bg-red-600 hover:bg-red-700 text-white text-lg font-medium">
|
|
||||||
Logout
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<button type="button" onclick="window.location.href='../../home.php';"
|
|
||||||
class="px-6 py-3 rounded-full bg-neutral-800 hover:bg-neutral-700 text-gray-200 text-lg font-medium">
|
|
||||||
Back
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
(function () {
|
|
||||||
const btn = document.getElementById('togglePwd');
|
|
||||||
const input = document.getElementById('plainPwd');
|
|
||||||
if (!btn || !input) return;
|
|
||||||
btn.addEventListener('click', function () {
|
|
||||||
if (input.type === 'password') {
|
|
||||||
input.type = 'text';
|
|
||||||
btn.textContent = 'Hide';
|
|
||||||
} else {
|
|
||||||
input.type = 'password';
|
|
||||||
btn.textContent = 'Show';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
101
src/home.php
@@ -1,101 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Initialize the application
|
|
||||||
include './core/init.php';
|
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
|
||||||
ini_set('display_errors', 0);
|
|
||||||
ini_set('display_startup_errors', 0);
|
|
||||||
error_reporting(0);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<!-- Meta & Viewport Configuration -->
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100..900&display=swap" rel="stylesheet">
|
|
||||||
|
|
||||||
<!-- Dynamic Page Title (from .env DOMAIN variable) -->
|
|
||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="bg-black">
|
|
||||||
<!-- Includes -->
|
|
||||||
<?php include 'assets/_navbar.php'; ?>
|
|
||||||
<?php include 'assets/_sidebar.php'; ?>
|
|
||||||
<?php include 'core/connection.php'; ?>
|
|
||||||
<?php include 'core/home/home_config.php'; ?>
|
|
||||||
|
|
||||||
<main class="mt-8 p-7">
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$sql = "SELECT thumbnail, duration, channel_image, title, channel_name, views, uploaded_at FROM videos ORDER BY uploaded_at DESC";
|
|
||||||
$result = $conn->query($sql);
|
|
||||||
|
|
||||||
if ($result->num_rows > 0):
|
|
||||||
while ($row = $result->fetch_assoc()):
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="cursor-pointer">
|
|
||||||
<!-- Thumbnail -->
|
|
||||||
<div class="relative">
|
|
||||||
<img src="<?php echo htmlspecialchars($row['thumbnail']); ?>" alt="video thumbnail"
|
|
||||||
class="w-full h-auto rounded-2xl opacity-90" loading="lazy">
|
|
||||||
<span class="absolute bottom-2 right-2 text-gray-200 text-xs px-1 py-[0.15rem] rounded-md bg-black/50">
|
|
||||||
<?php echo htmlspecialchars(formatDuration($row['duration'])); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<!-- Info -->
|
|
||||||
<div class="flex mt-2 gap-3">
|
|
||||||
<img src="<?php echo htmlspecialchars($row['channel_image']); ?>" alt="channel"
|
|
||||||
class="w-auto h-10 rounded-full opacity-90" loading="lazy">
|
|
||||||
<div>
|
|
||||||
<h3 class="text-md text-gray-200"><?php echo htmlspecialchars($row['title']); ?></h3>
|
|
||||||
<p class="text-sm text-gray-400"><?php echo htmlspecialchars($row['channel_name']); ?></p>
|
|
||||||
<p class="text-sm text-gray-400">
|
|
||||||
<?php echo htmlspecialchars(formatViews($row['views'])); ?> views •
|
|
||||||
<?php echo htmlspecialchars(timeAgo($row['uploaded_at'])); ?>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
endwhile;
|
|
||||||
else:
|
|
||||||
echo "<p class='text-gray-400'>No videos found.</p>";
|
|
||||||
endif;
|
|
||||||
?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<!-- Scripts -->
|
|
||||||
<script src="assets/js/navbar_config.js"></script>
|
|
||||||
<script src="assets/js/sidebar_config.js"></script>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
// Error reporting
|
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('display_startup_errors', 1);
|
ini_set('display_startup_errors', 1);
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
// Application includes
|
include './pages/dashboard.php';
|
||||||
include 'home.php';
|
|
||||||
?>
|
?>
|
||||||
393
src/pages/account.php
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
include './../core/init.php';
|
||||||
|
include './../core/connection.php';
|
||||||
|
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
error_reporting(0);
|
||||||
|
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
header("Location: ./../index.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = $_SESSION['user_id'] ?? null;
|
||||||
|
if (!$user_id) {
|
||||||
|
header("Location: ./../index.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$username = 'Unknown';
|
||||||
|
$email = 'Unknown';
|
||||||
|
$is_admin = false;
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("SELECT username, email, is_admin FROM users WHERE id = ? LIMIT 1");
|
||||||
|
if ($stmt) {
|
||||||
|
$stmt->bind_param("i", $user_id);
|
||||||
|
$stmt->execute();
|
||||||
|
$stmt->bind_result($db_username, $db_email, $db_is_admin);
|
||||||
|
if ($stmt->fetch()) {
|
||||||
|
$username = $db_username;
|
||||||
|
$email = $db_email;
|
||||||
|
$is_admin = ((int) $db_is_admin === 1);
|
||||||
|
}
|
||||||
|
$stmt->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
$email_initial = strtoupper(substr($email, 0, 1));
|
||||||
|
|
||||||
|
$helpdesk_email = $_ENV['HELPDESK_EMAIL'];
|
||||||
|
$helpdesk_phone = $_ENV['HELPDESK_PHONE'];
|
||||||
|
|
||||||
|
$management_email = $_ENV['MANAGEMENT_EMAIL'];
|
||||||
|
$management_phone = $_ENV['MANAGEMENT_PHONE'];
|
||||||
|
|
||||||
|
$health_email = $_ENV['HEALTH_EMAIL'];
|
||||||
|
$health_phone = $_ENV['HEALTH_PHONE'];
|
||||||
|
|
||||||
|
$library_email = $_ENV['LIBRARY_EMAIL'];
|
||||||
|
$library_phone = $_ENV['LIBRARY_PHONE'];
|
||||||
|
|
||||||
|
$security_email = $_ENV['SECURITY_EMAIL'];
|
||||||
|
$security_phone = $_ENV['SECURITY_PHONE'];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100..900&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<title><?php echo htmlspecialchars(($_ENV['DOMAIN']) . ' - Account'); ?></title>
|
||||||
|
|
||||||
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-neutral-900 text-gray-200 min-h-screen flex flex-col antialiased selection:bg-blue-500/30"
|
||||||
|
style="font-family: 'Lexend Deca', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;">
|
||||||
|
|
||||||
|
<div class="h-[140px] md:h-[150px] w-full bg-neutral-900 relative overflow-hidden border-b border-neutral-800">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="absolute top-4 left-4 md:top-6 md:left-6 z-20">
|
||||||
|
<button onclick="window.location.href='./../index.php';" class="group flex items-center gap-2 px-4 py-2 bg-blue-500/10 backdrop-blur-xl
|
||||||
|
border border-blue-500/40 rounded-xl text-sm text-neutral-300
|
||||||
|
hover:text-white hover:bg-blue-500/20
|
||||||
|
transition-all duration-300 active:scale-95">
|
||||||
|
<svg class="w-4 h-4 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||||
|
</svg>
|
||||||
|
Dashboard
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-1 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 -mt-12 md:-mt-20 relative z-10 pb-12">
|
||||||
|
|
||||||
|
<div class="flex flex-col md:flex-row items-center md:items-end gap-4 md:gap-8 mb-8 md:mb-12">
|
||||||
|
|
||||||
|
<div class="relative shrink-0 group">
|
||||||
|
<div
|
||||||
|
class="w-28 h-28 md:w-44 md:h-44 rounded-full bg-neutral-900 border-4 md:border-[6px] border-neutral-900 shadow-2xl flex items-center justify-center relative overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="absolute inset-0 bg-gradient-to-tr from-neutral-800 via-neutral-700 to-neutral-600 group-hover:scale-110 transition-transform duration-700">
|
||||||
|
</div>
|
||||||
|
<span class="relative z-10 text-4xl md:text-6xl font-bold text-white drop-shadow-lg">
|
||||||
|
<?php echo $email_initial; ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="absolute bottom-1 right-1 md:bottom-3 md:right-3 bg-neutral-900 rounded-full p-1 md:p-1.5">
|
||||||
|
<div
|
||||||
|
class="w-4 h-4 md:w-6 md:h-6 bg-green-500 rounded-full border-2 md:border-[3px] border-neutral-900 flex items-center justify-center shadow-lg shadow-green-500/50">
|
||||||
|
<div class="w-1.5 h-1.5 md:w-2 md:h-2 bg-white rounded-full opacity-70 animate-pulse"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-1 w-full text-center md:text-left pb-0 md:pb-4">
|
||||||
|
<h1 class="text-2xl md:text-5xl font-bold text-white tracking-tight mb-3 break-all md:break-normal">
|
||||||
|
<?php echo htmlspecialchars($email); ?>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap items-center justify-center md:justify-start gap-2 md:gap-3">
|
||||||
|
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full border bg-green-500/10 border-green-500/20 text-green-400 text-[10px] md:text-xs font-bold uppercase tracking-wider backdrop-blur-md">
|
||||||
|
<svg class="w-3 h-3 md:w-3.5 md:h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
Verified
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full md:w-auto pb-0 md:pb-4 mt-2 md:mt-0">
|
||||||
|
<form method="get" action="">
|
||||||
|
<button type="submit" name="action" value="logout"
|
||||||
|
class="w-full md:w-auto flex items-center justify-center gap-2 px-6 py-3 rounded-xl bg-red-500/10 text-red-400 border border-red-500/20 hover:bg-red-500/80 hover:text-white hover:shadow-lg hover:shadow-red-500/20 transition-all duration-300 font-medium text-sm active:scale-95">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
||||||
|
</svg>
|
||||||
|
Sign Out
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 xl:grid-cols-3 gap-6 md:gap-8">
|
||||||
|
|
||||||
|
<div class="xl:col-span-2 space-y-6">
|
||||||
|
<div
|
||||||
|
class="bg-neutral-900/60 backdrop-blur-xl border border-neutral-800 rounded-2xl p-5 md:p-8 shadow-xl relative overflow-hidden h-full">
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 w-full h-0.5 bg-gradient-to-r from-blue-500 via-neutral-600 to-transparent">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between mb-6">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-lg md:text-xl font-bold text-white">Your Identification</h2>
|
||||||
|
<p class="text-xs text-neutral-400 mt-1">View the University credentials & access details
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-2 bg-neutral-800/50 rounded-lg border border-neutral-700/50">
|
||||||
|
<svg class="w-5 h-5 md:w-6 md:h-6 text-blue-400" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-4 0V5a2 2 0 114 0v1m-4 0c0 .6.4 1 1 1 1 1 0 0 1 1 1v3" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-5">
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<label
|
||||||
|
class="block text-[10px] font-bold text-neutral-500 uppercase tracking-widest mb-1.5 ml-1">Username/
|
||||||
|
University ID/ Student ID</label>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="relative flex-1 min-w-0">
|
||||||
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<svg class="w-4 h-4 text-blue-400 transition-colors" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="w-full bg-black/40 border border-neutral-800 text-neutral-200 text-sm rounded-xl py-3.5 pl-9 pr-4 font-mono truncate group-hover:border-neutral-700 transition-colors">
|
||||||
|
<?php echo htmlspecialchars($username); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="btn-user"
|
||||||
|
onclick="copyToClipboard('<?php echo htmlspecialchars($username, ENT_QUOTES); ?>', 'btn-user')"
|
||||||
|
class="shrink-0 p-3.5 bg-neutral-800 border border-neutral-700 rounded-xl text-neutral-400 hover:text-white hover:bg-neutral-700 hover:border-neutral-600 transition-all shadow-sm active:scale-95"
|
||||||
|
title="Copy ID">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<label
|
||||||
|
class="block text-[10px] font-bold text-neutral-500 uppercase tracking-widest mb-1.5 ml-1">Authenticated
|
||||||
|
Email Address</label>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="relative flex-1 min-w-0">
|
||||||
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||||
|
<svg class="w-4 h-4 text-blue-400 transition-colors" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="w-full bg-black/40 border border-neutral-800 text-neutral-200 text-sm rounded-xl py-3.5 pl-9 pr-4 font-mono truncate group-hover:border-neutral-700 transition-colors">
|
||||||
|
<?php echo htmlspecialchars($email); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="btn-email"
|
||||||
|
onclick="copyToClipboard('<?php echo htmlspecialchars($email, ENT_QUOTES); ?>', 'btn-email')"
|
||||||
|
class="shrink-0 p-3.5 bg-neutral-800 border border-neutral-700 rounded-xl text-neutral-400 hover:text-white hover:bg-neutral-700 hover:border-neutral-600 transition-all shadow-sm active:scale-95"
|
||||||
|
title="Copy Email">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 pt-2">
|
||||||
|
<div
|
||||||
|
class="p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 flex items-center justify-between group hover:border-green-500/20 transition-colors">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p class="text-[10px] text-neutral-500 uppercase font-bold">Account Status</p>
|
||||||
|
<p class="text-xs font-semibold text-neutral-200 mt-1">
|
||||||
|
Activated
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<svg class="w-5 h-5 text-green-400 drop-shadow-[0_0_6px_rgba(34,197,94,0.45)]"
|
||||||
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 flex items-center justify-between group hover:border-blue-500/20 transition-colors">
|
||||||
|
<div>
|
||||||
|
<p class="text-[10px] text-neutral-500 uppercase font-bold">CAMPUS ROLE</p>
|
||||||
|
<p class="text-xs font-semibold text-white mt-1">
|
||||||
|
<?php echo $is_admin ? 'Administrator' : 'Student'; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<svg class="w-5 h-5 text-blue-400 opacity-90 transition-colors" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-3">
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="group flex items-center gap-4 p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 hover:border-blue-500/30 hover:bg-neutral-800/50 transition-all duration-300">
|
||||||
|
<div
|
||||||
|
class="p-2.5 bg-blue-500/10 rounded-lg text-blue-400 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p
|
||||||
|
class="text-xs font-bold text-white uppercase tracking-wide group-hover:text-blue-400 transition-colors">
|
||||||
|
IT Helpdesk Support</p>
|
||||||
|
<div class="text-[10px] text-neutral-400 mt-0.5">
|
||||||
|
<p><?php echo htmlspecialchars($helpdesk_email); ?></p>
|
||||||
|
<p><?php echo htmlspecialchars($helpdesk_phone); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="group flex items-center gap-4 p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 hover:border-purple-500/30 hover:bg-neutral-800/50 transition-all duration-300">
|
||||||
|
<div
|
||||||
|
class="p-2.5 bg-purple-500/10 rounded-lg text-purple-400 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p
|
||||||
|
class="text-xs font-bold text-white uppercase tracking-wide group-hover:text-purple-400 transition-colors">
|
||||||
|
Management Support</p>
|
||||||
|
<div class="text-[10px] text-neutral-400 mt-0.5">
|
||||||
|
<p><?php echo htmlspecialchars($management_email); ?></p>
|
||||||
|
<p><?php echo htmlspecialchars($management_phone); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="group flex items-center gap-4 p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 hover:border-emerald-500/30 hover:bg-neutral-800/50 transition-all duration-300">
|
||||||
|
<div
|
||||||
|
class="p-2.5 bg-emerald-500/10 rounded-lg text-emerald-400 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p
|
||||||
|
class="text-xs font-bold text-white uppercase tracking-wide group-hover:text-emerald-400 transition-colors">
|
||||||
|
Health & Food Support</p>
|
||||||
|
<div class="text-[10px] text-neutral-400 mt-0.5">
|
||||||
|
<p><?php echo htmlspecialchars($health_email); ?></p>
|
||||||
|
<p><?php echo htmlspecialchars($health_phone); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="group flex items-center gap-4 p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 hover:border-amber-500/30 hover:bg-neutral-800/50 transition-all duration-300">
|
||||||
|
<div
|
||||||
|
class="p-2.5 bg-amber-500/10 rounded-lg text-amber-400 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p
|
||||||
|
class="text-xs font-bold text-white uppercase tracking-wide group-hover:text-amber-400 transition-colors">
|
||||||
|
Library & Books Support</p>
|
||||||
|
<div class="text-[10px] text-neutral-400 mt-0.5">
|
||||||
|
<p><?php echo htmlspecialchars($library_email); ?></p>
|
||||||
|
<p><?php echo htmlspecialchars($library_phone); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="group flex items-center gap-4 p-4 rounded-xl bg-neutral-800/30 border border-neutral-800 hover:border-red-500/30 hover:bg-neutral-800/50 transition-all duration-300">
|
||||||
|
<div class="p-2.5 bg-red-500/10 rounded-lg text-red-400 group-hover:scale-110 transition-transform">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<p
|
||||||
|
class="text-xs font-bold text-white uppercase tracking-wide group-hover:text-red-400 transition-colors">
|
||||||
|
Campus Security Support</p>
|
||||||
|
<div class="text-[10px] text-neutral-400 mt-0.5">
|
||||||
|
<p><?php echo htmlspecialchars($security_email); ?></p>
|
||||||
|
<p><?php echo htmlspecialchars($security_phone); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script src="./../assets/js/account_config.js"></script>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
@@ -54,15 +54,15 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -73,7 +73,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -84,7 +84,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<!-- Left Section -->
|
<!-- Left Section -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('create_an_account'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('create_an_account'); ?></h1>
|
||||||
@@ -195,6 +195,6 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="assets/js/create_account_config.js"></script>
|
<script src="./../assets/js/create_account_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
@@ -69,7 +69,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($error) && isset($_POST['pass
|
|||||||
if ($stmt) {
|
if ($stmt) {
|
||||||
$stmt->bind_param("ssiss", $username, $email, $age, $gender, $password_hash);
|
$stmt->bind_param("ssiss", $username, $email, $age, $gender, $password_hash);
|
||||||
if ($stmt->execute()) {
|
if ($stmt->execute()) {
|
||||||
include './core/auth/mail/create_account_config.php';
|
include './../core/auth/mail/create_account_config.php';
|
||||||
sendAccountCreationMail($email, $username);
|
sendAccountCreationMail($email, $username);
|
||||||
|
|
||||||
unset($_SESSION['signup']);
|
unset($_SESSION['signup']);
|
||||||
@@ -99,15 +99,15 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA -->
|
<!-- Favicon & PWA -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- TailwindCSS -->
|
<!-- TailwindCSS -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts -->
|
<!-- Google Fonts -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -118,7 +118,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit -->
|
<!-- Debug Kit -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -128,7 +128,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<!-- Left -->
|
<!-- Left -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('create_password_title'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('create_password_title'); ?></h1>
|
||||||
@@ -218,6 +218,6 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="assets/js/create_account_config.js"></script>
|
<script src="./../assets/js/create_account_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
65
src/pages/dashboard.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
// Initialize the application
|
||||||
|
include './core/init.php';
|
||||||
|
include './core/router.php';
|
||||||
|
|
||||||
|
// Suppress all PHP errors in production environment
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
ini_set('display_startup_errors', 0);
|
||||||
|
error_reporting(0);
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<!-- Meta & Viewport Configuration -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<!-- Favicon & PWA Assets -->
|
||||||
|
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
||||||
|
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
||||||
|
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
|
<link rel="stylesheet" href="./src/output.css">
|
||||||
|
|
||||||
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100..900&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Dynamic Page Title (from .env DOMAIN variable) -->
|
||||||
|
<title><?php echo htmlspecialchars($_ENV['DOMAIN'] . ' - Dashboard'); ?></title>
|
||||||
|
|
||||||
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
|
<?php include './assets/_debug_kit.php'; ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body class="bg-neutral-900 text-gray-200 antialiased">
|
||||||
|
<?php include './assets/_navbar.php'; ?>
|
||||||
|
|
||||||
|
<div class="flex h-screen overflow-hidden">
|
||||||
|
|
||||||
|
|
||||||
|
<?php include './assets/_sidebar.php'; ?>
|
||||||
|
|
||||||
|
<main class="flex-1 overflow-y-auto p-6">
|
||||||
|
<div class="max-w-7xl mx-auto space-y-6">
|
||||||
|
<?php include $current_route['file']; ?>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./assets/js/dashboard_config.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
406
src/pages/error/404.php
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
<?php
|
||||||
|
include './../../core/init.php';
|
||||||
|
?>
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>Service Paused - <?php echo htmlspecialchars($_ENV['DOMAIN']); ?></title>
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="./../../assets/favicon/favicon-96x96.png" sizes="96x96">
|
||||||
|
<link rel="icon" type="image/svg+xml" href="./../../assets/favicon/favicon.svg">
|
||||||
|
<link rel="shortcut icon" href="./../../assets/favicon/favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="./../../assets/favicon/apple-touch-icon.png">
|
||||||
|
<link rel="manifest" href="./../../assets/favicon/site.webmanifest">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./../../assets/css/error_config.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@300;400;600;700&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
:root{
|
||||||
|
--eerie-black:#060b14;
|
||||||
|
--pure-white:#ffffff;
|
||||||
|
--neon-sky:#37bbf9;
|
||||||
|
--neon-sky-translucent:rgba(55,187,249,0.2745098039);
|
||||||
|
--neon-sky-glow-weak:rgba(55,187,249,0.18);
|
||||||
|
--neon-sky-glow-mid:rgba(55,187,249,0.28);
|
||||||
|
--neon-sky-pressed:rgba(55,187,249,0.2745098039);
|
||||||
|
--transparent-dark:rgba(6,11,20,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*,*:before,*:after{box-sizing:border-box;}
|
||||||
|
*{-webkit-tap-highlight-color:rgba(0,0,0,0);transform-style:preserve-3d;}
|
||||||
|
*:focus{outline:none!important;}
|
||||||
|
|
||||||
|
body,html{height:100%;margin:0;}
|
||||||
|
body{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
align-content:center;
|
||||||
|
justify-content:center;
|
||||||
|
padding:12px;
|
||||||
|
background:var(--eerie-black);
|
||||||
|
color:var(--pure-white);
|
||||||
|
font-family:"Lexend Deca", sans-serif;
|
||||||
|
font-feature-settings:"liga","ss05" on,"ss07" on;
|
||||||
|
font-size:24px;
|
||||||
|
text-rendering:optimizeLegibility;
|
||||||
|
-webkit-font-smoothing:antialiased;
|
||||||
|
overflow-x:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection{background:none;}
|
||||||
|
|
||||||
|
.return-btn{
|
||||||
|
font:inherit;
|
||||||
|
background:none;
|
||||||
|
border:none;
|
||||||
|
color:var(--pure-white);
|
||||||
|
text-align:left;
|
||||||
|
cursor:pointer;
|
||||||
|
padding:0;
|
||||||
|
transition:color 150ms ease,text-shadow 150ms ease,opacity 120ms ease;
|
||||||
|
animation:return-blink 2.4s ease-in-out infinite;
|
||||||
|
animation-play-state:running;
|
||||||
|
}
|
||||||
|
|
||||||
|
.return-btn:hover,
|
||||||
|
.return-btn:focus,
|
||||||
|
.return-btn:focus-visible{
|
||||||
|
color:var(--neon-sky);
|
||||||
|
animation:none!important;
|
||||||
|
animation-play-state:paused!important;
|
||||||
|
opacity:1!important;
|
||||||
|
text-shadow:0 0 10px var(--neon-sky-glow-mid);
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg{width:70px;height:auto;}
|
||||||
|
|
||||||
|
.crack{position:relative;z-index:4;margin-left:-46px;}
|
||||||
|
.crack polyline{
|
||||||
|
fill:none;
|
||||||
|
stroke:var(--neon-sky);
|
||||||
|
stroke-width:10px;
|
||||||
|
stroke-linecap:round;
|
||||||
|
stroke-linejoin:round;
|
||||||
|
stroke-dasharray:1649.099;
|
||||||
|
stroke-dashoffset:1649.099;
|
||||||
|
animation:drawStroke 1500ms ease-out 500ms forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
main{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
align-content:center;
|
||||||
|
justify-content:center;
|
||||||
|
width:100%;
|
||||||
|
max-width:100vw;
|
||||||
|
}
|
||||||
|
main>div{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
align-content:center;
|
||||||
|
position:relative;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
main>div svg{position:relative;z-index:1;}
|
||||||
|
main>div svg polygon{fill:var(--eerie-black);}
|
||||||
|
main>div span{
|
||||||
|
display:block;
|
||||||
|
position:relative;
|
||||||
|
z-index:0;
|
||||||
|
padding:0 12px;
|
||||||
|
line-height:1.4;
|
||||||
|
}
|
||||||
|
main>div:first-child{text-align:right;z-index:1;}
|
||||||
|
main>div:first-child span:first-child{
|
||||||
|
opacity:0;
|
||||||
|
transform:translateX(100%);
|
||||||
|
animation:translateLeft 1000ms linear 1250ms forwards;
|
||||||
|
}
|
||||||
|
main>div:first-child span:last-child{
|
||||||
|
opacity:0;
|
||||||
|
transform:translateX(100%);
|
||||||
|
animation:translateLeft 1000ms linear 1450ms forwards;
|
||||||
|
}
|
||||||
|
main>div:first-child svg polygon{
|
||||||
|
animation:removeFill 10ms ease-out 1600ms forwards;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
z-index:0;
|
||||||
|
margin-left:-50px;
|
||||||
|
}
|
||||||
|
main>div:last-child span:first-child{
|
||||||
|
opacity:0;
|
||||||
|
transform:translateX(-100%);
|
||||||
|
animation:translateRight 1000ms linear 1650ms forwards;
|
||||||
|
}
|
||||||
|
main>div:last-child span:last-child{
|
||||||
|
opacity:0;
|
||||||
|
transform:translateX(-100%);
|
||||||
|
animation:translateRight 1000ms linear 1850ms forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes drawStroke{
|
||||||
|
0%{stroke-dashoffset:1649.099;}
|
||||||
|
100%{stroke-dashoffset:0;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes removeFill{
|
||||||
|
0%{fill:var(--eerie-black);}
|
||||||
|
100%{fill:var(--transparent-dark);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulseColor{
|
||||||
|
0%{color:var(--pure-white);}
|
||||||
|
25%{color:var(--neon-sky-translucent);}
|
||||||
|
50%{color:var(--pure-white);}
|
||||||
|
75%{color:var(--neon-sky-translucent);}
|
||||||
|
100%{color:var(--pure-white);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes translateLeft{
|
||||||
|
0%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,150,0,0,1);opacity:1;}
|
||||||
|
7.61%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,69.561,0,0,1);}
|
||||||
|
11.41%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,39.355,0,0,1);}
|
||||||
|
15.12%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,17.801,0,0,1);}
|
||||||
|
18.92%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,3.02,0,0,1);}
|
||||||
|
22.72%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-5.661,0,0,1);}
|
||||||
|
30.23%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-10.852,0,0,1);}
|
||||||
|
50.25%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-2.282,0,0,1);}
|
||||||
|
70.27%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0.519,0,0,1);}
|
||||||
|
100%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);opacity:1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes translateRight{
|
||||||
|
0%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-150,0,0,1);opacity:1;}
|
||||||
|
7.61%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-69.561,0,0,1);}
|
||||||
|
11.41%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-39.355,0,0,1);}
|
||||||
|
15.12%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-17.801,0,0,1);}
|
||||||
|
18.92%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-3.02,0,0,1);}
|
||||||
|
22.72%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,5.661,0,0,1);}
|
||||||
|
30.23%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,10.852,0,0,1);}
|
||||||
|
50.25%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,2.282,0,0,1);}
|
||||||
|
70.27%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,-0.519,0,0,1);}
|
||||||
|
100%{transform:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);opacity:1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes return-blink{
|
||||||
|
0%{opacity:1;text-shadow:none;}
|
||||||
|
40%{opacity:.62;text-shadow:0 0 6px #37bbf949;}
|
||||||
|
60%{opacity:.92;text-shadow:0 0 10px #37bbf949;}
|
||||||
|
100%{opacity:1;text-shadow:none;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:1024px){
|
||||||
|
body{
|
||||||
|
font-size:22px;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:64px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-44px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-46px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 12px;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:22px;
|
||||||
|
padding:4px 0;
|
||||||
|
line-height:1.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:768px){
|
||||||
|
body{
|
||||||
|
font-size:20px;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:58px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-40px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-42px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 10px;
|
||||||
|
line-height:1.35;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:600px){
|
||||||
|
body{
|
||||||
|
font-size:18px;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
transform:scale(1.1);
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:54px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-38px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-40px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 10px;
|
||||||
|
line-height:1.3;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:480px){
|
||||||
|
body{
|
||||||
|
font-size:17px;
|
||||||
|
padding:8px;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
transform:scale(1.05);
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:50px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-36px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-38px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 8px;
|
||||||
|
line-height:1.3;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:400px){
|
||||||
|
body{
|
||||||
|
font-size:16px;
|
||||||
|
padding:8px;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
transform:scale(1.0);
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:46px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-34px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-36px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 8px;
|
||||||
|
line-height:1.25;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:360px){
|
||||||
|
body{
|
||||||
|
font-size:15px;
|
||||||
|
padding:6px;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
transform:scale(0.95);
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:42px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-32px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-34px;
|
||||||
|
}
|
||||||
|
main>div span{
|
||||||
|
padding:0 6px;
|
||||||
|
line-height:1.25;
|
||||||
|
}
|
||||||
|
.return-btn{
|
||||||
|
font-size:15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height:500px) and (orientation:landscape){
|
||||||
|
body{
|
||||||
|
font-size:14px;
|
||||||
|
padding:6px;
|
||||||
|
}
|
||||||
|
main{
|
||||||
|
transform:scale(0.85);
|
||||||
|
}
|
||||||
|
svg{
|
||||||
|
width:38px;
|
||||||
|
}
|
||||||
|
.crack{
|
||||||
|
margin-left:-28px;
|
||||||
|
}
|
||||||
|
main>div:last-child{
|
||||||
|
margin-left:-30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="body-font">
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
<div><span>404 error</span><span>page not found</span></div>
|
||||||
|
<svg viewBox="0 0 200 600">
|
||||||
|
<polygon
|
||||||
|
points="118.302698 8 59.5369448 66.7657528 186.487016 193.715824 14 366.202839 153.491505 505.694344 68.1413353 591.044514 200 591.044514 200 8">
|
||||||
|
</polygon>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<svg class="crack" viewBox="0 0 200 600">
|
||||||
|
<polyline
|
||||||
|
points="118.302698 8 59.5369448 66.7657528 186.487016 193.715824 14 366.202839 153.491505 505.694344 68.1413353 591.044514">
|
||||||
|
</polyline>
|
||||||
|
</svg>
|
||||||
|
<div>
|
||||||
|
<svg viewBox="0 0 200 600">
|
||||||
|
<polygon
|
||||||
|
points="118.302698 8 59.5369448 66.7657528 186.487016 193.715824 14 366.202839 153.491505 505.694344 68.1413353 591.044514 0 591.044514 0 8">
|
||||||
|
</polygon>
|
||||||
|
</svg>
|
||||||
|
<div><span>sorry about that!</span>
|
||||||
|
<span>
|
||||||
|
<button class="return-btn" onclick="window.location.href='./../../index.php'">
|
||||||
|
return home?
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -16,15 +16,15 @@ include './core/init.php';
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -35,14 +35,14 @@ include './core/init.php';
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
<!-- Includes -->
|
<!-- Includes -->
|
||||||
<?php include './core/connection.php'; ?>
|
<?php include './../core/connection.php'; ?>
|
||||||
<?php include './core/languages/language_config.php';?>
|
<?php include './../core/languages/language_config.php';?>
|
||||||
<?php include './core/feedback/mail/feedback_config.php';?>
|
<?php include './../core/feedback/mail/feedback_config.php';?>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Handles the language selection
|
// Handles the language selection
|
||||||
@@ -79,7 +79,7 @@ include './core/init.php';
|
|||||||
<!-- Left -->
|
<!-- Left -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900" alt="xovae-logo" />
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900" alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2">Language Support</h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2">Language Support</h1>
|
||||||
<p class="text-gray-400">
|
<p class="text-gray-400">
|
||||||
@@ -3,16 +3,16 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('display_startup_errors', 0);
|
ini_set('display_startup_errors', 0);
|
||||||
error_reporting(0);
|
error_reporting(0);
|
||||||
|
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
include './core/forgot/mail/forgot_email_config.php';
|
include './../core/forgot/mail/forgot_email_config.php';
|
||||||
|
|
||||||
// Handle language selection
|
// Handle language selection
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_array($_POST['language'], $languages, true)) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_array($_POST['language'], $languages, true)) {
|
||||||
@@ -89,15 +89,15 @@ if (!empty($_SESSION['forgot_success'])) {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -108,7 +108,7 @@ if (!empty($_SESSION['forgot_success'])) {
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -118,7 +118,7 @@ if (!empty($_SESSION['forgot_success'])) {
|
|||||||
<!-- Left -->
|
<!-- Left -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('find_email_title'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('find_email_title'); ?></h1>
|
||||||
@@ -208,6 +208,7 @@ if (!empty($_SESSION['forgot_success'])) {
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="./assets/js/forgot_email_config.js"></script>
|
<script src="./../assets/js/forgot_email_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
include './core/auth/mail/forgot_password_config.php'; // sendPasswordResetSuccessMail() - success mail
|
include './../core/auth/mail/forgot_password_config.php'; // sendPasswordResetSuccessMail() - success mail
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
@@ -297,15 +297,15 @@ if (
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -316,7 +316,7 @@ if (
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -326,7 +326,7 @@ if (
|
|||||||
<!-- Left Side Content -->
|
<!-- Left Side Content -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('reset_password_title'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('reset_password_title'); ?></h1>
|
||||||
@@ -436,6 +436,6 @@ if (
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="assets/js/forgot_password_config.js"></script>
|
<script src="./../assets/js/forgot_password_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
@@ -34,7 +34,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['input'])) {
|
|||||||
$stmt->fetch();
|
$stmt->fetch();
|
||||||
|
|
||||||
$_SESSION['signin_email'] = $email;
|
$_SESSION['signin_email'] = $email;
|
||||||
header('Location: sign_in_password.php');
|
header('Location: ./sign_in_password.php');
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
$error = t('account_not_found');
|
$error = t('account_not_found');
|
||||||
@@ -69,15 +69,15 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
@@ -88,7 +88,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -99,7 +99,7 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
<!-- Left Side -->
|
<!-- Left Side -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('sign_in'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('sign_in'); ?></h1>
|
||||||
@@ -189,6 +189,6 @@ if (empty($current_texts) && !empty($languages)) {
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="assets/js/sign_in_config.js"></script>
|
<script src="./../assets/js/sign_in_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -2,11 +2,10 @@
|
|||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
include './core/init.php';
|
include './../core/init.php';
|
||||||
include './core/connection.php';
|
include './../core/connection.php';
|
||||||
include './core/languages/language_config.php';
|
include './../core/languages/language_config.php';
|
||||||
include './core/auth/mail/forgot_password_config.php';
|
include './../core/auth/mail/forgot_password_config.php';
|
||||||
|
|
||||||
// Suppress all PHP errors in production environment
|
// Suppress all PHP errors in production environment
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('display_startup_errors', 0);
|
ini_set('display_startup_errors', 0);
|
||||||
@@ -124,7 +123,7 @@ if (
|
|||||||
if (empty($password)) {
|
if (empty($password)) {
|
||||||
$error = t('empty_password_error');
|
$error = t('empty_password_error');
|
||||||
} else {
|
} else {
|
||||||
$stmt = $conn->prepare("SELECT id, password_hash FROM users WHERE email = ? LIMIT 1");
|
$stmt = $conn->prepare(" SELECT id, password_hash, is_admin FROM users WHERE email = ? LIMIT 1 ");
|
||||||
|
|
||||||
if (!$stmt) {
|
if (!$stmt) {
|
||||||
$error = t('database_prepare_failed');
|
$error = t('database_prepare_failed');
|
||||||
@@ -134,13 +133,14 @@ if (
|
|||||||
$stmt->store_result();
|
$stmt->store_result();
|
||||||
|
|
||||||
if ($stmt->num_rows > 0) {
|
if ($stmt->num_rows > 0) {
|
||||||
$stmt->bind_result($user_id, $hashed_password);
|
$stmt->bind_result($user_id, $hashed_password, $is_admin);
|
||||||
$stmt->fetch();
|
$stmt->fetch();
|
||||||
|
|
||||||
if (password_verify($password, $hashed_password)) {
|
if (password_verify($password, $hashed_password)) {
|
||||||
$_SESSION['user_id'] = $user_id;
|
$_SESSION['user_id'] = $user_id;
|
||||||
$_SESSION['logged_in'] = true;
|
$_SESSION['logged_in'] = true;
|
||||||
$_SESSION['user_email'] = $email;
|
$_SESSION['user_email'] = $email;
|
||||||
|
$_SESSION['is_admin'] = (bool) $is_admin;
|
||||||
|
|
||||||
// Fetch username for display
|
// Fetch username for display
|
||||||
$user_stmt = $conn->prepare("SELECT username FROM users WHERE id = ? LIMIT 1");
|
$user_stmt = $conn->prepare("SELECT username FROM users WHERE id = ? LIMIT 1");
|
||||||
@@ -152,7 +152,7 @@ if (
|
|||||||
$user_stmt->close();
|
$user_stmt->close();
|
||||||
|
|
||||||
unset($_SESSION['signin_email']);
|
unset($_SESSION['signin_email']);
|
||||||
header('Location: home.php');
|
header('Location: ./../index.php');
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
$error = t('incorrect_password');
|
$error = t('incorrect_password');
|
||||||
@@ -184,16 +184,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_arr
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<!-- Favicon & PWA Assets -->
|
<!-- Favicon & PWA Assets -->
|
||||||
<link rel="icon" type="image/png" href="./assets/favicon/favicon-96x96.png" sizes="96x96" />
|
<link rel="icon" type="image/png" href="./../assets/favicon/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./../assets/favicon/favicon.svg" />
|
||||||
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" />
|
<link rel="shortcut icon" href="./../assets/favicon/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="./../assets/favicon/apple-touch-icon.png" />
|
||||||
<link rel="manifest" href="./assets/favicon/site.webmanifest" />
|
<link rel="manifest" href="./../assets/favicon/site.webmanifest" />
|
||||||
<meta name="apple-mobile-web-app-title" content="SteamsTube" />
|
<meta name="apple-mobile-web-app-title" content="<?php echo htmlspecialchars($_ENV['DOMAIN']); ?>" />
|
||||||
|
|
||||||
<!-- Main Stylesheet (Tailwind CSS) -->
|
<!-- Main Stylesheet (Tailwind CSS) -->
|
||||||
<link rel="stylesheet" href="./src/output.css">
|
<link rel="stylesheet" href="./../src/output.css">
|
||||||
|
|
||||||
<!-- Google Fonts: Lexend Deca -->
|
<!-- Google Fonts: Lexend Deca -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
@@ -203,7 +202,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_arr
|
|||||||
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
<title><?php echo htmlspecialchars(!empty($_ENV['DOMAIN']) ? $_ENV['DOMAIN'] : 'UNKNOWN DOMAIN'); ?></title>
|
||||||
|
|
||||||
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
<!-- Debug Kit: Optional outline borders (toggled via .env DEBUG_MODE) -->
|
||||||
<?php include 'assets/_debug_kit.php'; ?>
|
<?php include './../assets/_debug_kit.php'; ?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
<body class="bg-neutral-900 text-gray-200 flex items-center justify-center min-h-screen p-4">
|
||||||
@@ -214,7 +213,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_arr
|
|||||||
<!-- Left Side -->
|
<!-- Left Side -->
|
||||||
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
<div class="p-8 md:p-12 flex flex-col self-start text-center md:text-left items-center md:items-start">
|
||||||
<div class="flex items-center mb-6">
|
<div class="flex items-center mb-6">
|
||||||
<img src="./assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
<img src="./../assets/images/logos/xovae.svg" class="h-14 w-auto rounded-full bg-neutral-900"
|
||||||
alt="xovae-logo" />
|
alt="xovae-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('sign_in'); ?></h1>
|
<h1 class="text-3xl font-normal text-gray-200 mb-2"><?php echo t('sign_in'); ?></h1>
|
||||||
@@ -312,6 +311,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['language']) && in_arr
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="assets/js/sign_in_config.js"></script>
|
<script src="./../assets/js/sign_in_config.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||