diff --git a/Apis/api/Controllers/CvMatcherController.cs b/Apis/api/Controllers/CvMatcherController.cs index 03098f2..3b0bcc1 100644 --- a/Apis/api/Controllers/CvMatcherController.cs +++ b/Apis/api/Controllers/CvMatcherController.cs @@ -246,38 +246,24 @@ public sealed class CvMatcherController : ControllerBase { var result = await _jobSearchApi.StartSearchAsync(t, ct); var lang = "en"; - var html = result.Status switch + var (title, message) = result.Status switch { - StartJobSearchStatus.Started => - HtmlPage(_templates.Get("html.job-search.started.title", lang), _templates.Get("html.job-search.started.message", lang)), - StartJobSearchStatus.AlreadyUsed => - HtmlPage(_templates.Get("html.job-search.already-used.title", lang), _templates.Get("html.job-search.already-used.message", lang)), - StartJobSearchStatus.Expired => - HtmlPage(_templates.Get("html.job-search.expired.title", lang), _templates.Get("html.job-search.expired.message", lang)), - _ => - HtmlPage(_templates.Get("html.job-search.invalid.title", lang), _templates.Get("html.job-search.invalid.message", lang)) + StartJobSearchStatus.Started => (_templates.Get("html.job-search.started.title", lang), _templates.Get("html.job-search.started.message", lang)), + StartJobSearchStatus.AlreadyUsed => (_templates.Get("html.job-search.already-used.title", lang), _templates.Get("html.job-search.already-used.message", lang)), + StartJobSearchStatus.Expired => (_templates.Get("html.job-search.expired.title", lang), _templates.Get("html.job-search.expired.message", lang)), + _ => (_templates.Get("html.job-search.invalid.title", lang), _templates.Get("html.job-search.invalid.message", lang)) }; - return Content(html, "text/html"); + return Content(_templates.Render("html.job-search.shell", "*", ("title", title), ("message", message)), "text/html"); } catch (Exception ex) { _logger.LogError(ex, "Job search start failed for token {Token}.", t); - return Content(HtmlPage(_templates.Get("html.job-search.error.title", "en"), _templates.Get("html.job-search.error.message", "en")), "text/html"); + var title = _templates.Get("html.job-search.error.title", "en"); + var message = _templates.Get("html.job-search.error.message", "en"); + return Content(_templates.Render("html.job-search.shell", "*", ("title", title), ("message", message)), "text/html"); } } - private static string HtmlPage(string title, string message) => $$""" - - - {{title}} - MyAi.ro - - -

{{title}}

{{message}}

- - """; - private async Task CacheUploadedCvAsync(IFormFile file, string documentId, CancellationToken ct) { try diff --git a/Apis/myai-data/Migrations/20260524145351_AddTemplates.cs b/Apis/myai-data/Migrations/20260524145351_AddTemplates.cs index 7099ee3..3b68ef7 100644 --- a/Apis/myai-data/Migrations/20260524145351_AddTemplates.cs +++ b/Apis/myai-data/Migrations/20260524145351_AddTemplates.cs @@ -71,6 +71,11 @@ namespace MyAi.Data.Migrations Row("email.search-results.empty", "en", "MyAi.ro found no jobs matching your CV. Try again later or update your CV.", "No results message for job search results email"); Row("email.search-results.empty", "ro", "MyAi.ro nu a gasit joburi care sa corespunda CV-ului tau. Incercati mai tarziu sau ajustati CV-ul.", "Mesaj fara rezultate pentru emailul de cautare joburi"); + // HTML job-search page shell — wraps title + message in a centered card page + Row("html.job-search.shell", "*", + "{{title}} - MyAi.ro

{{title}}

{{message}}

", + "Full HTML shell for job-search status pages. Placeholders: {{title}}, {{message}}."); + // HTML job-search start page messages Row("html.job-search.started.title", "en", "Job search started", "Title for job search started page"); Row("html.job-search.started.message", "en", "Your job search has started. Results will be sent to your email shortly.", "Message for job search started page"); diff --git a/Apis/myai-data/Migrations/20260601190000_AddHtmlJobSearchShell.cs b/Apis/myai-data/Migrations/20260601190000_AddHtmlJobSearchShell.cs new file mode 100644 index 0000000..87b638a --- /dev/null +++ b/Apis/myai-data/Migrations/20260601190000_AddHtmlJobSearchShell.cs @@ -0,0 +1,37 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using MyAi.Data; + +#nullable disable + +namespace MyAi.Data.Migrations +{ + /// + public partial class AddHtmlJobSearchShell : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + table: "Templates", + columns: ["Key", "Language", "Value", "Description"], + values: new object[] + { + "html.job-search.shell", + "*", + "{{title}} - MyAi.ro

{{title}}

{{message}}

", + "Full HTML shell for job-search status pages. Placeholders: {{title}}, {{message}}." + }, + schema: MigrationConstants.SchemaName); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "Templates", + keyColumns: ["Key", "Language"], + keyValues: new object[] { "html.job-search.shell", "*" }, + schema: MigrationConstants.SchemaName); + } + } +}