Skip to content

Commit

Permalink
more minor improvements here and there
Browse files Browse the repository at this point in the history
  • Loading branch information
NielsPilgaard committed Aug 9, 2024
1 parent 7ce13a9 commit ad98649
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 135 deletions.
46 changes: 23 additions & 23 deletions src/shared/Jordnaer.Shared/Database/Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,36 @@ namespace Jordnaer.Shared;
[Index(nameof(Name), IsUnique = true)]
public class Group
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }

[Url]
public string? ProfilePictureUrl { get; set; }
[Url]
public string? ProfilePictureUrl { get; set; }

[MaxLength(500, ErrorMessage = "Adresse må højest være 500 karakterer langt.")]
public string? Address { get; set; }
[MaxLength(500, ErrorMessage = "Adresse må højest være 500 karakterer langt.")]
public string? Address { get; set; }

[DanishZipCode(ErrorMessage = "Post nummer skal være mellem 1000 og 9999")]
public int? ZipCode { get; set; }
[DanishZipCode(ErrorMessage = "Post nummer skal være mellem 1000 og 9999")]
public int? ZipCode { get; set; }

[MaxLength(100, ErrorMessage = "By navn må højest være 100 karakterer langt.")]
public string? City { get; set; }
[MaxLength(100, ErrorMessage = "By navn må højest være 100 karakterer langt.")]
public string? City { get; set; }

[MinLength(2, ErrorMessage = "Gruppe navn skal være mindst 2 karakterer langt.")]
[MaxLength(128, ErrorMessage = "Gruppens navn må højest være 128 karakterer lang.")]
public required string Name { get; set; }
[MinLength(2, ErrorMessage = "Gruppe navn skal være mindst 2 karakterer langt.")]
[MaxLength(128, ErrorMessage = "Gruppens navn må højest være 128 karakterer lang.")]
public required string Name { get; set; }

[Required(ErrorMessage = "Påkrævet.")]
[MaxLength(200, ErrorMessage = "Gruppens beskrivelse må højest være 200 karakterer lang.")]
public required string ShortDescription { get; set; }
[Required(ErrorMessage = "Påkrævet.")]
[MaxLength(200, ErrorMessage = "Gruppens beskrivelse må højest være 200 karakterer lang.")]
public required string ShortDescription { get; set; }

[MaxLength(4000, ErrorMessage = "Gruppens beskrivelse må højest være 4000 karakterer lang.")]
public string? Description { get; set; }
[MaxLength(4000, ErrorMessage = "Gruppens beskrivelse må højest være 4000 karakterer lang.")]
public string? Description { get; set; }

public List<UserProfile> Members { get; set; } = new();
public List<GroupMembership> Memberships { get; set; } = new();
public List<Category> Categories { get; set; } = new();
public List<UserProfile> Members { get; set; } = new();
public List<GroupMembership> Memberships { get; set; } = new();
public List<Category> Categories { get; set; } = new();

public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
}
14 changes: 7 additions & 7 deletions src/web/Jordnaer/Features/Email/EmailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Jordnaer.Features.Email;
public interface IEmailService
{
Task SendEmailFromContactForm(ContactForm contactForm, CancellationToken cancellationToken = default);
Task SendMembershipRequestEmails(Guid groupId, CancellationToken cancellationToken = default);
Task SendMembershipRequestEmails(string groupName, CancellationToken cancellationToken = default);
}

