Switch PHP views to Twig and add 2FA/UI enhancements
Migrate many view templates from raw PHP to Twig and modernize UI/UX for 2FA and settings. Controllers updated to provide avatar data and two-factor info (ProfileController, UserController) and SettingsController now includes timezone lists, notification preset selection, cron path, cached update state and rollback availability. ErrorHandler now attempts to render error pages via a new Core\TwigService with a safe fallback to raw PHP views. TwoFactorService generation silences deprecated warnings during QR code creation. Numerous .php view files were removed and replaced with .twig equivalents (2fa setup/verify/backup-codes and many auth, dashboard, domains, errors, layout, users, tags, tld-registry, etc.), and core/TwigService was added. These changes move the app toward a Twig-based templating system, improve 2FA flows, surface avatar images in lists/profiles, and make error rendering more robust.
This commit is contained in:
124
app/Views/layout/sidebar.twig
Normal file
124
app/Views/layout/sidebar.twig
Normal file
@@ -0,0 +1,124 @@
|
||||
{# Sidebar Navigation Partial #}
|
||||
<aside id="sidebar" class="sidebar fixed left-0 top-0 w-64 z-30
|
||||
bg-white dark:bg-slate-900
|
||||
border-r border-gray-200 dark:border-slate-800
|
||||
transition-colors duration-200">
|
||||
<div class="h-full overflow-y-auto flex flex-col">
|
||||
|
||||
{# Logo Section #}
|
||||
<div class="h-16 px-4 border-b border-gray-200 dark:border-slate-800 flex items-center justify-between">
|
||||
<a href="/" class="flex items-center gap-3">
|
||||
<img src="{{ base_url }}/assets/logo.svg" alt="{{ appSettings.app_name|default('Domain Monitor') }}" class="h-11 w-auto">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-base font-bold text-gray-800 dark:text-white tracking-tight leading-tight">{{ appSettings.app_name|default('Domain Monitor') }}</span>
|
||||
<span class="text-xs text-gray-400 dark:text-slate-500 font-medium">Track your domains</span>
|
||||
</div>
|
||||
</a>
|
||||
{# Mobile Close Button #}
|
||||
<button onclick="closeSidebar()" class="md:hidden flex items-center justify-center w-9 h-9 text-gray-500 hover:text-gray-700 hover:bg-gray-100 dark:text-slate-400 dark:hover:text-white dark:hover:bg-slate-800 rounded-lg transition-colors">
|
||||
<i class="fas fa-times text-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{# Navigation Links #}
|
||||
<nav class="px-3 py-4 flex-1">
|
||||
<div class="space-y-0.5">
|
||||
<a href="/" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active('/') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-chart-line text-sm mr-3 w-4 {{ is_active('/') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="/domains" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/domains') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-globe text-sm mr-3 w-4 {{ is_active_prefix('/domains') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Domains</span>
|
||||
</a>
|
||||
|
||||
<a href="/groups" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/groups') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-bell text-sm mr-3 w-4 {{ is_active_prefix('/groups') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Notification Groups</span>
|
||||
</a>
|
||||
|
||||
<a href="/tld-registry" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/tld-registry') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-database text-sm mr-3 w-4 {{ is_active_prefix('/tld-registry') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">TLD Registry</span>
|
||||
{% if session.role is defined and session.role != 'admin' %}
|
||||
<span class="ml-auto text-xs bg-gray-200 dark:bg-slate-700 px-1.5 py-0.5 rounded text-gray-500 dark:text-slate-400">View</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
|
||||
<a href="/tags" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/tags') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-tags text-sm mr-3 w-4 {{ is_active_prefix('/tags') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Tag Management</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{# Tools Section #}
|
||||
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-slate-800">
|
||||
<p class="text-xs font-semibold text-gray-400 dark:text-slate-500 uppercase tracking-wider px-3 mb-1.5">Tools</p>
|
||||
<div class="space-y-0.5">
|
||||
<a href="/debug/whois" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/debug/whois') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-search text-sm mr-3 w-4 {{ is_active_prefix('/debug/whois') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">WHOIS Lookup</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# System Section (Admin Only) #}
|
||||
{% if session.role is defined and session.role == 'admin' %}
|
||||
<div class="mt-4 pt-4 border-t border-gray-200 dark:border-slate-800">
|
||||
<p class="text-xs font-semibold text-gray-400 dark:text-slate-500 uppercase tracking-wider px-3 mb-1.5">System</p>
|
||||
<div class="space-y-0.5">
|
||||
<a href="/settings" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/settings') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-cog text-sm mr-3 w-4 {{ is_active_prefix('/settings') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Settings</span>
|
||||
</a>
|
||||
<a href="/users" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/users') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-users text-sm mr-3 w-4 {{ is_active_prefix('/users') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Users</span>
|
||||
</a>
|
||||
<a href="/errors" class="sidebar-link group flex items-center px-3 py-2 rounded-lg transition-all duration-200
|
||||
{{ is_active_prefix('/errors') ? 'bg-blue-50 dark:bg-slate-800 text-blue-700 dark:text-blue-400 font-medium' : 'text-gray-600 dark:text-slate-400 hover:bg-gray-100 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-white' }}">
|
||||
<i class="fas fa-bug text-sm mr-3 w-4 {{ is_active_prefix('/errors') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-slate-500 group-hover:text-blue-500 dark:group-hover:text-blue-400' }}"></i>
|
||||
<span class="text-sm">Error Logs</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</nav>
|
||||
|
||||
{# Quick Stats - Compact #}
|
||||
<div class="px-3 pb-2 border-t border-gray-200 dark:border-slate-800 pt-3">
|
||||
<div class="text-xs font-semibold text-gray-400 dark:text-slate-500 uppercase tracking-wider px-2 mb-2">Domain Stats</div>
|
||||
<div class="grid grid-cols-3 gap-1.5 px-1">
|
||||
<div class="bg-gray-50 dark:bg-slate-800 rounded-lg p-2 text-center">
|
||||
<div class="text-base font-bold text-gray-800 dark:text-white">{{ domainStats.total|default(0) }}</div>
|
||||
<div class="text-xs text-gray-400 dark:text-slate-500">Total</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 dark:bg-slate-800 rounded-lg p-2 text-center">
|
||||
<div class="text-base font-bold text-orange-500 dark:text-orange-400">{{ domainStats.expiring_soon|default(0) }}</div>
|
||||
<div class="text-xs text-gray-400 dark:text-slate-500" title="Within {{ domainStats.expiring_threshold|default(30) }} days">Expiring</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 dark:bg-slate-800 rounded-lg p-2 text-center">
|
||||
<div class="text-base font-bold text-emerald-500 dark:text-emerald-400">{{ domainStats.active|default(0) }}</div>
|
||||
<div class="text-xs text-gray-400 dark:text-slate-500">Active</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Footer #}
|
||||
<div class="px-4 py-3 border-t border-gray-200 dark:border-slate-800">
|
||||
<div class="text-center">
|
||||
<p class="text-xs text-gray-500 dark:text-slate-500">© {{ "now"|date("Y") }} <a href="https://github.com/Hosteroid/domain-monitor" target="_blank" class="text-gray-500 dark:text-slate-500 hover:text-blue-500 dark:hover:text-blue-400 transition-colors duration-150" title="Visit {{ appSettings.app_name|default('Domain Monitor') }} on GitHub">{{ appSettings.app_name|default('Domain Monitor') }}</a></p>
|
||||
<p class="text-xs text-gray-400 dark:text-slate-600 mt-0.5">v{{ appSettings.app_version|default(appVersion) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
Reference in New Issue
Block a user