185 lines
10 KiB
Plaintext
185 lines
10 KiB
Plaintext
<!DOCTYPE html>
|
|
<html class='h-full'>
|
|
<head>
|
|
<title>ReFurrer</title>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<% if Object.const_defined?("Rack::MiniProfiler") %>
|
|
<% # needed so miniprofiler doens't screw with the fetch() api %>
|
|
<script type='text/javascript'>
|
|
if(!window.MiniProfiler) {
|
|
window.MiniProfiler = {};
|
|
}
|
|
window.MiniProfiler.patchesApplied = true;
|
|
</script>
|
|
<% end %>
|
|
<link rel="icon" href="data:,">
|
|
<%= favicon_link_tag "refurrer-logo-icon.png", type: "image/png" %>
|
|
<%= csrf_meta_tags %>
|
|
<%= csp_meta_tag %>
|
|
<%= javascript_pack_tag "application-bundle" %>
|
|
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
|
|
<%= yield :head %>
|
|
</head>
|
|
<body class="mx-0 flex flex-col h-full">
|
|
<header class="bg-white border-b border-slate-200 shadow-sm top-0">
|
|
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div class="flex items-center justify-between h-16">
|
|
<!-- Logo and Brand -->
|
|
<div class="flex items-center">
|
|
<%= link_to root_path, class: "flex items-center space-x-2 hover:opacity-80 transition-opacity" do %>
|
|
<%= image_tag asset_path("refurrer-logo-md.png"), class: "w-8 h-8 sm:w-10 sm:h-10", alt: "ReFurrer Logo" %>
|
|
<div class="flex flex-col">
|
|
<span class="text-lg sm:text-xl font-bold text-slate-900 leading-tight">
|
|
ReFurrer
|
|
</span>
|
|
<span class="text-xs text-slate-500 font-medium hidden sm:block leading-tight">
|
|
Furry Swiss Army Knife
|
|
</span>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
<!-- User Menu (works for both desktop and mobile) -->
|
|
<div class="relative">
|
|
<% if user_signed_in? %>
|
|
<button type="button"
|
|
id="user-menu-button"
|
|
class="flex items-center space-x-2 rounded-md px-3 py-2 text-slate-600 transition-colors hover:bg-slate-50 hover:text-slate-900 touch-manipulation"
|
|
aria-controls="user-menu"
|
|
aria-expanded="false"
|
|
style="touch-action: manipulation; -webkit-touch-callout: none;">
|
|
<!-- User Avatar -->
|
|
<div class="flex h-8 w-8 items-center justify-center rounded-full bg-slate-600 text-sm font-medium text-white">
|
|
<%= current_user.email.first.upcase %>
|
|
</div>
|
|
<!-- Mobile: Show hamburger icon -->
|
|
<div class="sm:hidden">
|
|
<svg class="menu-icon block h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
</svg>
|
|
<svg class="close-icon hidden h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</div>
|
|
<!-- Desktop: Show chevron -->
|
|
<i class="chevron-icon hidden sm:block fas fa-chevron-down text-xs transition-transform"></i>
|
|
</button>
|
|
<!-- User Menu Dropdown -->
|
|
<div class="hidden fixed sm:absolute left-0 right-0 sm:left-auto z-10 sm:mt-4 sm:w-64 sm:rounded-lg bg-white py-2 shadow-lg border border-slate-200 opacity-0 -translate-y-2 transition-all duration-150 ease-out"
|
|
id="user-menu">
|
|
<!-- User Info Header -->
|
|
<div class="border-b border-slate-200 px-4 py-3 sm:py-3 max-sm:py-4">
|
|
<div class="flex items-center space-x-3">
|
|
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-slate-600 text-lg font-medium text-white">
|
|
<%= current_user.email.first.upcase %>
|
|
</div>
|
|
<div class="min-w-0 flex-1">
|
|
<div class="truncate text-sm font-medium text-slate-900">
|
|
<%= current_user.email %>
|
|
</div>
|
|
<% if current_user.role == 'admin' %>
|
|
<span class="mt-1 inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-red-100 text-red-800">
|
|
Administrator
|
|
</span>
|
|
<% elsif current_user.role == 'moderator' %>
|
|
<span class="mt-1 inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-800">
|
|
Moderator
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Admin Tools -->
|
|
<% if current_user.role == 'admin' %>
|
|
<div class="py-2">
|
|
<div class="px-4 py-2">
|
|
<div class="text-xs font-semibold uppercase tracking-wider text-slate-500">
|
|
Admin Tools
|
|
</div>
|
|
</div>
|
|
<%= link_to global_states_path, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-cogs mr-3 w-4 text-slate-400"></i>
|
|
<span>Global State</span>
|
|
<% end %>
|
|
<%= link_to good_job_path, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-tasks mr-3 w-4 text-slate-400"></i>
|
|
<span>Jobs Queue</span>
|
|
<% end %>
|
|
<%= link_to grafana_path, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-chart-line mr-3 w-4 text-slate-400"></i>
|
|
<span>Grafana</span>
|
|
<% end %>
|
|
<%= link_to prometheus_path, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-chart-bar mr-3 w-4 text-slate-400"></i>
|
|
<span>Prometheus</span>
|
|
<% end %>
|
|
<div class="my-2 border-t border-slate-200"></div>
|
|
</div>
|
|
<% end %>
|
|
<!-- User Options -->
|
|
<div class="py-2">
|
|
<%= link_to edit_user_registration_path, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-user-cog mr-3 w-4 text-slate-400"></i>
|
|
<span>Edit Profile</span>
|
|
<% end %>
|
|
<%= link_to destroy_user_session_path, method: :delete, class: "flex w-full items-center px-4 py-2 text-sm text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900" do %>
|
|
<i class="fas fa-sign-out-alt mr-3 w-4 text-slate-400"></i>
|
|
<span>Sign Out</span>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% else %>
|
|
<!-- Guest Navigation -->
|
|
<div class="flex items-center space-x-2">
|
|
<%= link_to new_user_session_path, class: "inline-flex items-center px-3 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded-md transition-colors" do %>
|
|
<i class="fas fa-sign-in-alt mr-2"></i>
|
|
<span class="hidden sm:inline">Sign In</span>
|
|
<span class="sm:hidden">Login</span>
|
|
<% end %>
|
|
<%= link_to new_user_registration_path, class: "inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors" do %>
|
|
<i class="fas fa-user-plus mr-2"></i>
|
|
<span class="hidden sm:inline">Sign Up</span>
|
|
<span class="sm:hidden">Join</span>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Debug Info Bar (shown only when applicable and in condensed form on mobile) -->
|
|
<% if policy(IpAddressRole).view_debug_info? %>
|
|
<div class="bg-slate-50 border-t border-slate-200 px-4 py-2">
|
|
<div class="mx-auto max-w-7xl">
|
|
<div class="flex flex-col sm:flex-row text-xs text-slate-600 gap-1 sm:gap-4">
|
|
<div class="flex">
|
|
<span class="font-medium">IP:</span>
|
|
<span class="font-mono truncate">2001:0db8:85a3:0000:0000:8a2e:0370:7334</span>
|
|
</div>
|
|
<div class="flex">
|
|
<%= link_to "Role", state_ip_address_roles_path, class: "text-blue-600 hover:text-blue-800 font-medium" %>
|
|
<span class="font-medium">:</span>
|
|
<span class="font-mono">
|
|
<% if role = current_ip_address_role %>
|
|
<%= role.ip_address %> / <%= role.role %>
|
|
<% else %>
|
|
None
|
|
<% end %>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</header>
|
|
<main class="flex flex-col grow bg-slate-200">
|
|
<% if notice %>
|
|
<p class="notice bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative" role="alert"><%= notice %></p>
|
|
<% end %>
|
|
<% if alert %>
|
|
<p class="alert bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert"><%= alert %></p>
|
|
<% end %>
|
|
<%= yield %>
|
|
</main>
|
|
</body>
|
|
</html>
|