public sealed class EmailService(IPublishEndpoint publishEndpoint,
Expand Down Expand Up @@ -40,15 +40,15 @@ public async Task SendEmailFromContactForm(
}

public async Task SendMembershipRequestEmails(
Guid groupId,
string groupName,
CancellationToken cancellationToken = default)
{
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
var membersThatCanApproveRequest = context
.GroupMemberships
.AsNoTracking()
.Where(x =>
x.GroupId == groupId &&
x.Group.Name == groupName &&
x.PermissionLevel == PermissionLevel.Admin)
.Select(x => x.UserProfileId);

Expand All @@ -60,15 +60,15 @@ public async Task SendMembershipRequestEmails(

if (emails.Count is 0)
{
logger.LogError("No users found who can approve membership request for group {GroupId}.", groupId);
logger.LogError("No users found who can approve membership request for group {GroupName}.", groupName);
return;
}

logger.LogInformation("Found {MembersThatCanApproveRequestCount} users who can approve " +
"membership request for group {GroupId}. " +
"Sending an email to them.", emails.Count, groupId);
"membership request for group {GroupName}. " +
"Sending an email to them.", emails.Count, groupName);

var groupMembershipUrl = $"{navigationManager.BaseUri}/groups/{groupId}/memberships";
var groupMembershipUrl = $"{navigationManager.BaseUri}groups/{groupName}/memberships";

List<EmailAddress> toEmail = [emails.First()];
var email = new SendEmail
Expand Down
31 changes: 18 additions & 13 deletions src/web/Jordnaer/Features/GroupSearch/GroupCard.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<MudCard Elevation="3">
<MudCardContent>
<MudImage ObjectPosition="ObjectPosition.Left"
Style="border-radius: 10%"
Src="@Group.ProfilePictureUrl"
Class="mb-3"
loading="lazy" />

@if (Group.ProfilePictureUrl is not null)
{
<MudImage ObjectPosition="ObjectPosition.Left"
Style="border-radius: 10%"
Src="@Group.ProfilePictureUrl"
Class="mb-3"
loading="lazy" />
}
<MudTextField Label="Navn"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.AlternateEmail"
Expand All @@ -20,24 +22,27 @@
T="string"
Text="@Group.DisplayLocation()" />

<MudTextField Label="Kort beskrivelse"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Description"
ReadOnly
T="string"
Text="@Group.ShortDescription" />
@if (!string.IsNullOrEmpty(Group.ShortDescription))
{
<MudTextField Label="Kort beskrivelse"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Description"
ReadOnly
T="string"
Text="@Group.ShortDescription" />
}

@if (Group.Categories.Length > 0)
{
<MudChipField ChipColor="Color.Tertiary"
Class="hide-child-inputs"
Label="Kategorier"
Values="Group.Categories.ToList()"
T="string"
ReadOnly
ChipVariant="Variant.Filled"
Closeable="false"
Clearable="false"
Class="ms-0"
WrapChips />
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,37 @@
<MudNavLink Class="card-link" Href="@($"/groups/{group.Name}")">
<MudCard Class="pa-3 my-3 card-hover" Elevation="3">
<MudCardContent Class="d-flex flex-column align-center">
<MudTextField Label="Navn" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.AlternateEmail" ReadOnly T="string" Text="@group.Name" Class="mb-5" />
<MudImage Fluid Width="200" Style="border-radius: 25%" Src="@group.ProfilePictureUrl" loading="lazy" />
<MudTextField Label="Område" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Place" ReadOnly T="string" Text="@group.DisplayLocation()" />
<MudTextField Label="Navn"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.AlternateEmail"
ReadOnly
T="string"
Text="@group.Name"
Class="mb-5" />

@if (group.Categories.Any())
@if (!string.IsNullOrEmpty(group.ProfilePictureUrl))
{
<MudDivider Class="my-4" />
<MudImage Fluid
Width="200"
Style="border-radius: 25%"
Src="@group.ProfilePictureUrl"
loading="lazy" />
}

<MudTextField Label="Område"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Place"
ReadOnly
T="string"
Text="@group.DisplayLocation()"
Class="mb-4" />

<MudText Typo="Typo.h6"><MudIcon Class="mr-2" Icon="@Icons.Material.Filled.Star" />Kategorier</MudText>
@if (group.Categories.Length is not 0)
{
<div class="d-flex align-center">
<MudIcon Class="mr-1" Icon="@Icons.Material.Filled.Star" />
<MudText Typo="Typo.h6">Kategorier</MudText>
</div>
<MudChipSet ReadOnly Class="d-flex flex-wrap justify-center flex-grow-1" T="MudChip<string>">
@foreach (var category in group.Categories)
{
Expand Down
13 changes: 6 additions & 7 deletions src/web/Jordnaer/Features/Groups/GroupMemberListComponent.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
}
else
{
<MudList ReadOnly="false" T="RenderFragment">
<MudList ReadOnly="CurrentUserIsAdmin" T="RenderFragment">
<MudListSubheader>
@if (IsGroupModerator)
@if (CurrentUserIsAdmin)
{
<MudListItem Icon="@Icons.Material.Filled.Edit"
Href="@($"/groups/{GroupName}/members")">
Expand All @@ -33,13 +33,12 @@ else
</MudList>
}
@code {

[Parameter]
[Parameter, EditorRequired]
public string? GroupName { get; set; }

[Parameter]
public bool IsGroupModerator { get; set; } = false;
[Parameter, EditorRequired]
public bool CurrentUserIsAdmin { get; set; } = false;

[Parameter]
[Parameter, EditorRequired]
public required List<UserSlim>? GroupMembers { get; set; }
}
23 changes: 13 additions & 10 deletions src/web/Jordnaer/Features/Membership/MembershipService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Jordnaer.Features.Membership;
public interface IMembershipService
{
Task<OneOf<Success, Error<MembershipStatus>, Error<string>>> RequestMembership(
Guid groupId,
string groupName,
CancellationToken cancellationToken = default);
}

Expand All @@ -22,7 +22,7 @@ public class MembershipService(CurrentUser currentUser,
ILogger<MembershipService> logger) : IMembershipService
{
public async Task<OneOf<Success, Error<MembershipStatus>, Error<string>>> RequestMembership(
Guid groupId,
string groupName,
CancellationToken cancellationToken = default)
{
logger.LogFunctionBegan();
Expand All @@ -31,21 +31,24 @@ public async Task<OneOf<Success, Error<MembershipStatus>, Error<string>>> Reques
{
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);

var existingMembership = await context
.GroupMemberships
.FirstOrDefaultAsync(x =>
x.GroupId == groupId &&
x.UserProfileId == currentUser.Id,
cancellationToken);
var group = await context.Groups
.Where(x => x.Name == groupName)
.Include(x => x.Memberships.Where(membership => membership.UserProfileId == currentUser.Id))
.FirstOrDefaultAsync(cancellationToken);
if (group is null)
{
return new Error<string>($"Gruppen {groupName} kunne ikke findes.");
}

var existingMembership = group.Memberships.FirstOrDefault(x => x.UserProfileId == currentUser.Id);
if (existingMembership is not null)
{
return new Error<MembershipStatus>(existingMembership.MembershipStatus);
}

context.GroupMemberships.Add(new GroupMembership
{
GroupId = groupId,
GroupId = group.Id,
UserProfileId = currentUser.Id!,
MembershipStatus = MembershipStatus.PendingApprovalFromGroup,
PermissionLevel = PermissionLevel.Write,
Expand All @@ -57,7 +60,7 @@ public async Task<OneOf<Success, Error<MembershipStatus>, Error<string>>> Reques

await context.SaveChangesAsync(cancellationToken);

await emailService.SendMembershipRequestEmails(groupId, cancellationToken);
await emailService.SendMembershipRequestEmails(groupName, cancellationToken);

return new Success();
}
Expand Down
Loading

0 comments on commit ad98649

Please sign in to comment.