~register page

main
Peace 9 months ago
parent 9153dabed7
commit 3d7ae02b39
  1. 4
      FluentBlazorApp/FluentBlazorApp/Components/Layout/NavMenu.razor
  2. 9
      FluentBlazorApp/FluentBlazorApp/Components/Pages/Home.razor
  3. 4
      FluentBlazorApp/FluentBlazorApp/Components/Pages/Login.razor
  4. 46
      FluentBlazorApp/FluentBlazorApp/Components/Pages/Register.razor
  5. 26
      FluentBlazorApp/FluentBlazorApp/Components/Pages/Weather.razor
  6. 17
      FluentBlazorApp/FluentBlazorApp/Controllers/AccountController.cs
  7. 5
      FluentBlazorApp/FluentBlazorApp/DTOs/LoginDTO.cs
  8. 3
      FluentBlazorApp/FluentBlazorApp/DTOs/RegisterDTO.cs
  9. 10
      FluentBlazorApp/FluentBlazorApp/DTOs/WeatherForecastDTO.cs
  10. 8
      FluentBlazorApp/FluentBlazorApp/FluentBlazorApp.csproj
  11. 8
      FluentBlazorApp/FluentBlazorApp/Migrations/20240805064123_InitialCreate.Designer.cs
  12. 4
      FluentBlazorApp/FluentBlazorApp/Migrations/20240805064123_InitialCreate.cs
  13. 4
      FluentBlazorApp/FluentBlazorApp/Migrations/AppDbContextModelSnapshot.cs
  14. 2
      FluentBlazorApp/FluentBlazorApp/Models/ApplicationUser.cs
  15. 1
      FluentBlazorApp/FluentBlazorApp/Repos/Account.cs
  16. 10
      FluentBlazorApp/FluentBlazorApp/Services/AccountService.cs
  17. 1
      FluentBlazorApp/FluentBlazorApp/Services/IAccountService.cs

@ -6,8 +6,12 @@
<nav class="sitenav" aria-labelledby="main-menu">
<FluentNavMenu Id="main-menu" Collapsible="true" Width="250" Title="Navigation menu" @bind-Expanded="expanded" CustomToggle="true">
<FluentNavLink Href="/" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.Home())" IconColor="Color.Accent">Home</FluentNavLink>
<AuthorizeView>
<Authorized>
<FluentNavLink Href="counter" Icon="@(new Icons.Regular.Size20.NumberSymbolSquare())" IconColor="Color.Accent">Counter</FluentNavLink>
<FluentNavLink Href="weather" Icon="@(new Icons.Regular.Size20.WeatherPartlyCloudyDay())" IconColor="Color.Accent">Weather</FluentNavLink>
</Authorized>
</AuthorizeView>
<FluentNavLink Href="login" Icon="@(new Icons.Regular.Size20.PersonPasskey())" IconColor="Color.Accent">Login</FluentNavLink>
<FluentNavLink Href="register" Icon="@(new Icons.Regular.Size20.PersonAdd())" IconColor="Color.Accent">Register</FluentNavLink>
</FluentNavMenu>

@ -4,4 +4,11 @@
<h1>Hello, world!</h1>
Welcome to your new Fluent Blazor app.
<AuthorizeView>
<Authorized>
<h3>Hi, @(context.User.Identity!.Name), Welcome</h3>
</Authorized>
<NotAuthorized>
<h3>You are not logged in</h3>
</NotAuthorized>
</AuthorizeView>

@ -9,9 +9,9 @@
<DataAnnotationsValidator/>
<FluentValidationSummary/>
<FluentStack Orientation="Orientation.Vertical">
<FluentStack Orientation="Orientation.Vertical" VerticalGap="5">
<div>
<FluentTextField @bind-Value="login.Name" Label="Id" Required/>
<FluentTextField @bind-Value="login.Name" Label="Name" Required/>
<FluentValidationMessage For="@(() => login.Name)"/>
</div>
<div>

@ -0,0 +1,46 @@
@page "/register"
@inject IToastService ToastService
@rendermode RenderMode.InteractiveServer
<FluentGrid Justify="JustifyContent.Center">
<FluentGridItem sm="4">
<h2>Login</h2>
<FluentEditForm Model="@register" OnValidSubmit="@OnRegisterSubmit">
<DataAnnotationsValidator/>
<FluentValidationSummary/>
<FluentStack Orientation="Orientation.Vertical" VerticalGap="5">
<div>
<FluentTextField @bind-Value="register.Name" Label="Name" Required />
<FluentValidationMessage For="@(() => register.Name)" />
</div>
<div>
<FluentTextField @bind-Value="register.Password" TextFieldType="TextFieldType.Password" Label="Password" Required />
<FluentValidationMessage For="@(() => register.Password)" />
</div>
<div>
<FluentTextField @bind-Value="register.ConfirmPassword" TextFieldType="TextFieldType.Password" Label="Confirm Password" Required />
<FluentValidationMessage For="@(() => register.ConfirmPassword)" />
</div>
<FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Register</FluentButton>
</FluentStack>
</FluentEditForm>
</FluentGridItem>
</FluentGrid>
@code {
RegisterDTO register = new RegisterDTO();
async Task OnRegisterSubmit(EditContext context)
{
RegistrationResonse response = await AccountService.RegisterAsync(register);
if (!response.Flag)
{
ToastService.ShowError(response.message, 5000);
return;
}
ToastService.ShowSuccess(response.message, 5000);
register = new RegisterDTO();
}
}

