521 lines
26 KiB
Plaintext
521 lines
26 KiB
Plaintext
@using QRRapidoApp.Services
|
|
@using Microsoft.AspNetCore.Http.Extensions
|
|
@using Microsoft.Extensions.Localization
|
|
@using Microsoft.Extensions.Configuration
|
|
@inject AdDisplayService AdService
|
|
@inject IStringLocalizer<QRRapidoApp.Resources.SharedResource> Localizer
|
|
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostEnvironment
|
|
@inject IConfiguration Configuration
|
|
|
|
@{
|
|
var isDevelopment = HostEnvironment?.IsDevelopment() ?? false;
|
|
var isPremiumUser = false;
|
|
var currentCulture = System.Globalization.CultureInfo.CurrentUICulture?.Name ?? "pt-BR";
|
|
|
|
// App info for footer
|
|
var appName = Configuration["App:Name"] ?? "QR Rapido";
|
|
var appVersion = Configuration["App:Version"] ?? "1.0.0";
|
|
var appEnvironment = Configuration["App:Environment"] ?? HostEnvironment?.EnvironmentName ?? "Unknown";
|
|
var secretsLoaded = Configuration.GetValue<bool>("App:SecretsLoaded");
|
|
|
|
// SEO: Determine current culture from URL
|
|
var requestPath = Context.Request.Path.Value ?? "/";
|
|
var isSpanish = requestPath.StartsWith("/es/", StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(requestPath, "/es", StringComparison.OrdinalIgnoreCase);
|
|
var isEnglish = requestPath.StartsWith("/en/", StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(requestPath, "/en", StringComparison.OrdinalIgnoreCase);
|
|
|
|
// Get path without culture prefix for building alternate URLs
|
|
var pathWithoutCulture = requestPath;
|
|
if (requestPath.StartsWith("/es/", StringComparison.OrdinalIgnoreCase))
|
|
pathWithoutCulture = requestPath.Length > 3 ? requestPath.Substring(3) : "/";
|
|
else if (string.Equals(requestPath, "/es", StringComparison.OrdinalIgnoreCase))
|
|
pathWithoutCulture = "/";
|
|
else if (requestPath.StartsWith("/en/", StringComparison.OrdinalIgnoreCase))
|
|
pathWithoutCulture = requestPath.Length > 3 ? requestPath.Substring(3) : "/";
|
|
if (string.IsNullOrEmpty(pathWithoutCulture)) pathWithoutCulture = "/";
|
|
|
|
// Canonical URL
|
|
var canonicalUrl = isEnglish
|
|
? $"https://qrrapido.site/en{(pathWithoutCulture == "/" ? "" : pathWithoutCulture)}"
|
|
: isSpanish
|
|
? $"https://qrrapido.site/es{(pathWithoutCulture == "/" ? "" : pathWithoutCulture)}"
|
|
: $"https://qrrapido.site{pathWithoutCulture}";
|
|
|
|
// Alternate URLs for hreflang
|
|
var ptUrl = $"https://qrrapido.site{pathWithoutCulture}";
|
|
var esUrl = $"https://qrrapido.site/es{(pathWithoutCulture == "/" ? "" : pathWithoutCulture)}";
|
|
var enUrl = $"https://qrrapido.site/en{(pathWithoutCulture == "/" ? "" : pathWithoutCulture)}";
|
|
|
|
// Culture prefix for internal links
|
|
var culturePrefix = isEnglish ? "/en" : isSpanish ? "/es" : "";
|
|
|
|
if (User?.Identity?.IsAuthenticated == true)
|
|
{
|
|
var userId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
|
|
if (!string.IsNullOrWhiteSpace(userId))
|
|
{
|
|
try
|
|
{
|
|
isPremiumUser = await AdService.HasValidPremiumSubscription(userId);
|
|
}
|
|
catch
|
|
{
|
|
isPremiumUser = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
<!DOCTYPE html>
|
|
<html lang="@currentCulture">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>@ViewData["Title"] - QR Rapido | Gerador QR Code Ultrarrápido</title>
|
|
|
|
<!-- Cache Control Headers -->
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<meta http-equiv="Pragma" content="no-cache">
|
|
<meta http-equiv="Expires" content="0">
|
|
|
|
<!-- SEO Meta Tags -->
|
|
<meta name="description" content="@(ViewBag.Description ?? Localizer["QRGenerateDescription"])">
|
|
<meta name="keywords" content="@(ViewBag.Keywords ?? "qr rapido, gerador qr rapido, qr code rapido, codigo qr rapido, qr gratis rapido, generador qr rapido, qr ultrarapido")">
|
|
<meta name="author" content="QR Rapido">
|
|
<meta name="robots" content="index, follow">
|
|
|
|
<!-- Canonical URL -->
|
|
<link rel="canonical" href="@canonicalUrl">
|
|
|
|
<!-- Hreflang for multilingual SEO -->
|
|
<link rel="alternate" hreflang="pt-BR" href="@ptUrl">
|
|
<link rel="alternate" hreflang="es" href="@esUrl">
|
|
<link rel="alternate" hreflang="en" href="@enUrl">
|
|
<link rel="alternate" hreflang="x-default" href="@ptUrl">
|
|
|
|
<!-- Open Graph -->
|
|
<meta property="og:title" content="@(ViewBag.Title ?? "QR Rapido") - @Localizer["FastestQRGeneratorWeb"]">
|
|
<meta property="og:description" content="@(ViewBag.Description ?? Localizer["QRGenerateDescription"])">
|
|
<meta property="og:image" content="https://qrrapido.site/images/pix-og.png">
|
|
<meta property="og:url" content="@canonicalUrl">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:site_name" content="QR Rapido">
|
|
<meta property="og:locale" content="@(isSpanish ? "es_PY" : "pt_BR")">
|
|
|
|
<!-- Twitter Cards -->
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="QR Rapido - @Localizer["FastestQRGeneratorWeb"]">
|
|
<meta name="twitter:description" content="@Localizer["QRGenerateDescription"]">
|
|
<meta name="twitter:image" content="https://qrrapido.site/images/qrrapido-twitter-card.png">
|
|
|
|
<!-- Preload critical resources for performance -->
|
|
<link rel="preload" href="/webfonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin>
|
|
<link rel="preload" href="/webfonts/fa-brands-400.woff2" as="font" type="font/woff2" crossorigin>
|
|
<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" as="style">
|
|
<link rel="preload" href="~/css/site.css" as="style">
|
|
<link rel="preload" href="~/css/qrrapido-theme.css" as="style">
|
|
|
|
|
|
<script type="text/javascript">
|
|
(function(c,l,a,r,i,t,y){
|
|
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
|
|
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
|
|
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
|
|
})(window, document, "clarity", "script", "tufamidcvb");
|
|
</script>
|
|
|
|
@*
|
|
<!-- Hotjar Tracking Code for https://qrrapido.site -->
|
|
<script data-cfasync="false">
|
|
(function(h,o,t,j,a,r){
|
|
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
|
|
h._hjSettings={hjid:6550944,hjsv:6};
|
|
a=o.getElementsByTagName('head')[0];
|
|
r=o.createElement('script');r.async=1;
|
|
r.crossOrigin='anonymous';
|
|
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
|
|
a.appendChild(r);
|
|
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
|
|
</script>
|
|
*@
|
|
|
|
<!-- Structured Data Schema.org -->
|
|
<script type="application/ld+json">
|
|
{
|
|
"@@context": "https://schema.org",
|
|
"@@type": "WebApplication",
|
|
"name": "QR Rapido",
|
|
"description": "Gerador de QR Code ultrarrápido em português e espanhol",
|
|
"url": "https://qrrapido.site",
|
|
"applicationCategory": "UtilityApplication",
|
|
"operatingSystem": "Web",
|
|
"author": {
|
|
"@@type": "Organization",
|
|
"name": "QR Rapido"
|
|
},
|
|
"offers": {
|
|
"@@type": "Offer",
|
|
"price": "0",
|
|
"priceCurrency": "BRL",
|
|
"description": "Geração gratuita de QR codes"
|
|
},
|
|
"aggregateRating": {
|
|
"@@type": "AggregateRating",
|
|
"ratingValue": "4.8",
|
|
"reviewCount": "2547"
|
|
},
|
|
"featureList": [
|
|
"Geração em segundos",
|
|
"Suporte multilíngue",
|
|
"Sem cadastro obrigatório",
|
|
"Sem limite diário",
|
|
"Download múltiplos formatos"
|
|
]
|
|
}
|
|
</script>
|
|
|
|
|
|
<!-- Google tag (gtag.js) -->
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-64FCDJGT44"></script>
|
|
<script>
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
|
|
gtag('config', 'G-64FCDJGT44');
|
|
</script>
|
|
|
|
@*
|
|
<!-- Google Analytics 4 - Optimized with defer -->
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-64FCDJGT44"></script>
|
|
<script defer>
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
|
|
gtag('config', 'G-64FCDJGT44');
|
|
|
|
// Custom events for QR Rapido
|
|
window.trackQRGeneration = function(type, time, isPremium) {
|
|
gtag('event', 'qr_generated', {
|
|
'event_category': 'QR Generation',
|
|
'event_label': type,
|
|
'value': Math.round(parseFloat(time) * 1000),
|
|
'custom_parameters': {
|
|
'generation_time': parseFloat(time),
|
|
'user_type': isPremium ? 'premium' : 'free',
|
|
'speed_category': time < 1.0 ? 'ultra_fast' : time < 2.0 ? 'fast' : 'normal'
|
|
}
|
|
});
|
|
};
|
|
|
|
window.trackSpeedComparison = function(ourTime, competitorAvg) {
|
|
gtag('event', 'speed_comparison', {
|
|
'event_category': 'Performance',
|
|
'our_time': parseFloat(ourTime),
|
|
'competitor_avg': parseFloat(competitorAvg),
|
|
'speed_advantage': parseFloat(competitorAvg) - parseFloat(ourTime)
|
|
});
|
|
};
|
|
|
|
window.trackLanguageChange = function(from, to) {
|
|
gtag('event', 'language_change', {
|
|
'event_category': 'Localization',
|
|
'previous_language': from,
|
|
'new_language': to
|
|
});
|
|
};
|
|
</script>
|
|
|
|
*@
|
|
@* AdSense removed - Preparing for Adsterra integration *@
|
|
|
|
<!-- Bootstrap 5 - Optimized loading -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" media="print" onload="this.media='all'">
|
|
<link rel="stylesheet" href="~/css/vendor/fontawesome.min.css" asp-append-version="true" media="print" onload="this.media='all'" />
|
|
<link rel="stylesheet" href="~/css/telegram-fab.css" asp-append-version="true" />
|
|
<link rel="stylesheet" href="~/css/rating.css" asp-append-version="true" />
|
|
|
|
<!-- Custom CSS - Critical above fold with cache busting -->
|
|
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
|
<link rel="stylesheet" href="~/css/qrrapido-theme.css" asp-append-version="true" />
|
|
|
|
<!-- Translation variables for JavaScript -->
|
|
<script>
|
|
window.QRRapidoTranslations = {
|
|
shareError: '@Localizer["ShareError"]',
|
|
linkCopied: '@Localizer["LinkCopied"]',
|
|
enterQRContent: '@Localizer["EnterQRContent"]',
|
|
contentTooLong: '@Localizer["ContentTooLong"]',
|
|
featureNotAvailable: '@Localizer["FeatureNotAvailable"]',
|
|
vCardValidationError: '@Localizer["VCardValidationError"]',
|
|
logoTooLarge: '@Localizer["LogoTooLarge"]',
|
|
invalidLogoFormat: '@Localizer["InvalidLogoFormat"]',
|
|
premiumCornerStyleRequired: '@Localizer["PremiumCornerStyleRequired"]',
|
|
fastestGeneratorBrazil: '@Localizer["FastestGeneratorBrazil"]',
|
|
validationContentMinLength: '@Localizer["ValidationContentMinLength"]',
|
|
errorSavingHistory: '@Localizer["ErrorSavingHistory"]',
|
|
rateLimitReached: '@Localizer["RateLimitReached"]',
|
|
premiumLogoRequired: '@Localizer["PremiumLogoRequired"]',
|
|
contentAddedToastTitle: '@Localizer["ContentAddedToastTitle"]',
|
|
contentAddedToastMessage: '@Localizer["ContentAddedToastMessage"]',
|
|
generateButtonReady: '@Localizer["GenerateButtonReady"]'
|
|
};
|
|
</script>
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/svg+xml" href="/images/qrrapido-favicon.svg">
|
|
<link rel="icon" type="image/png" href="/images/qrrapido-favicon-32x32.png">
|
|
|
|
<!-- Web App Manifest -->
|
|
<link rel="manifest" href="/manifest.json">
|
|
<meta name="theme-color" content="#007BFF">
|
|
</head>
|
|
<body>
|
|
<!-- Header with QR Rapido branding -->
|
|
<header class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
|
|
<div class="container">
|
|
<a class="navbar-brand d-flex align-items-center" href="/">
|
|
<svg width="40" height="40" class="me-2" viewBox="0 0 100 100">
|
|
<!-- QR Rapido logo with speed effect -->
|
|
<rect x="10" y="10" width="80" height="80" fill="#007BFF" rx="8"/>
|
|
<rect x="20" y="20" width="15" height="15" fill="white"/>
|
|
<rect x="65" y="20" width="15" height="15" fill="white"/>
|
|
<rect x="20" y="65" width="15" height="15" fill="white"/>
|
|
<!-- Speed lines -->
|
|
<path d="M85 45 L95 45 M85 50 L92 50 M85 55 L89 55" stroke="#FF6B35" stroke-width="2"/>
|
|
</svg>
|
|
<div>
|
|
<h1 class="h4 mb-0 text-primary fw-bold">QR Rapido</h1>
|
|
<small class="text-muted" id="tagline">@Localizer["Tagline"]</small>
|
|
</div>
|
|
</a>
|
|
|
|
<div class="navbar-nav ms-auto d-flex flex-row align-items-center gap-3">
|
|
<!-- Main Menu Dropdown -->
|
|
<div class="dropdown">
|
|
<button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
<i class="fas fa-bars"></i> <span class="d-none d-md-inline ms-1">Menu</span>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="@Url.Action("Index", "Home")">
|
|
<i class="fas fa-home me-2"></i>@Localizer["Home"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="@Url.Action("HowToUse", "Home")">
|
|
<i class="fas fa-question-circle me-2"></i>@Localizer["HowToUse"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="@Url.Action("FAQ", "Home")">
|
|
<i class="fas fa-comments me-2"></i>FAQ
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="@Url.Action("About", "Home")">
|
|
<i class="fas fa-info-circle me-2"></i>@Localizer["About"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="@Url.Action("Contact", "Home")">
|
|
<i class="fas fa-envelope me-2"></i>@Localizer["Contact"]
|
|
</a></li>
|
|
</ul>
|
|
</div>
|
|
<!-- Language selector -->
|
|
<div class="dropdown">
|
|
<button class="btn btn-outline-secondary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
<i class="fas fa-globe"></i> <span id="current-lang">PT</span>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="#" data-lang="pt-BR">🌎 Português (Brasil)</a></li>
|
|
<li><a class="dropdown-item" href="#" data-lang="es">🌎 Español</a></li>
|
|
<li><a class="dropdown-item" href="#" data-lang="en">🌎 English</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Theme Toggle -->
|
|
<div class="theme-toggle-container">
|
|
<button id="theme-toggle" class="btn btn-outline-secondary btn-sm" type="button" title="Alternar tema">
|
|
<i id="theme-icon" class="fas fa-sun"></i>
|
|
<span id="theme-text" class="d-none d-md-inline ms-1">Claro</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Global speed timer -->
|
|
<div class="d-none d-md-block">
|
|
<small class="text-success fw-bold">
|
|
<i class="fas fa-stopwatch"></i>
|
|
<span id="avg-generation-time">1.2s</span> @Localizer["Average"]
|
|
</small>
|
|
</div>
|
|
|
|
@if (User.Identity.IsAuthenticated)
|
|
{
|
|
<a href="/Pagamento/SelecaoPlano" class="btn btn-warning text-dark fw-bold shadow-sm animate-pulse">
|
|
<i class="fas fa-coins"></i> <span class="d-none d-md-inline">Comprar Créditos</span>
|
|
</a>
|
|
|
|
<div class="dropdown">
|
|
<button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
<i class="fas fa-user"></i> @User.Identity.Name
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="/">
|
|
<i class="fas fa-qrcode me-2"></i> @Localizer["GenerateQRCode"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="/Account/Profile">
|
|
<i class="fas fa-user-cog me-2"></i> @Localizer["Profile"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="/Account/History">
|
|
<i class="fas fa-history me-2"></i> @Localizer["History"]
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="/Developer">
|
|
<i class="fas fa-code me-2"></i> Desenvolvedor
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li>
|
|
<form method="post" action="/Account/Logout" class="d-inline">
|
|
<button type="submit" class="dropdown-item text-danger">
|
|
<i class="fas fa-sign-out-alt me-2"></i>@Localizer["Logout"]
|
|
</button>
|
|
</form>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<a href="/Account/Login" class="btn btn-primary btn-sm">
|
|
<i class="fas fa-sign-in-alt"></i> @Localizer["Login"]
|
|
</a>
|
|
<div class="d-none d-md-block">
|
|
<small class="text-success">
|
|
<i class="fas fa-gift"></i> Cadastre-se = 5 Grátis!
|
|
</small>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Hero Section for speed -->
|
|
<section class="bg-gradient-primary text-white py-4 mb-4">
|
|
<div class="container text-center">
|
|
<h2 class="h5 mb-2">
|
|
<i class="fas fa-bolt"></i> @Localizer["FastestQRGeneratorWeb"]
|
|
</h2>
|
|
<p class="mb-0 opacity-75">
|
|
@Localizer["AverageTimePrefix"] <strong>@Localizer["AverageTimeValue"]</strong> @Localizer["AverageTimeSuffix"]
|
|
</p>
|
|
<div class="mt-3">
|
|
<a href="@(culturePrefix)/tutoriais" class="btn btn-sm btn-light">
|
|
<i class="fas fa-graduation-cap"></i> @Localizer["ViewTutorials"]
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Ad Space Header (conditional) -->
|
|
@await Html.PartialAsync("_AdSpace", new { position = "header" })
|
|
|
|
<main role="main">
|
|
@RenderBody()
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="bg-dark text-light py-4 mt-5">
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-md-5">
|
|
<h5>QR Rapido</h5>
|
|
<p class="small">@Localizer["FastestQRGeneratorDescription"]</p>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<h6>@Localizer["Tools"]</h6>
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<ul class="list-unstyled small">
|
|
<li><a href="@(culturePrefix)/pix" class="text-light text-decoration-none">@Localizer["PixGenerator"]</a></li>
|
|
<li><a href="@(culturePrefix)/wifi" class="text-light text-decoration-none">QR Code WiFi</a></li>
|
|
<li><a href="@(culturePrefix)/whatsapp" class="text-light text-decoration-none">Link WhatsApp</a></li>
|
|
<li><a href="@(culturePrefix)/vcard" class="text-light text-decoration-none">@Localizer["DigitalCard"]</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-6">
|
|
<ul class="list-unstyled small">
|
|
<li><a href="@(culturePrefix)/email" class="text-light text-decoration-none">QR Code Email</a></li>
|
|
<li><a href="@(culturePrefix)/sms" class="text-light text-decoration-none">QR Code SMS</a></li>
|
|
<li><a href="@(culturePrefix)/texto" class="text-light text-decoration-none">@Localizer["TextQR"]</a></li>
|
|
<li><a href="@(culturePrefix)/url" class="text-light text-decoration-none">QR Code URL</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<h6>@Localizer["UsefulLinks"]</h6>
|
|
<ul class="list-unstyled small">
|
|
<li><a href="@Url.Action("Privacy", "Home")" class="text-light">@Localizer["Privacy"]</a></li>
|
|
<li><a href="@Url.Action("Terms", "Home")" class="text-light">@Localizer["TermsOfUse"]</a></li>
|
|
<li><a href="@Url.Action("Upgrade", "Premium")" class="text-warning">Premium</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<h6>@Localizer["Support"]</h6>
|
|
<ul class="list-unstyled">
|
|
<li><a href="mailto:contato@qrrapido.site" class="text-light">Contato</a></li>
|
|
<li><a href="@Url.Action("FAQ", "Home")" class="text-light">@Localizer["Help"]</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="text-center mb-2">
|
|
<small class="text-muted">
|
|
@Html.Raw(Localizer["JobMakerCredit"].ToString().Replace("JobMaker", "<a href=\"https://jobmaker.com.br\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-warning\">JobMaker</a>"))
|
|
</small>
|
|
</div>
|
|
<div class="text-center">
|
|
<small>© 2024 QR Rapido. @Localizer["AllRightsReserved"]</small>
|
|
</div>
|
|
<div class="text-center mt-2">
|
|
<small class="text-muted" style="font-size: 0.7rem;">
|
|
@appName v@(appVersion) |
|
|
@appEnvironment
|
|
@if (secretsLoaded)
|
|
{
|
|
<span class="text-success" title="Docker Secrets loaded">✓</span>
|
|
}
|
|
else if (appEnvironment == "Production")
|
|
{
|
|
<span class="text-danger" title="Secrets NOT loaded from Docker!">✗</span>
|
|
}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- Cookie Consent Banner -->
|
|
@await Html.PartialAsync("_CookieConsent")
|
|
|
|
<!-- Support FAB - Available for all users, with rating option -->
|
|
@await Html.PartialAsync("_TelegramPremiumFab", isPremiumUser)
|
|
|
|
<!-- Bootstrap 5 JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="~/js/telegram-fab.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/rating.js" asp-append-version="true" defer></script>
|
|
|
|
@if (isDevelopment || true) // FORCE INDIVIDUAL SCRIPTS FOR NOW TO ENSURE CHANGES ARE VISIBLE
|
|
{
|
|
<script src="~/js/simple-opcacity.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/test.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/qr-speed-generator.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/language-switcher.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/theme-toggle.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/cookie-consent.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/performance-optimizations.js" asp-append-version="true" defer></script>
|
|
<script src="~/js/pix-generator.js" asp-append-version="true" defer></script>
|
|
}
|
|
else
|
|
{
|
|
<script src="~/dist/app.min.js" asp-append-version="true"></script>
|
|
}
|
|
|
|
@await RenderSectionAsync("Scripts", required: false)
|
|
</body>
|
|
</html>
|