feat: Refactor newsletter preferences management and update UI components
This commit is contained in:
parent
028cc39a40
commit
02874677be
@ -6,7 +6,7 @@
|
|||||||
- Email 驗證
|
- Email 驗證
|
||||||
- 個人資料(基本資料、聯絡方式、公司資訊)
|
- 個人資料(基本資料、聯絡方式、公司資訊)
|
||||||
- 收貨地址簿
|
- 收貨地址簿
|
||||||
- 訂閱管理(清單與偏好)
|
- 訂閱管理(清單與退訂)
|
||||||
- 退訂(單一清單)
|
- 退訂(單一清單)
|
||||||
- 連結外站(可選:回到來源站點)
|
- 連結外站(可選:回到來源站點)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@
|
|||||||
- 登入 / 註冊 / 忘記密碼 / 修改密碼
|
- 登入 / 註冊 / 忘記密碼 / 修改密碼
|
||||||
- Email 驗證頁(可自建或導回會員中心)
|
- Email 驗證頁(可自建或導回會員中心)
|
||||||
- 訂閱表單(未登入)
|
- 訂閱表單(未登入)
|
||||||
- 訂閱偏好管理(登入後)
|
- 外站自建訂閱偏好管理(登入後,走 API)
|
||||||
- 退訂頁(從 email token 進來)
|
- 退訂頁(從 email token 進來)
|
||||||
|
|
||||||
### 管理者端
|
### 管理者端
|
||||||
@ -49,7 +49,7 @@
|
|||||||
- UC-05 Email 驗證: `/account/verifyemail?email=...&token=...`
|
- UC-05 Email 驗證: `/account/verifyemail?email=...&token=...`
|
||||||
- UC-07 訂閱確認(double opt-in): `/newsletter/confirm?token=...`
|
- UC-07 訂閱確認(double opt-in): `/newsletter/confirm?token=...`
|
||||||
- UC-08 取消訂閱(單一清單): `/newsletter/unsubscribe?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 會員資料查看 / 編輯: `/profile`
|
||||||
- UC-10.1 收貨地址簿管理: `/profile/addresses`
|
- UC-10.1 收貨地址簿管理: `/profile/addresses`
|
||||||
- UC-10.2 我的電子報訂閱: `/profile/subscriptions`
|
- UC-10.2 我的電子報訂閱: `/profile/subscriptions`
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
- UC-06 訂閱電子報(未登入) [API]
|
- UC-06 訂閱電子報(未登入) [API]
|
||||||
- UC-07 訂閱確認(double opt-in) [UI]
|
- UC-07 訂閱確認(double opt-in) [UI]
|
||||||
- UC-08 取消訂閱(單一清單) [UI]
|
- UC-08 取消訂閱(單一清單) [UI]
|
||||||
- UC-09 訂閱偏好管理(登入後) [API/UI]
|
- UC-09 訂閱偏好管理(登入後) [API]
|
||||||
- UC-10 會員資料查看(Email 為主) [API/UI]
|
- UC-10 會員資料查看(Email 為主) [API/UI]
|
||||||
|
|
||||||
## 管理者端
|
## 管理者端
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using MemberCenter.Application.Abstractions;
|
using MemberCenter.Application.Abstractions;
|
||||||
using MemberCenter.Web.Models.Newsletter;
|
using MemberCenter.Web.Models.Newsletter;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace MemberCenter.Web.Controllers;
|
namespace MemberCenter.Web.Controllers;
|
||||||
|
|
||||||
@ -63,59 +62,4 @@ public class NewsletterController : Controller
|
|||||||
ViewData["Result"] = "Subscription canceled.";
|
ViewData["Result"] = "Subscription canceled.";
|
||||||
return View("UnsubscribeResult");
|
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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; } = "{}";
|
|
||||||
}
|
|
||||||
@ -1,2 +1,2 @@
|
|||||||
<h1>Member Center</h1>
|
<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>
|
||||||
|
|||||||
@ -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>
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
<h1>Preferences</h1>
|
|
||||||
<p>@(ViewData["Result"] ?? "Done")</p>
|
|
||||||
@ -38,7 +38,6 @@
|
|||||||
<a asp-area="" asp-controller="Profile" asp-action="Index">Profile</a>
|
<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="Addresses">Addresses</a>
|
||||||
<a asp-area="" asp-controller="Profile" asp-action="Subscriptions">Subscriptions</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>
|
||||||
</div>
|
</div>
|
||||||
@if (User.IsInRole("admin") || User.IsInRole("superuser"))
|
@if (User.IsInRole("admin") || User.IsInRole("superuser"))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user