Files
EnvelopeGenerator/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/LocalizationController.cs
TekH 0d2e43b2d6 Add multilingual support with language selector
Introduced a `LanguageControls` component for switching between
languages (`de-DE`, `en-US`, `fr-FR`) and integrated a new
`LocalizationService` to manage language preferences. Updated
`LocalizationController` to handle language persistence via
cookies and support multiple cultures. Enhanced the footer
layout to include the language selector alongside theme
controls.

Added `flag-icons` library for displaying country flags and
configured request localization in `Program.cs`. Styled the
language selector dropdown and improved sender page visuals
with updated CSS. Defaulted language handling to `de-DE` for
fallback scenarios. Cleaned up redundant code in
`LocalizationController`.
2026-09-28 09:19:46 +02:00

118 lines
4.0 KiB
C#

using DigitalData.Core.API;
using EnvelopeGenerator.Application.Resources;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Localization;
namespace EnvelopeGenerator.Server.Controllers;
/// <summary>
/// Controller für die Verwaltung der Lokalisierung und Spracheinstellungen.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
[Route("api/[controller]")]
[ApiController]
public class LocalizationController : ControllerBase
{
private static readonly Guid L_KEY = Guid.NewGuid();
private readonly ILogger<LocalizationController> _logger;
private readonly IStringLocalizer<Resource> _mLocalizer;
private readonly IMemoryCache _cache;
/// <summary>
/// Konstruktor für den <see cref="LocalizationController"/>.
/// </summary>
/// <param name="logger">Logger für die Protokollierung.</param>
/// <param name="localizer">Lokalisierungsdienst für Ressourcen.</param>
/// <param name="memoryCache">Speicher-Cache für die Zwischenspeicherung von Daten.</param>
/// <param name="_modelLocalizer">Lokalisierungsdienst für Modelle.</param>
public LocalizationController(
ILogger<LocalizationController> logger,
IMemoryCache memoryCache,
IStringLocalizer<Resource> modelLocalizer)
{
_logger = logger;
_cache = memoryCache;
_mLocalizer = modelLocalizer;
}
/// <summary>
/// Ruft alle lokalisierten Daten ab.
/// </summary>
/// <returns>Eine Liste aller lokalisierten Daten.</returns>
[HttpGet]
public IActionResult GetAll() => Ok(_cache.GetOrCreate(Language ?? string.Empty + L_KEY, _ => _mLocalizer.ToDictionary()));
/// <summary>
/// Ruft die aktuelle Sprache ab.
/// </summary>
/// <returns>Die aktuelle Sprache oder ein NotFound-Ergebnis, wenn keine Sprache gesetzt ist.</returns>
[HttpGet("lang")]
public IActionResult GetLanguage() => Language is null ? NotFound() : Ok(Language);
/// <summary>
/// Setzt die Sprache.
/// </summary>
/// <param name="language">Die zu setzende Sprache.</param>
/// <returns>Ein Ok-Ergebnis, wenn die Sprache erfolgreich gesetzt wurde, oder ein BadRequest-Ergebnis, wenn die Eingabe ungültig ist.</returns>
[HttpPost("lang")]
public IActionResult SetLanguage([FromQuery] string language)
{
if (string.IsNullOrEmpty(language))
return BadRequest();
Language = language;
return Ok();
}
/// <summary>
/// Löscht die aktuelle Sprache.
/// </summary>
/// <returns>Ein Ok-Ergebnis, wenn die Sprache erfolgreich gelöscht wurde.</returns>
[HttpDelete("lang")]
public IActionResult DeleteLanguage()
{
Language = null;
return Ok();
}
/// <summary>
/// Eigenschaft für die Verwaltung der aktuellen Sprache über Cookies.
/// </summary>
private string? Language
{
get
{
var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
if (string.IsNullOrEmpty(cookieValue))
return "de-DE";
var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures[0];
return culture?.Value ?? "de-DE";
}
set
{
if (value is null)
Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);
else
{
var cookieOptions = new CookieOptions()
{
Expires = DateTimeOffset.UtcNow.AddYears(1),
Secure = false,
SameSite = SameSiteMode.Strict,
HttpOnly = true
};
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)),
cookieOptions);
}
}
}
}