Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/agents/grafana.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Analyze and interpret Grafana logs, traces, and metrics using MCP Grafana server
tools: ['grafana/*', 'search', 'fetch']
model: Claude Sonnet 4.5 (copilot)
model: Claude Opus 4.5 (Preview) (copilot)
---

# Grafana Log & Trace Analyzer Mode
Expand Down
2 changes: 1 addition & 1 deletion .github/prompts/releasemanager.prompt.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
agent: agent
model: GPT-4.1 (copilot)
model: Claude Opus 4.5 (Preview) (copilot)
description: Generate release notes from a GitHub Pull Request URL
tools: [runCommands]
---
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
--resource-group deveats-wpc2025-rg \
--settings \
ConnectionStrings__DefaultConnection="${{ secrets.CONNECTION_STRING_TEST }}" \
ASPNETCORE_ENVIRONMENT="Production" \
ASPNETCORE_ENVIRONMENT="Test" \
OTEL_EXPORTER_OTLP_ENDPOINT="https://otlp-gateway-prod-eu-central-0.grafana.net/otlp" \
OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \
OTEL_RESOURCE_ATTRIBUTES="deployment.environment=test" \
Expand Down
199 changes: 166 additions & 33 deletions src/DevEats.Web/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
@inherits LayoutComponentBase
@inject IWebHostEnvironment Environment

<PageTitle>DevEats - Recensioni Ristoranti</PageTitle>

<div class="app-wrapper">
@if (!Environment.IsProduction())
{
@* Environment Warning Banner - Only shown in non-production environments *@
<div class="env-warning-banner" role="status" aria-live="polite" aria-atomic="true">
<div class="banner-content">
@* Accessibility: Icon is decorative, hidden from screen readers *@
<i class="bi bi-exclamation-triangle-fill banner-icon" aria-hidden="true"></i>
<div class="banner-text">
This is a <strong>@Environment.EnvironmentName.ToUpper()</strong> environment
</div>
</div>
</div>
}

@* Accessibility: Replaced inline style with CSS class for better maintainability *@
<div class="app-wrapper @(!Environment.IsProduction() ? "has-env-banner" : "")">
<nav class="modern-navbar">
<div class="container">
<div class="navbar-content">
<a class="brand-logo" href="/">
<div class="brand-icon">
<i class="bi bi-shop"></i>
@* Accessibility: Added aria-label for screen readers *@
<a class="brand-logo" href="/" aria-label="DevEats Home">
<div class="brand-icon" aria-hidden="true">
<i class="bi bi-shop" aria-hidden="true"></i>
</div>
<span class="brand-text">Dev<span class="brand-highlight">Eats</span></span>
</a>

<button class="mobile-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span></span>
<span></span>
<span></span>
@* Accessibility: Added ARIA attributes for mobile menu button *@
<button class="mobile-toggle"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-label="Toggle navigation menu"
aria-expanded="false"
aria-controls="navbarNav">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</button>

<div class="collapse navbar-collapse" id="navbarNav">
<ul class="nav-menu">
<li class="nav-item">
<a class="nav-link-modern" href="/">
<i class="bi bi-house-door-fill"></i>
@* Accessibility: Decorative icon hidden from screen readers *@
<i class="bi bi-house-door-fill" aria-hidden="true"></i>
<span>Home</span>
</a>
</li>
Expand All @@ -33,7 +58,8 @@
</div>
</nav>

<main class="main-content">
@* Accessibility: Main content landmark with ID for skip link *@
<main class="main-content" id="main-content" tabindex="-1">
@Body
</main>

Expand All @@ -54,7 +80,8 @@
<span>Powered by .NET 8 & Blazor Server</span>
</div> *@
<div class="footer-love">
Made with <i class="bi bi-heart-fill"></i> for hungry developers
@* Accessibility: Decorative icon hidden from screen readers *@
Made with <i class="bi bi-heart-fill" aria-hidden="true"></i> for hungry developers
</div>
</div>
</div>
Expand All @@ -66,6 +93,69 @@
</div>

