Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v 0.6.0 #53

Merged
merged 16 commits into from
Apr 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/iRLeagueManager.Web/Components/DisplayUser.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@using iRLeagueApiCore.Common.Models.Users;

<div title="@@@FallbackName" class="d-flex gap-2">
@if (User is null || (string.IsNullOrEmpty(User.Firstname) && string.IsNullOrEmpty(User.Firstname)))
{
<label>@FallbackName</label>
}
else
{
<label>@User.Firstname @User.Lastname</label>
@if (ShowUserName)
{
<label class="text-muted"><i>@User.UserName</i></label>
}
}
</div>

@code {
[Parameter]
public string FallbackName { get; set; } = string.Empty;
[Parameter]
public UserModel? User { get; set; }
[Parameter]
public bool ShowUserName { get; set; } = true;

protected override void OnParametersSet()
{
if (string.IsNullOrEmpty(FallbackName) && User is not null)
{
FallbackName = User.UserName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@using Blazored.Typeahead
@using iRLeagueApiCore.Common.Models
@using iRLeagueApiCore.Common.Models.Reviews
@using iRLeagueApiCore.Common.Models.Users;
@using iRLeagueManager.Web.ViewModels
@inject NavigationManager NavigationManager

Expand Down
10 changes: 9 additions & 1 deletion src/iRLeagueManager.Web/Components/Reviews/ReviewComment.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@inherits MvvmComponentBase
@using iRLeagueApiCore.Common.Models
@using iRLeagueApiCore.Common.Models.Reviews
@using iRLeagueApiCore.Common.Models.Users;
@using iRLeagueManager.Web.ViewModels

<div class="d-flex justify-content-between align-items-start">
<div>
<h6 class="fw-bold">@Bind(Comment, x => x.AuthorName)</h6>
<h6 class="fw-bold"><DisplayUser User=@GetUser(Comment.AuthorUserId) FallbackName=@Comment.AuthorName /></h6>
<div class="m-1 preserve-format">
@Bind(Comment, x=> x.Text)
</div>
Expand Down Expand Up @@ -36,6 +37,8 @@
public IModalService ModalService { get; set; } = default!;
[CascadingParameter]
public IEnumerable<MemberInfoModel> InvolvedMembers { get; set; } = Array.Empty<MemberInfoModel>();
[CascadingParameter]
public IEnumerable<UserModel> LeagueUsers { get; set; } = Array.Empty<UserModel>();
[Parameter, EditorRequired]
public ReviewCommentViewModel Comment { get; set; } = default!;
[CascadingParameter]
Expand Down Expand Up @@ -101,4 +104,9 @@
await OnStateHasChanged.InvokeAsync();
}
}

private UserModel? GetUser(string userId)
{
return LeagueUsers.FirstOrDefault(x => x.UserId == userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
Debounce=500
placeholder="Type Name ...">
<SelectedTemplate Context=user>
@user?.UserName
<DisplayUser User=@user ShowUserName=false />
</SelectedTemplate>
<ResultTemplate Context=user>
@user.UserName (@user.Firstname @user.Lastname)
<DisplayUser User=@user />
</ResultTemplate>
</BlazoredTypeahead>
<CancelSubmitButtons
Expand Down
70 changes: 70 additions & 0 deletions src/iRLeagueManager.Web/Pages/Member/ConfirmEmail.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@page "/member/{UserId}/confirm/{ConfirmationToken}"
@inject LeagueApiService ApiService
@inject NavigationManager NavigationManager

<div class="container-sm" style="max-width: 790px;">
@if (Success)
{
<p class="mb-3">
Your email has been successfully verified.
You can now log into your account with your username and password
</p>
<a class="btn btn-primary" href="/member/login">
Login
</a>
}
else if (Error)
{
<p>Oops, something went wrong! Please contact the administrator if you continue having problems.</p>
}
else
{
<p>
<span class="spinner-border spinner-border-sm me-1" />Processing email confirmation ...
</p>
}
</div>

@code {
[Parameter]
public string UserId { get; set; } = default!;
[Parameter]
public string ConfirmationToken { get; set; } = default!;

private bool Success { get; set; } = false;
private bool Error { get; set; } = false;

protected override void OnParametersSet()
{
base.OnParametersSet();
BlazorParameterNullException.ThrowIfNull(this, UserId);
BlazorParameterNullException.ThrowIfNull(this, ConfirmationToken);
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender == false)
{
return;
}

var result = await ApiService.Client
.Users()
.WithId(UserId)
.ConfirmEmail(ConfirmationToken)
.Post();
if (result.Success)
{
Success = true;
await InvokeAsync(StateHasChanged);
await Task.Delay(3000);
NavigationManager.NavigateTo("/member/login");
}
else
{
Error = true;
}
await InvokeAsync(StateHasChanged);
}
}
29 changes: 25 additions & 4 deletions src/iRLeagueManager.Web/Pages/Member/Login.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@using System.ComponentModel.DataAnnotations
@using iRLeagueApiCore.Client
@using iRLeagueApiCore.Client.Http
@using iRLeagueApiCore.Common.Responses;
@using iRLeagueManager.Web.Extensions
@inject IConfiguration configuration
@inject ITokenStore tokenStore
Expand All @@ -26,15 +27,28 @@
<InputText @bind-Value="model.Password" type="password" class="form-control" />
<ValidationMessage For="@(() => model.Password)" />
</div>
<button disabled="@loading" class="btn btn-primary mb-3">
<FormValidationMessage TValue=string Message=@ResultValidator?.ErrorMessage />
@if (ResendConfirmation)
{
<a href="./member/resend-confirmation"><p>Resend confirmation Email</p></a>
}
<button disabled="@loading" class="btn btn-primary mt-3 mb-3">
@if (loading)
{
<span class="spinner-border spinner-border-sm mr-1"></span>
}
Login
</button>
</EditForm>
<a href="./member/PasswordReset">Forgot password</a>
<div class="mb-3">
<a href="./member/PasswordReset">Forgot password</a>
</div>
<div>
<small>Not a member yet?</small>
</div>
@*<button class="btn btn-secondary" @onclick=@(() => NavigationManager.NavigateTo("/member/register"))>
Sign Up
</button>*@
</div>
</div>
</div>
Expand All @@ -51,7 +65,9 @@
private bool loading;
public bool Loading { get => loading; set { loading = value; InvokeAsync(StateHasChanged); } }

private StatusResultValidator ResultValidator { get; set; } = default!;
private bool ResendConfirmation { get; set; } = false;

private StatusResultValidator? ResultValidator { get; set; }

public User model = new User();

Expand Down Expand Up @@ -85,10 +101,15 @@
try
{
Loading = true;
ResendConfirmation = false;
var result = await ApiClient.LogIn(model.Username, model.Password);
if (result.Success == false)
{
ResultValidator.ValidateResult(result.ToStatusResult());
ResultValidator?.ValidateResult(result.ToStatusResult());
if (result.ToStatusResult().Message == "MailConfirm")
{
ResendConfirmation = true;
}
return;
}
var returnUrl = NavigationManager.QueryString("returnUrl") ?? "";
Expand Down
7 changes: 4 additions & 3 deletions src/iRLeagueManager.Web/Pages/Member/PasswordReset.razor
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
}
Set Password
</button>

</EditForm>
</div>
</div>
Expand All @@ -55,7 +56,7 @@

private bool Success { get; set; }

private StatusResultValidator ResultValidator { get; set; } = default!;
private StatusResultValidator? ResultValidator { get; set; }

public record SetPassword
{
Expand All @@ -81,12 +82,12 @@
Loading = true;
var token = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(ResetToken));
var requestUrl = $"Authenticate/SetPassword/{UserId}";
var request = ApiService.Client.CustomEndpoint(requestUrl)
var request = ApiService.Client.CustomEndpoint<object>(requestUrl)
.Post(new { PasswordToken = token, NewPassword = model.NewPassword});
var result = await request;
if (result.Success == false)
{
ResultValidator.ValidateResult(result.ToStatusResult());
ResultValidator?.ValidateResult(result.ToStatusResult());
return;
}
Success = true;
Expand Down
90 changes: 90 additions & 0 deletions src/iRLeagueManager.Web/Pages/Member/Profile.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
@page "/member/{UserId}/profile"
@inject UserViewModel User;
@using iRLeagueApiCore.Common.Models.Users;

<div class="container-sm" style="max-width: 790px;">
<div class="card">
<div class="card-header">
<label>User Profile</label>
</div>
<div class="card-body">
<AuthorizeView [email protected] Resource=@UserId Context="AuthorizeContext">
<Authorized>
<EditForm Model=@User>
<div class="d-flex flex-column gap-3">
<StatusResultValidator @ref=ResultValidator />
<div class="form-group">
<label>Username</label>
<input [email protected] class="form-control" disabled/>
<ValidationMessage For="@(() => User.UserName)" />
</div>
<div class="form-group">
<label>Firstname</label>
<InputText @bind-Value="User.Firstname" class="form-control" />
<ValidationMessage For="@(() => User.Firstname)" />
</div>
<div class="form-group">
<label>Lastname</label>
<InputText @bind-Value="User.Lastname" class="form-control" />
<ValidationMessage For="@(() => User.Lastname)" />
</div>
<div class="form-check">
<InputCheckbox @bind-Value="User.ShowFullname" class="form-check-input" type="checkbox" id="show-fullname" />
<label class="form-check-label" for="show-fullname">
Allow other users to view your firstname & lastname
</label>
</div>
<div class="form-group">
<label>Email</label>
<InputText @bind-Value="User.Email" type="email" class="form-control" disabled/>
<ValidationMessage For="@(() => User.Email)" />
</div>
@if (User.HasChanged)
{
<div class="d-flex gap-3 mt-3">
<button class="btn btn-primary" @onclick=SaveChanges>
@if (User.Loading)
{
<span class="spinner-border spinner-border-sm mr-1"></span>
}
Save
</button>
<button class="btn btn-outline-secondary" type="button" @onclick=@(() => User.LoadUser(User.UserId))>
Reset
</button>
</div>
}
</div>
</EditForm>
</Authorized>
</AuthorizeView>
</div>
</div>
</div>

@code {
[Parameter]
public string UserId { get; set; } = default!;

private StatusResultValidator? ResultValidator { get; set; }

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender == false)
{
return;
}
await User.LoadUser(UserId);
await InvokeAsync(StateHasChanged);
}

private async Task SaveChanges()
{
var result = await User.SaveChangesAsync();
if (result.IsSuccess == false)
{
ResultValidator?.ValidateResult(result);
}
}
}
Loading