refactor: Simplify ChangePresentationInfosRequest by removing phone number and email fields; update related API endpoints for email and phone number management

This commit is contained in:
2025-04-24 04:43:41 -04:00
parent 06ac4c9624
commit 36846405a5
5 changed files with 146 additions and 24 deletions

View File

@@ -0,0 +1,70 @@
using FluentValidation;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Hutopy.Web.Features.Contents.Data;
using Hutopy.Web.Common.Security;
namespace Hutopy.Web.Features.Contents.Handlers;
[PublicAPI]
public record ChangeEmailRequest(
Guid CreatorId,
string? Email);
[PublicAPI]
public sealed class ChangeEmailRequestValidator : Validator<ChangeEmailRequest>
{
public ChangeEmailRequestValidator()
{
RuleFor(x => x.CreatorId)
.NotEmpty()
.WithMessage("Creator ID is required");
RuleFor(x => x.Email)
.Must(email => email == null || !string.IsNullOrWhiteSpace(email))
.WithMessage("Email cannot be empty if provided");
}
}
[PublicAPI]
public class ChangeEmailHandler(
ContentDbContext context)
: Endpoint<ChangeEmailRequest>
{
public override void Configure()
{
Post("/api/creators/{CreatorId}/email");
Options(o => o.WithTags("Creators"));
}
public override async Task HandleAsync(
ChangeEmailRequest request,
CancellationToken ct)
{
var creator = await context
.Creators
.Include(c => c.Presentation)
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
if (creator is null)
{
await SendNotFoundAsync(ct);
return;
}
// Check if the current user is the creator
if (creator.CreatedBy != User.GetUserId())
{
await SendUnauthorizedAsync(ct);
return;
}
creator.Presentation.Email = request.Email?.Trim();
await context.SaveChangesAsync(ct);
await SendOkAsync(ct);
}
}

View File

@@ -0,0 +1,70 @@
using FluentValidation;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Hutopy.Web.Features.Contents.Data;
using Hutopy.Web.Common.Security;
namespace Hutopy.Web.Features.Contents.Handlers;
[PublicAPI]
public record ChangePhoneNumberRequest(
Guid CreatorId,
string? PhoneNumber);
[PublicAPI]
public sealed class ChangePhoneNumberRequestValidator : Validator<ChangePhoneNumberRequest>
{
public ChangePhoneNumberRequestValidator()
{
RuleFor(x => x.CreatorId)
.NotEmpty()
.WithMessage("Creator ID is required");
RuleFor(x => x.PhoneNumber)
.Must(phone => phone == null || !string.IsNullOrWhiteSpace(phone))
.WithMessage("Phone number cannot be empty if provided");
}
}
[PublicAPI]
public class ChangePhoneNumberHandler(
ContentDbContext context)
: Endpoint<ChangePhoneNumberRequest>
{
public override void Configure()
{
Post("/api/creators/{CreatorId}/phone");
Options(o => o.WithTags("Creators"));
}
public override async Task HandleAsync(
ChangePhoneNumberRequest request,
CancellationToken ct)
{
var creator = await context
.Creators
.Include(c => c.Presentation)
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
if (creator is null)
{
await SendNotFoundAsync(ct);
return;
}
// Check if the current user is the creator
if (creator.CreatedBy != User.GetUserId())
{
await SendUnauthorizedAsync(ct);
return;
}
creator.Presentation.PhoneNumber = request.PhoneNumber?.Trim();
await context.SaveChangesAsync(ct);
await SendOkAsync(ct);
}
}

View File

@@ -7,9 +7,7 @@ namespace Hutopy.Web.Features.Contents.Handlers;
public record ChangePresentationInfosRequest( public record ChangePresentationInfosRequest(
Guid CreatorId, Guid CreatorId,
string Description, string Description,
string? VideoUrl, string? VideoUrl);
string? PhoneNumber,
string? Email);
[PublicAPI] [PublicAPI]
public sealed class ChangePresentationInfosRequestValidator : Validator<ChangePresentationInfosRequest> public sealed class ChangePresentationInfosRequestValidator : Validator<ChangePresentationInfosRequest>
@@ -27,14 +25,6 @@ public sealed class ChangePresentationInfosRequestValidator : Validator<ChangePr
RuleFor(x => x.VideoUrl) RuleFor(x => x.VideoUrl)
.Must(url => url == null || YouTubeUrlHelper.IsValidYouTubeUrlOrId(url)) .Must(url => url == null || YouTubeUrlHelper.IsValidYouTubeUrlOrId(url))
.WithMessage("Invalid YouTube URL or video ID format"); .WithMessage("Invalid YouTube URL or video ID format");
RuleFor(x => x.PhoneNumber)
.Must(phone => phone == null || !string.IsNullOrWhiteSpace(phone))
.WithMessage("Phone number cannot be empty if provided");
RuleFor(x => x.Email)
.Must(email => email == null || !string.IsNullOrWhiteSpace(email))
.WithMessage("Email cannot be empty if provided");
} }
} }
@@ -71,8 +61,6 @@ public class ChangePresentationInfosHandler(
creator.Presentation.VideoUrl = request.VideoUrl != null creator.Presentation.VideoUrl = request.VideoUrl != null
? YouTubeUrlHelper.ExtractVideoId(request.VideoUrl.Trim()) ? YouTubeUrlHelper.ExtractVideoId(request.VideoUrl.Trim())
: null; : null;
creator.Presentation.PhoneNumber = request.PhoneNumber?.Trim();
creator.Presentation.Email = request.Email?.Trim();
await context.SaveChangesAsync(ct); await context.SaveChangesAsync(ct);

View File

@@ -50,13 +50,10 @@ async function saveEmail() {
try { try {
isLoading.value = true; isLoading.value = true;
// Save presentation info // Save email
await client.post( await client.post(
`/api/creators/${props.creator.id}/presentation-infos`, `/api/creators/${props.creator.id}/email`,
{ {
description: props.creator.presentation?.description || "",
videoUrl: props.creator.presentation?.videoUrl || "",
phoneNumber: props.creator.presentation?.phoneNumber || "",
email: email.value || "" email: email.value || ""
} }
); );

View File

@@ -50,14 +50,11 @@ async function savePhoneNumber() {
try { try {
isLoading.value = true; isLoading.value = true;
// Save presentation info // Save phone number
await client.post( await client.post(
`/api/creators/${props.creator.id}/presentation-infos`, `/api/creators/${props.creator.id}/phone`,
{ {
description: props.creator.presentation?.description || "", phoneNumber: phoneNumber.value || ""
videoUrl: props.creator.presentation?.videoUrl || "",
phoneNumber: phoneNumber.value || "",
email: props.creator.presentation?.email || ""
} }
); );