<style>
/* Skip Link for Keyboard Accessibility (WCAG 2.4.1) */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px 16px;
text-decoration: none;
z-index: 2000;
border-radius: 0 0 4px 0;
}

.skip-link:focus {
top: 0;
}

/* Environment Warning Banner */
.env-warning-banner {
position: fixed;
top: 0;
left: 0;
right: 0;
/* Accessibility: Darker red gradient for WCAG AA 4.5:1 contrast with white text */
background: linear-gradient(135deg, #e53e3e 0%, #c53030 100%);
z-index: 1050;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
padding: 1rem 0;
}

.banner-content {
display: flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 0 1.5rem;
}

.banner-icon {
font-size: 1.2rem;
color: white;
flex-shrink: 0;
}

.banner-text {
color: white;
font-size: 1rem;
font-weight: 500;
text-align: center;
line-height: 1.4;
}

.banner-text strong {
font-weight: 700;
letter-spacing: 0.5px;
}

@@media (prefers-reduced-motion: reduce) {
.env-warning-banner {
opacity: 1;
}
}

/* App Wrapper */
.app-wrapper {
min-height: 100vh;
Expand All @@ -74,6 +164,11 @@
background: #f7fafc;
}

/* Accessibility: CSS class for environment banner margin instead of inline style */
.app-wrapper.has-env-banner {
margin-top: 56px;
}

/* Modern Navbar */
.modern-navbar {
background: linear-gradient(135deg, #ff6b6b 0%, #ff8e53 50%, #feca57 100%);
Expand All @@ -96,11 +191,6 @@
align-items: center;
gap: 0.75rem;
text-decoration: none;
transition: all 0.3s ease;
}

.brand-logo:hover {
transform: translateY(-2px);
}

.brand-icon {
Expand Down Expand Up @@ -169,15 +259,13 @@
text-decoration: none;
font-weight: 500;
border-radius: 12px;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.15);
}

.nav-link-modern:hover {
background: rgba(255, 255, 255, 0.2);
color: white;
transform: translateY(-2px);
}

.nav-link-modern i {
Expand Down Expand Up @@ -207,18 +295,24 @@
height: 4px;
background: linear-gradient(90deg, #ff6b6b, #ff8e53, #feca57, #fdcb6e);
background-size: 300% 100%;
animation: gradientShift 3s ease infinite;
}

@@keyframes gradientShift {
0% {
background-position: 0% 50%;
/* Accessibility: Footer gradient animation only for users who haven't requested reduced motion */
@@media (prefers-reduced-motion: no-preference) {
.footer-decoration {
animation: gradientShift 3s ease infinite;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;

@@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
}

Expand Down Expand Up @@ -303,15 +397,37 @@

.footer-love i {
color: #f56565;
animation: heartbeat 1.5s ease infinite;
}

@@keyframes heartbeat {
0%, 100% {
transform: scale(1);
/* Accessibility: Heart animation and hover transforms only for users who haven't requested reduced motion */
@@media (prefers-reduced-motion: no-preference) {
.brand-logo {
transition: all 0.3s ease;
}

.brand-logo:hover {
transform: translateY(-2px);
}
50% {
transform: scale(1.2);

.nav-link-modern {
transition: all 0.3s ease;
}

.nav-link-modern:hover {
transform: translateY(-2px);
}

.footer-love i {
animation: heartbeat 1.5s ease infinite;
}

@@keyframes heartbeat {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
}
}

Expand Down Expand Up @@ -355,6 +471,23 @@
.footer-info {
align-items: center;
}

.env-warning-banner {
padding: 0.75rem 0;
}

.banner-text {
font-size: 0.875rem;
}

.banner-content {
gap: 0.5rem;
padding: 0 1rem;
}

.banner-icon {
font-size: 1.1rem;
}
}

@@media (max-width: 768px) {
Expand Down