Commit Graph

11 Commits

Author SHA1 Message Date
Anatolii Grynchuk b0996833bc feat: add RabbitMQ worker, contracts, usage UI in channels screen
- Add HrynCo.NotificationService.Contracts project with SendEmailMessage and NotificationResultMessage
- Add SendEmailConsumer (RabbitMQ worker) with reply-to pattern via CorrelationContext.ReplyTo
- Add SendEmailHandler owning SMTP send + usage increment as business logic
- Add GetChannelUsageSummaryHandler with single DB query via navigation property
- Merge usage stats inline into channels list (daily/monthly with progress bars)
- Refactor AdminChannelsController.Index to use GetChannelUsageSummaryQuery
- Add RabbitMQ service to docker-compose files
- Remove dead AdminChannelUsageController, ChannelUsageViewModel, ChannelUsageSummary

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 14:00:58 +03:00
Anatolii Grynchuk 6434e3e636 fix: serve bootstrap locally, fix modal button null reference
- Replace CDN bootstrap with local /lib/bootstrap/ - CDN SRI hash was
  mismatching and blocking the script entirely (no Bootstrap = no modals)
- Fix addEventListener null error: script runs before @section FormActions
  renders the button, so use document-level event delegation instead

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:45:20 +03:00
Anatolii Grynchuk 7587e7fd17 fix: move test modal to view body, wire button via addEventListener
Razor section forwarding across nested layouts is unreliable.
Modal div and script are now directly in Edit.cshtml body (not in
any section) so they are always in the DOM when the page renders.
Button uses addEventListener instead of inline onclick to decouple
from layout rendering order.

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:43:25 +03:00
Anatolii Grynchuk c2ad3c7f3e fix: prevent browser from clearing username field on channel edit
autocomplete=off is ignored by Chrome/Firefox when a password field is
present - they clear the username value after page load. Use
autocomplete=new-password on both fields to signal a new-credential
context and prevent autofill interference.

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:30:44 +03:00
Anatolii Grynchuk 215285d3c0 fix: channel save tracking conflict and test modal rendering
- Use AsNoTracking() on all EmailChannelRepository read methods to prevent
  EF identity conflict when Update() attaches a new entity with same key
- Move test modal to @section Scripts rendered at end of <body> so
  bootstrap.Modal is available and modal is not nested inside card DOM
- Add @RenderSection('Scripts') forwarding in _EditorLayout to bubble
  child scripts sections up to _Layout
- Switch Test button to programmatic bootstrap.Modal() open instead of
  data-bs-toggle (more reliable across layout section boundaries)

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:29:54 +03:00
Anatolii Grynchuk 2b272e989b refactor: channel holds delivery config only — remove AppDisplayName, AppBaseUrl
- SmtpChannelSettings: Host, Port, Username, Password, UseSsl, FromEmail, FromName only
- AppDisplayName and AppBaseUrl moved to template variables (payload responsibility)
- Updated ViewModel, controller Save/Edit mapping, and Edit view accordingly

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 03:08:12 +03:00
Anatolii Grynchuk 61ccf9c777 feat: add test channel feature in admin UI
- POST /admin/channels/{id}/test — direct SMTP send via MailKit
- Test button shown only on existing channels (not create)
- Bootstrap modal with recipient email input and spinner
- Inline success/error result inside the modal

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 02:57:36 +03:00
Anatolii Grynchuk 936d41c2f1 feat: improved admin UI styles and layout
- Max-width 860px on editor card
- Two-column row for ServiceName/Key/Language fields
- Gradient card header, proper shadow, grey footer
- Footer buttons right-aligned
- Smaller uppercase table headers, better typography
- Overhauled admin.css with CSS variables and cleaner rules

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 02:51:58 +03:00
Anatolii Grynchuk c90b07386d feat: polished admin UI styles + email channels admin CRUD
- Extract inline styles to wwwroot/css/admin.css
- Bootstrap Icons for nav and buttons
- Styled page headers, table, empty state, readonly fields
- Email Channels admin: list, create, edit, delete
- GetAllEmailChannelsQuery + handler
- AdminChannelsController with full CRUD
- form id + form= attribute pattern for EditorLayout footer buttons

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 02:43:59 +03:00
Anatolii Grynchuk 855d0862f9 fix: save button not submitting — form id + form= attribute on submit button; migrator connection string in dev compose
- _EditorLayout renders FormActions section outside <form> in the DOM
- Added id='templateForm' to form, form='templateForm' to submit button (HTML5 form association)
- Added migrator env override in docker-compose.Development.yml so connection string is not read from \

Ref: IT-628

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 02:35:01 +03:00
Anatolii Grynchuk 2a0a5f737d feat: add MVC Razor admin UI for email templates
- GetAllEmailTemplatesQuery + handler (new GetAll use case)
- IEmailTemplateRepository.GetAllAsync + EF implementation
- AdminTemplatesController: Index, Create, Edit, Save, Delete
- EmailTemplateEditViewModel with IsNew/PageTitle helpers
- Views/_ViewStart, _ViewImports, Shared/_Layout (Bootstrap 5)
- Shared/_EditorLayout (chained layout for all edit screens)
- Views/AdminTemplates/Index (table with edit/delete actions)
- Views/AdminTemplates/Edit (card form, readonly composite key on edit)
- Program.cs: AddControllersWithViews, UseStaticFiles, MapDefaultControllerRoute

Ref: IT-634

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-02 02:06:08 +03:00