@ -14,7 +14,7 @@
else
{
<!-- This page is rendered in SSR mode, so the FluentDataGrid component does not offer any interactivity (like sorting). -->
<FluentDataGrid Id="weathergrid" Items="@forecasts" GridTemplateColumns="1fr 1fr 1fr 2fr" TGridItem="WeatherForecast">
<FluentDataGrid Id="weathergrid" Items="@forecasts" GridTemplateColumns="1fr 1fr 1fr 2fr" TGridItem="WeatherForecastDTO">
<PropertyColumn Title="Date" Property="@(c => c!.Date)" Align="Align.Start"/>
<PropertyColumn Title="Temp. (C)" Property="@(c => c!.TemperatureC)" Align="Align.Center"/>
<PropertyColumn Title="Temp. (F)" Property="@(c => c!.TemperatureF)" Align="Align.Center"/>
@ -23,28 +23,8 @@ else
}
@code {
private IQueryable<WeatherForecast>? forecasts;
private IQueryable<WeatherForecastDTO>? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).AsQueryable();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
=> forecasts = (await AccountService.GetWeatherForecastsAync()).AsQueryable();
}

@ -1,5 +1,6 @@
using FluentBlazorApp.DTOs;
using FluentBlazorApp.Repos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using static FluentBlazorApp.Responses.CustomResponses;
@ -18,6 +19,7 @@ namespace FluentBlazorApp.Controllers
}
[HttpPost("register")]
[AllowAnonymous]
public async Task<ActionResult<RegistrationResonse>> RegiserAsync(RegisterDTO model)
{
var result = await _accountRepo.RegisterAsync(model);
@ -25,10 +27,25 @@ namespace FluentBlazorApp.Controllers
}
[HttpPost("login")]
[AllowAnonymous]
public async Task<ActionResult<LoginResponse>> LoginAsync(LoginDTO model)
{
var result = await _accountRepo.LoginAsync(model);
return Ok(result);
}
[HttpGet("weather")]
[Authorize]
public ActionResult<WeatherForecastDTO[]> GetWeatherForecast()
{
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
return Ok(Enumerable.Range(1, 5).Select(index => new WeatherForecastDTO
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray());
}
}
}

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace FluentBlazorApp.DTOs
{
@ -7,7 +8,7 @@ namespace FluentBlazorApp.DTOs
[Required, DataType(DataType.Text), StringLength(50, MinimumLength = 2)]
public string Name { get; set; } = string.Empty;
[Required, DataType(DataType.Password)]
[Required, DataType(DataType.Password), StringLength(50, MinimumLength = 4)]
public string Password { get; set; } = string.Empty;
}
}

@ -4,9 +4,6 @@ namespace FluentBlazorApp.DTOs
{
public class RegisterDTO : LoginDTO
{
[Required, DataType(DataType.EmailAddress), EmailAddress]
public string Email { get; set; } = string.Empty;
[Required, DataType(DataType.Password), Compare(nameof(Password))]
public string ConfirmPassword { get; set; } = string.Empty;
}

@ -0,0 +1,10 @@
namespace FluentBlazorApp.DTOs
{
public class WeatherForecastDTO
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
@ -25,4 +25,10 @@
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.*-* " />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<Content Update="Components\Pages\Register.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
</Project>

@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace FluentBlazorApp.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20240802051133_First")]
partial class First
[Migration("20240805064123_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -32,10 +32,6 @@ namespace FluentBlazorApp.Migrations
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace FluentBlazorApp.Migrations
{
/// <inheritdoc />
public partial class First : Migration
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@ -22,8 +22,6 @@ namespace FluentBlazorApp.Migrations
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Password = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},

@ -29,10 +29,6 @@ namespace FluentBlazorApp.Migrations
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext");

@ -6,8 +6,6 @@
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

@ -50,7 +50,6 @@ namespace FluentBlazorApp.Repos
new ApplicationUser()
{
Name = model.Name,
Email = model.Email,
Password = BCrypt.Net.BCrypt.HashPassword(model.Password)
});

@ -7,6 +7,7 @@ namespace FluentBlazorApp.Services
public class AccountService : IAccountService
{
private readonly HttpClient _httpClient;
private readonly string BASE_URL = "api/account";
public AccountService(HttpClient httpClient)
{
@ -15,16 +16,21 @@ namespace FluentBlazorApp.Services
public async Task<LoginResponse> LoginAsync(LoginDTO model)
{
var resonse = await _httpClient.PostAsJsonAsync("api/account/login", model);
var resonse = await _httpClient.PostAsJsonAsync($"{BASE_URL}/login", model);
var result = await resonse.Content.ReadFromJsonAsync<LoginResponse>();
return result;
}
public async Task<RegistrationResonse> RegisterAsync(RegisterDTO model)
{
var resonse = await _httpClient.PostAsJsonAsync("api/account/register", model);
var resonse = await _httpClient.PostAsJsonAsync($"{BASE_URL}/register", model);
var result = await resonse.Content.ReadFromJsonAsync<RegistrationResonse>();
return result;
}
public async Task<WeatherForecastDTO[]> GetWeatherForecastsAync()
=> await _httpClient.GetFromJsonAsync<WeatherForecastDTO[]>($"{BASE_URL}/weather");
}
}

@ -7,5 +7,6 @@ namespace FluentBlazorApp.Services
{
Task<RegistrationResonse> RegisterAsync(RegisterDTO model);
Task<LoginResponse> LoginAsync(LoginDTO model);
Task<WeatherForecastDTO[]> GetWeatherForecastsAync();
}
}

Loading…
Cancel
Save