Files
baffle-hub/app/views/layouts/application.html.erb
2025-11-10 14:10:37 +11:00

218 lines
9.3 KiB
Plaintext

<!DOCTYPE html>
<html class="bg-gray-50">
<head>
<title><%= content_for(:title) || "Baffle Hub - WAF Analytics" %></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="Baffle Hub">
<meta name="mobile-web-app-capable" content="yes">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= yield :head %>
<%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
<%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>
<link rel="icon" href="/icon.png" type="image/png">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icon.png">
<%# Includes all stylesheet files in app/assets/stylesheets %>
<%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<style>
/* Custom styles for code blocks and badges */
code {
@apply bg-gray-100 px-2 py-1 rounded text-sm font-mono;
}
/* Flash message transitions */
.flash-message {
animation: slideInDown 0.3s ease-out;
}
@keyframes slideInDown {
from {
transform: translateY(-100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
</style>
</head>
<body class="min-h-screen bg-gray-50">
<!-- Navigation Header -->
<header class="bg-gray-900 shadow-sm border-b border-gray-800">
<nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<!-- Logo and Main Navigation -->
<div class="flex items-center">
<!-- Logo -->
<%= link_to root_path, class: "flex-shrink-0 flex items-center" do %>
<svg class="h-8 w-8 text-blue-500 mr-3" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z"/>
</svg>
<span class="text-white text-lg font-bold">Baffle Hub</span>
<% end %>
<!-- Desktop Navigation -->
<div class="hidden md:block ml-10">
<div class="flex items-baseline space-x-4">
<%= link_to "🔴 Events", events_path,
class: nav_link_class(events_path) %>
<%= link_to "⚙️ Rules", rules_path,
class: nav_link_class(rules_path) %>
<%= link_to "🛡️ WAF Policies", waf_policies_path,
class: nav_link_class(waf_policies_path) %>
<%= link_to "🌐 Network Ranges", network_ranges_path,
class: nav_link_class(network_ranges_path) %>
<% if user_signed_in? && current_user_admin? %>
<%= link_to "🔗 DSNs", dsns_path,
class: nav_link_class(dsns_path) %>
<% end %>
</div>
</div>
</div>
<!-- Right side buttons -->
<div class="flex items-center space-x-4">
<% if user_signed_in? %>
<!-- User dropdown -->
<div class="relative" data-controller="dropdown">
<button type="button"
data-action="click->dropdown#toggle click@window->dropdown#hide"
class="flex items-center text-white hover:bg-gray-800 px-3 py-2 rounded-md text-sm font-medium">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
</svg>
<%= current_user.email_address %>
<span class="ml-2 px-2 py-0.5 text-xs rounded-full bg-blue-600 text-white">
<%= current_user.role %>
</span>
<svg class="w-4 h-4 ml-1" fill="currentColor" viewBox="0 0 24 24">
<path d="M7 10l5 5 5-5z"/>
</svg>
</button>
<!-- Dropdown menu -->
<div data-dropdown-target="menu"
class="hidden absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-50">
<div class="py-1">
<%= link_to edit_password_path,
class: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" do %>
⚙️ Account Settings
<% end %>
<% if current_user_admin? %>
<div class="border-t border-gray-100"></div>
<%= link_to users_path,
class: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" do %>
👥 Manage Users
<% end %>
<% end %>
<div class="border-t border-gray-100"></div>
<%= link_to session_path,
data: { turbo_method: :delete },
class: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" do %>
🚪 Sign Out
<% end %>
</div>
</div>
</div>
<% else %>
<% if User.none? %>
<%= link_to "👤 Create Admin Account", new_registration_path,
class: "bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md text-sm font-medium transition-colors" %>
<% else %>
<%= link_to "🔐 Sign In", new_session_path,
class: "bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md text-sm font-medium transition-colors" %>
<% end %>
<% end %>
<!-- Mobile menu button -->
<div class="md:hidden">
<button type="button"
data-controller="mobile-menu"
data-action="click->mobile-menu#toggle"
class="text-white hover:bg-gray-800 p-2 rounded-md">
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
<path data-mobile-menu-target="open" fill-rule="evenodd" d="M3 5h18v2H3V5zm0 6h18v2H3v-2zm0 6h18v2H3v-2z"/>
<path data-mobile-menu-target="close" class="hidden" fill-rule="evenodd" d="M18.278 16.864a1 1 0 01-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 01-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 011.414-1.414l4.829 4.828 4.828-4.828a1 1 0 111.414 1.414l-4.828 4.829 4.828 4.828z"/>
</svg>
</button>
</div>
</div>
</div>
<!-- Mobile menu -->
<div data-mobile-menu-target="menu" class="hidden md:hidden border-t border-gray-800">
<div class="px-2 pt-2 pb-3 space-y-1">
<%= link_to "🔴 Events", events_path,
class: mobile_nav_link_class(events_path) %>
<%= link_to "⚙️ Rules", rules_path,
class: mobile_nav_link_class(rules_path) %>
<%= link_to "🛡️ WAF Policies", waf_policies_path,
class: mobile_nav_link_class(waf_policies_path) %>
<%= link_to "🌐 Network Ranges", network_ranges_path,
class: mobile_nav_link_class(network_ranges_path) %>
<% if user_signed_in? && current_user_admin? %>
<%= link_to "🔗 DSNs", dsns_path,
class: mobile_nav_link_class(dsns_path) %>
<% end %>
</div>
</div>
</nav>
</header>
<!-- Flash Messages -->
<% if notice || alert %>
<div class="fixed top-20 left-0 right-0 z-50 px-4 py-2">
<% if notice %>
<div class="flash-message bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-md shadow-sm max-w-4xl mx-auto">
<div class="flex items-center">
<svg class="w-5 h-5 mr-2 text-green-600" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<%= notice %>
</div>
</div>
<% end %>
<% if alert %>
<div class="flash-message bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-md shadow-sm max-w-4xl mx-auto">
<div class="flex items-center">
<svg class="w-5 h-5 mr-2 text-red-600" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/>
</svg>
<%= alert %>
</div>
</div>
<% end %>
</div>
<% end %>
<!-- Main Content -->
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<%= yield %>
</main>
<!-- Footer -->
<footer class="bg-gray-900 text-gray-400 mt-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="text-center">
<p class="text-sm">© <%= Time.current.year %> Baffle Hub - WAF Analytics Platform</p>
</div>
</div>
</footer>
</body>
</html>