feat: Refactor newsletter preferences management and update UI components

This commit is contained in:
warrenchen 2026-04-17 16:47:20 +09:00
parent 028cc39a40
commit 02874677be
8 changed files with 5 additions and 90 deletions

View File

@ -6,7 +6,7 @@
- Email 驗證
- 個人資料(基本資料、聯絡方式、公司資訊)
- 收貨地址簿
- 訂閱管理(清單與偏好
- 訂閱管理(清單與退訂
- 退訂(單一清單)
- 連結外站(可選:回到來源站點)
@ -24,7 +24,7 @@
- 登入 / 註冊 / 忘記密碼 / 修改密碼
- Email 驗證頁(可自建或導回會員中心)
- 訂閱表單(未登入)
- 訂閱偏好管理(登入後)
- 外站自建訂閱偏好管理(登入後,走 API
- 退訂頁(從 email token 進來)
### 管理者端
@ -49,7 +49,7 @@
- UC-05 Email 驗證: `/account/verifyemail?email=...&token=...`
- UC-07 訂閱確認double opt-in: `/newsletter/confirm?token=...`
- UC-08 取消訂閱(單一清單): `/newsletter/unsubscribe?token=...`
- UC-09 訂閱偏好管理(登入後: `/newsletter/preferences?list_id=...&email=...`
- UC-09 訂閱偏好管理(外站整合 API: `/newsletter/preferences?list_id=...&email=...`
- UC-10 會員資料查看 / 編輯: `/profile`
- UC-10.1 收貨地址簿管理: `/profile/addresses`
- UC-10.2 我的電子報訂閱: `/profile/subscriptions`

View File

@ -14,7 +14,7 @@
- UC-06 訂閱電子報(未登入) [API]
- UC-07 訂閱確認double opt-in [UI]
- UC-08 取消訂閱(單一清單) [UI]
- UC-09 訂閱偏好管理(登入後) [API/UI]
- UC-09 訂閱偏好管理(登入後) [API]
- UC-10 會員資料查看Email 為主) [API/UI]
## 管理者端

View File

@ -1,7 +1,6 @@
using MemberCenter.Application.Abstractions;
using MemberCenter.Web.Models.Newsletter;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace MemberCenter.Web.Controllers;
@ -63,59 +62,4 @@ public class NewsletterController : Controller
ViewData["Result"] = "Subscription canceled.";
return View("UnsubscribeResult");
}
[HttpGet]
public async Task<IActionResult> Preferences([FromQuery(Name = "list_id")] Guid listId, [FromQuery] string email)
{
var subscription = await _newsletterService.GetPreferencesAsync(listId, email);
if (subscription is null)
{
ViewData["Result"] = "Subscription not found.";
return View("PreferencesResult");
}
return View(new PreferencesViewModel
{
ListId = listId,
Email = email,
PreferencesJson = subscription.Preferences.GetRawText()
});
}
[HttpPost]
public async Task<IActionResult> Preferences(PreferencesViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
Dictionary<string, object>? preferences = null;
try
{
preferences = JsonSerializer.Deserialize<Dictionary<string, object>>(model.PreferencesJson);
}
catch
{
ModelState.AddModelError(string.Empty, "Invalid JSON.");
return View(model);
}
var existing = await _newsletterService.GetPreferencesAsync(model.ListId, model.Email);
if (existing is null)
{
ViewData["Result"] = "Subscription not found.";
return View("PreferencesResult");
}
var subscription = await _newsletterService.UpdatePreferencesAsync(model.ListId, model.Email, preferences ?? new Dictionary<string, object>());
if (subscription is null)
{
ViewData["Result"] = "Subscription not found.";
return View("PreferencesResult");
}
ViewData["Result"] = "Preferences updated.";
return View("PreferencesResult");
}
}

View File

@ -1,15 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace MemberCenter.Web.Models.Newsletter;
public sealed class PreferencesViewModel
{
[Required]
public Guid ListId { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; } = string.Empty;
public string PreferencesJson { get; set; } = "{}";
}

View File

@ -1,2 +1,2 @@
<h1>Member Center</h1>
<p>Use this portal for account access and newsletter preferences.</p>
<p>Use this portal for account access, profile management, addresses, and subscriptions.</p>

View File

@ -1,11 +0,0 @@
@model MemberCenter.Web.Models.Newsletter.PreferencesViewModel
<h1>Preferences</h1>
<form method="post">
<input asp-for="ListId" type="hidden" />
<input asp-for="Email" type="hidden" />
<label>Preferences JSON</label>
<textarea asp-for="PreferencesJson" rows="6"></textarea>
<span asp-validation-for="PreferencesJson"></span>
<button type="submit">Save</button>
</form>

View File

@ -1,2 +0,0 @@
<h1>Preferences</h1>
<p>@(ViewData["Result"] ?? "Done")</p>

View File

@ -38,7 +38,6 @@
<a asp-area="" asp-controller="Profile" asp-action="Index">Profile</a>
<a asp-area="" asp-controller="Profile" asp-action="Addresses">Addresses</a>
<a asp-area="" asp-controller="Profile" asp-action="Subscriptions">Subscriptions</a>
<a asp-area="" asp-controller="Newsletter" asp-action="Preferences">Preferences</a>
</div>
</div>
@if (User.IsInRole("admin") || User.IsInRole("superuser"))