diff --git a/ManagerService/Controllers/SectionController.cs b/ManagerService/Controllers/SectionController.cs index e4b5ecd..d21f734 100644 --- a/ManagerService/Controllers/SectionController.cs +++ b/ManagerService/Controllers/SectionController.cs @@ -758,6 +758,46 @@ namespace ManagerService.Controllers } } + /// + /// Show or hide a section in the visitor apps + /// + /// Section id + /// true = visible, false = hidden + /// + /// Endpoint dédié plutôt que : celui-ci reconstruit le + /// sous-type via SectionFactory, donc un SectionDTO nu effacerait tout le + /// contenu spécifique de la section. + /// + [ProducesResponseType(typeof(object), 200)] + [ProducesResponseType(typeof(string), 404)] + [ProducesResponseType(typeof(string), 500)] + [HttpPut("{id}/visibility")] + public ObjectResult SetVisibility(string id, [FromQuery] bool isActive) + { + try + { + Section section = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == id); + + if (section == null) + throw new KeyNotFoundException("Section does not exist"); + + section.IsActive = isActive; + _myInfoMateDbContext.SaveChanges(); + + MqttClientService.PublishMessage($"config/{section.ConfigurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + + return new OkObjectResult(SectionFactory.ToDTO(section)); + } + catch (KeyNotFoundException ex) + { + return new NotFoundObjectResult(ex.Message) { }; + } + catch (Exception ex) + { + return new ObjectResult(ex.Message) { StatusCode = 500 }; + } + } + /// /// Update sections order /// diff --git a/ManagerService/EmailTemplates/EmailLayout.cs b/ManagerService/EmailTemplates/EmailLayout.cs index 9f89f22..3124190 100644 --- a/ManagerService/EmailTemplates/EmailLayout.cs +++ b/ManagerService/EmailTemplates/EmailLayout.cs @@ -3,57 +3,127 @@ using System; namespace ManagerService.EmailTemplates { /// - /// Shared HTML shell for all transactional emails — MyInfoMate branding - /// (cyan #0df2df header, dark logo band, white content card). + /// Shared HTML shell for all transactional emails. Palette taken from the + /// MyInfoMate platform deck: navy #0a1222, cyan #0df2df, teal #0e8f8a. /// public static class EmailLayout { + /// Absolute URL of the logo shown in the header band. Empty = wordmark only. + public static string LogoUrl { get; private set; } = ""; + + /// Public site linked from the footer. Empty = no link. + public static string LandingUrl { get; private set; } = ""; + + /// Called once at startup from configuration (see Startup.cs). + public static void Configure(string logoUrl, string landingUrl) + { + // Une URL relative afficherait une image cassée dans la boîte de + // réception : mieux vaut le bandeau sans logo que ça. + LogoUrl = logoUrl != null && logoUrl.StartsWith("http") ? logoUrl : ""; + LandingUrl = landingUrl ?? ""; + } + public static string Render(string title, string bodyHtml, string ctaText = null, string ctaUrl = null) { + var hasCta = !string.IsNullOrEmpty(ctaText) && !string.IsNullOrEmpty(ctaUrl); + + // Le texte de pré-en-tête est ce que la boîte de réception affiche à + // côté de l'objet : sans lui elle recopie le début du HTML. + var preheader = StripTags(bodyHtml); + if (preheader.Length > 140) preheader = preheader.Substring(0, 140) + "…"; + + var logoHtml = string.IsNullOrEmpty(LogoUrl) + ? "" + : $@""; + var ctaHtml = ""; - if (!string.IsNullOrEmpty(ctaText) && !string.IsNullOrEmpty(ctaUrl)) + if (hasCta) { ctaHtml = $@" - +
- -
- {ctaText} + + {ctaText}
"; + +

+ Le bouton ne fonctionne pas ? Copiez ce lien dans votre navigateur :
+ {ctaUrl} +

"; } + var landingHtml = string.IsNullOrEmpty(LandingUrl) + ? "" + : $@" · myinfomate.be"; + return $@" - - - + + + + + {title} + + +
{preheader}
+ +
-
- +
+ + + - - + + + + + - +
- MyInfoMate + + + + + + +
{logoHtml}MyInfoMate
-

{title}

-
{bodyHtml}
+
 
+

{title}

+
{bodyHtml}
{ctaHtml}
- MyInfoMate — {DateTime.UtcNow.Year} + + MyInfoMate — la plateforme de contenu des lieux culturels.
+ © {DateTime.UtcNow.Year} Unov{landingHtml}
+
"; } + + private static string StripTags(string html) + { + if (string.IsNullOrEmpty(html)) return ""; + var sb = new System.Text.StringBuilder(html.Length); + var inTag = false; + foreach (var c in html) + { + if (c == '<') inTag = true; + else if (c == '>') inTag = false; + else if (!inTag) sb.Append(c); + } + return sb.ToString().Replace(" ", " ").Trim(); + } } } diff --git a/ManagerService/Startup.cs b/ManagerService/Startup.cs index 60c5f56..03a4f8b 100644 --- a/ManagerService/Startup.cs +++ b/ManagerService/Startup.cs @@ -121,6 +121,10 @@ namespace ManagerService services.Configure(Configuration.GetSection("Stripe")); services.Configure(Configuration.GetSection("Resend")); + ManagerService.EmailTemplates.EmailLayout.Configure( + Configuration["AppUrls:Logo"] ?? $"{Configuration["AppUrls:Api"]}/email-logo.png", + Configuration["AppUrls:Landing"]); + foreach (var policy in ManagerService.Service.Security.PoliciesConfiguration) services.AddAuthorization(options => { @@ -320,6 +324,11 @@ namespace ManagerService //app.UseHttpsRedirection(); + // Sert wwwroot/ — aujourd'hui le seul fichier est le logo des e-mails + // transactionnels, qui doit vivre sur le même service que l'envoi pour + // ne pas dépendre du build du manager déployé en face. + app.UseStaticFiles(); + app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); diff --git a/ManagerService/appsettings.Development.json b/ManagerService/appsettings.Development.json index b2255f1..fe80efc 100644 --- a/ManagerService/appsettings.Development.json +++ b/ManagerService/appsettings.Development.json @@ -26,7 +26,8 @@ }, "AppUrls": { "ManagerApp": "http://localhost:9090", - "Landing": "http://localhost:3000" + "Landing": "http://localhost:3000", + "Api": "http://localhost:5000" } } diff --git a/ManagerService/appsettings.json b/ManagerService/appsettings.json index 01772fa..259688e 100644 --- a/ManagerService/appsettings.json +++ b/ManagerService/appsettings.json @@ -47,7 +47,8 @@ }, "AppUrls": { "ManagerApp": "https://manager.myinfomate.be", - "Landing": "https://myinfomate.be" + "Landing": "https://myinfomate.be", + "Api": "https://api.myinfomate.be" }, "Stripe": { "SecretKey": "sk_test_51U14rjRLQgHvlM4X4ewATCOOIzdIfTZEJCwwZT9sfpWm9LkrISoSEHfgHbPhJTujdYdPdRyCnrDoo5Sf8NMyCrPT00RfYB8fSN", diff --git a/ManagerService/wwwroot/email-logo.png b/ManagerService/wwwroot/email-logo.png new file mode 100644 index 0000000..bdd1fe1 Binary files /dev/null and b/ManagerService/wwwroot/email-logo.png differ