Made big progress in adding user signup fuctionaloity

This commit is contained in:
BOT Alex 2023-05-19 05:34:17 +02:00
parent 826fd4d03c
commit 496389890e
6 changed files with 242 additions and 77 deletions

View File

@ -1,11 +1,21 @@
@inherits LayoutComponentBase
@using System.Text.RegularExpressions
@using System.ComponentModel.DataAnnotations
@inject HttpClient httpClient
@inject Blazored.LocalStorage.ILocalStorageService localStorage
<MudLayout Class="overflow-hidden">
<MudAppBar Elevation="1">
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="AddUser">Primary</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ClearAllCookies">Clear cookies</MudButton>
<MudSpacer />
<MudAvatar @onclick="ToggleDrawer" Style="cursor:pointer;" Variant="Variant.Outlined" Color="Color.Success" Class="mr-n2">BT</MudAvatar>
@if (!isLoggedIn)
{
<MudPaper Class="pa-2 mr-2 d-flex mud-dark" Elevation="5">
<MudText Style="font-size: 15px;">Log-in or sign-up here</MudText>
<MudIcon Class="mr-n1" Icon="@Icons.Material.Filled.ArrowRightAlt" />
</MudPaper>
}
<MudAvatar @onclick="ToggleDrawer" Style="cursor:pointer;" Variant="Variant.Outlined" Color="Color.Surface" Class="mr-n2">?</MudAvatar>
</MudAppBar>
<MudDrawer @bind-Open="@openContentDrawer" ClipMode="DrawerClipMode.Always" Breakpoint="Breakpoint.Lg" PreserveOpenState="false" Elevation="1" Variant="@DrawerVariant.Mini" OpenMiniOnHover="true">
@ -17,11 +27,23 @@
</MudDrawer>
<MudDrawer Anchor="Anchor.End" @bind-Open="@openProfileDrawer" ClipMode="DrawerClipMode.Always" Breakpoint="Breakpoint.Lg" PreserveOpenState="true" Elevation="1" Variant="@DrawerVariant.Temporary">
@if (isLoggedIn)
{
<MudNavMenu>
<MudNavLink Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Store">Store</MudNavLink>
<MudNavLink Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Chat">Library</MudNavLink>
<MudNavLink Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Group">Community</MudNavLink>
</MudNavMenu>
}
else
{
<MudPaper Class="ma-2">
<MudStack Spacing="0" Class="justify-center">
<MudButton Class="ma-4" Variant="Variant.Outlined" Color="Color.Primary" OnClick="ShowLogIn">Log-in</MudButton>
<MudButton Class="ma-4" Variant="Variant.Outlined" Color="Color.Success" OnClick="ShowSignUp">Sign-up</MudButton>
</MudStack>
</MudPaper>
}
</MudDrawer>
<MudMainContent Class="overflow-hidden" Style="min-height: 100vh">
@ -29,33 +51,138 @@
</MudMainContent>
</MudLayout>
@*Sign-in overlay*@
<MudOverlay ZIndex="1400" @bind-Visible="isSigningUp" DarkBackground="true" Style="backdrop-filter:blur(5px)">
<MudPaper Class="pa-4 rounded-lg" @onclick:stopPropagation=true>
<MudIconButton Style="position: absolute; right: 0; top: 0;" Icon="@Icons.Material.Filled.Close" OnClick="HideOverlays" />
<MudText Typo="Typo.h3">Sign-up</MudText>
<MudForm @ref="form" @bind-IsValid="@isValid" @bind-Errors="@errors">
<MudTextField T="string" Label="Username" Required="true" RequiredError="User name is required!"
@bind-Text=tempUser.Username />
<MudTextField T="string" Label="Email" Required="true" RequiredError="Email is required!"
Validation="@(new EmailAddressAttribute() {ErrorMessage = "The email address is invalid"})"
@bind-Text=tempUser.Email/>
<MudTextField T="string" Label="Password" HelperText="Choose a strong password. (This will not be encrypted)" @ref="pwField1"
InputType="InputType.Password"
Validation="@(new Func<string, IEnumerable<string>>(PasswordStrength))" Required="true"
RequiredError="Password is required!"
@bind-Text=tempUser.Password/>
<MudTextField T="string"
Label="Password" HelperText="Repeat the password" InputType="InputType.Password"
Validation="@(new Func<string, string>(PasswordMatch))" />
<MudStack Row=true class="d-flex align-center">
<MudStack>
<MudCheckBox Class="ml-n2" T="bool" Required="true" RequiredError="You must agree"><MudText Style="font-size:10px;">I agree with <MudLink Href="/TOS" OnClick="HideOverlays" Style="font-size:10px;">Terms Of Service</MudLink></MudText></MudCheckBox>
</MudStack>
<MudButton Variant="Variant.Filled" Color="Color.Primary" Disabled="@(!isValid)" Class="ml-auto" OnClick="AddUser">Register</MudButton>
</MudStack>
</MudForm>
</MudPaper>
</MudOverlay>
@*Log-in overlay*@
<MudOverlay @bind-Visible="isLoggingIn" DarkBackground="true" AutoClose=true Style="backdrop-filter:blur(5px)">
<MudPaper @onclick:stopPropagation=true>
<MudText>Login</MudText>
</MudPaper>
</MudOverlay>
@code {
bool openContentDrawer = false;
bool openProfileDrawer = false;
bool isLoggedIn = false;
bool isSigningUp = false;
bool isLoggingIn = false;
bool isValid = false;
User tempUser = new User();
#region Drawers and overlays
void ToggleDrawer()
{
Console.WriteLine("Open!");
openProfileDrawer = !openProfileDrawer;
}
void ShowSignUp()
{
isSigningUp = true;
openContentDrawer = openProfileDrawer = false;
}
void ShowLogIn()
{
isLoggingIn = true;
openContentDrawer = openProfileDrawer = false;
}
void HideOverlays() => isSigningUp = isLoggingIn = false;
#endregion
async void AddUser()
{
//await httpClient.PostAsJsonAsync("https://globalchat-4a89f-default-rtdb.europe-west1.firebasedatabase.app/Database/Users.json", new User());
Console.WriteLine(tempUser.Username);
Console.WriteLine(tempUser.Email);
Console.WriteLine(tempUser.Password);
}
#region Signup
bool success;
string[] errors = { };
MudTextField<string> pwField1;
MudForm form;
private IEnumerable<string> PasswordStrength(string pw)
{
if (string.IsNullOrWhiteSpace(pw))
{
yield return "Password is required!";
yield break;
}
if (pw.Length < 8)
yield return "Password must be at least of length 8";
if (!Regex.IsMatch(pw, @"[A-Z]"))
yield return "Password must contain at least one capital letter";
if (!Regex.IsMatch(pw, @"[a-z]"))
yield return "Password must contain at least one lowercase letter";
if (!Regex.IsMatch(pw, @"[0-9]"))
yield return "Password must contain at least one digit";
}
private string PasswordMatch(string arg)
{
if (pwField1.Value != arg)
return "Passwords don't match";
return null;
}
#endregion
protected override async Task OnInitializedAsync()
{
// Reads "cookie"
var cookieContent = await localStorage.GetItemAsync<User>("cookieName");
if (cookieContent == null)
{
Console.WriteLine("Cookie is blank");
}
else
{
Console.WriteLine("We have a cookie with contents: " + cookieContent);
}
}
async void ClearAllCookies()
{
await localStorage.ClearAsync();
}
public class User
{
public string ID { get; set; } = "null";
public string Username { get; set; } = "null";
public string Email { get; set; } = "null";
public string Password { get; set; } = "null";
}
async void AddUser()
{
await httpClient.PostAsJsonAsync("https://globalchat-4a89f-default-rtdb.europe-west1.firebasedatabase.app/Database/Users.json", new User());
}
protected override async Task OnInitializedAsync()
{
//Response.Cookies.Append("MyCookie", "value1");
public string? Username { get; set; }
public string? Email { get; set; }
public string? Password { get; set; }
}
}

View File

@ -2,11 +2,20 @@
@using System.Globalization;
@inject NavigationManager NavManager
@inject HttpClient Http
@inject IJSRuntime JSRuntime
<style>
.bottom-start {
display: flex;
flex-direction: column-reverse;
height: 100%;
overflow: auto;
}
</style>
<MudContainer Class="justify-center">
<MudContainer Style="max-width: 400px; width: 100vw; min-width: 250px;">
<MudPaper Style="height: 80vh;" Class="mt-7 overflow-scroll">
<MudPaper Style="height: 80vh; flex-direction: column-reverse;" Class="mt-7 bottom-start">
@if (messages != null)
{
@ -14,47 +23,32 @@
{
Message message = messages[i];
if ("dumb zhen" == message.Name)
{
<MudStack Class="px-4 py-2 d-flex" Justify="Justify.FlexEnd" Row="true" AlignItems="AlignItems.End">
<MudStack>
<MudPaper Style="max-width: 320px;" Class="mud-theme-primary" Elevation="4">
<MudText Typo="Typo.body1" Class="px-2 pt-2">@message.Content</MudText>
<MudText Class="pa-1 pr-2" Align="Align.End" Style="font-size: 10px;">@("@" + message.Name)</MudText>
</MudPaper>
<MudText Class="mt-n3" Align="Align.End" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM/yyyy HH:mm", danishCulture))</MudText>
</MudStack>
</MudStack>
}
else
{
<MudStack Class="px-4 py-2" Row="true">
<MudStack>
<MudPaper Class="overflow-hidden" Style="max-width: 320px" Elevation="4">
<MudText Typo="Typo.body1" Class="px-2 pt-2">@message.Content</MudText>
<MudText Class="pa-1" Style="font-size: 10px;">@("@" + message.Name)</MudText>
</MudPaper>
<MudText Class="mt-n3" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM/yyyy HH:mm", danishCulture))</MudText>
<MudText Class="mt-n3 pl-1" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM HH:mm", danishCulture))</MudText>
</MudStack>
</MudStack>
}
}
<MudStack Class="px-4 py-2 d-flex" Justify="Justify.FlexEnd" Row="true" AlignItems="AlignItems.End">
<MudStack>
<MudPaper Style="max-width: 320px;" Class="mud-theme-primary" Elevation="4">
<MudText Typo="Typo.body1" Class="px-2 pt-2">World!</MudText>
<MudText Class="pa-1 pr-2" Align="Align.End" Style="font-size: 10px;">@("@Alex")</MudText>
</MudPaper>
<MudText Class="mt-n3" Align="Align.End" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM/yyyy HH:mm", danishCulture))</MudText>
</MudStack>
</MudStack>
<MudStack Class="px-4 py-2" Row="true">
<MudStack>
<MudPaper Style="max-width: 320px" Elevation="4">
<MudText Typo="Typo.body1" Class="px-2 pt-2">How about a longer thing here?!?!?! Test testes tetst estestse testset estsete stestest</MudText>
<MudText Class="pa-1" Style="font-size: 10px;">@("@Adam")</MudText>
</MudPaper>
<MudText Class="mt-n3" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM/yyyy HH:mm", danishCulture))</MudText>
</MudStack>
</MudStack>
<MudStack Class="px-4 py-2 d-flex" Justify="Justify.FlexEnd" Row="true" AlignItems="AlignItems.End">
<MudStack>
<MudPaper Style="max-width: 320px;" Class="mud-theme-primary" Elevation="4">
<MudText Typo="Typo.body1" Class="px-2 pt-2">It is working!</MudText>
<MudText Class="pa-1 pr-2" Align="Align.End" Style="font-size: 10px;">@("@Alex")</MudText>
</MudPaper>
<MudText Class="mt-n3" Align="Align.End" Style="font-size: 10px;">@(DateTime.Now.ToString("dd/MM/yyyy HH:mm", danishCulture))</MudText>
</MudStack>
</MudStack>
}
</MudPaper>
<MudContainer Class="d-flex pa-0">
@ -94,13 +88,25 @@
protected override async Task OnInitializedAsync()
{
if (messages == null)
messages = (await Http.GetFromJsonAsync<Message[]>("https://globalchat-4a89f-default-rtdb.europe-west1.firebasedatabase.app/Database/Messages.json"));
//for (int i = 0; i < messages.Length; i++)
//{
// Console.WriteLine($"Name: {messages[i].Name} Content: {messages[i].Content}");
//}
StartLoop();
}
bool isLooping = false;
private async Task StartLoop()
{
if (isLooping)
return;
isLooping = true;
while (isLooping)
{
messages = (await Http.GetFromJsonAsync<Message[]>("https://globalchat-4a89f-default-rtdb.europe-west1.firebasedatabase.app/Database/Messages.json"));
await Task.Delay(100000); // Delay for 1 second before the next iteration
}
}
public class Message

View File

@ -18,8 +18,8 @@
}
</style>
<MudOverlay @bind-Visible="isOverlayVisible" Style="backdrop-filter:blur(5px)" DarkBackground="true" AutoClose="true">
<MudPaper Elevation="3" Class="rounded-xl">
<MudOverlay ZIndex="1400" @bind-Visible="isOverlayVisible" Style="backdrop-filter:blur(5px)" DarkBackground="true" AutoClose="true">
<MudPaper @onclick:stopPropagation=true Elevation="3" Class="rounded-xl">
<MudImage Class="rounded-xl" Elevation="4" Src="@selectedPost.ImagePath" Width="500" Height="500"/>
<MudContainer Class="pa-5 d-flex align-center justify-content-start">
<MudText>
@ -31,7 +31,7 @@
</MudPaper>
</MudOverlay>
<MudOverlay @bind-Visible="isCreatePostWarningVisible" Style="backdrop-filter:blur(5px)" DarkBackground="true" AutoClose="true">
<MudOverlay ZIndex="1400" @bind-Visible="isCreatePostWarningVisible" Style="backdrop-filter:blur(5px)" DarkBackground="true" AutoClose="true">
<MudPaper Class="pa-8">
<MudContainer Class="pa-0 d-flex justify-content-end">
<MudText Typo="Typo.h4">I am sorry</MudText>

View File

@ -0,0 +1,18 @@
@page "/TOS"
<style>
.unreadable{
font-family: 'Comic Sans MS'
}
</style>
<div class="unreadable">
<p>Terms of Service (TOS) for Otakians Social Media Platform</p><p>Effective Date: 19/5/2023</p><p>Welcome to Otakians! These Terms of Service ("TOS") govern your use of the Otakians social media platform (the "Platform"). By accessing or using the Platform, you agree to be bound by these TOS. If you do not agree to these TOS, please refrain from using the Platform.</p>
<br /><b>1 - Acceptance of Terms</b><p>1.1 Agreement: By using the Platform, you agree to abide by these TOS and any additional guidelines or rules posted on the Platform.</p><p>1.2 Modification: Otakians reserves the right to modify, update, or change these TOS at any time. Any modifications will be effective immediately upon posting on the Platform. Your continued use of the Platform after such modifications constitutes your acceptance of the revised TOS.</p>
<br /><b>2 - User Conduct</b><p>2.1 Eligibility: You must be at least 13 years of age to use the Platform. If you are under 13, you may only use the Platform with the consent and supervision of a parent or legal guardian.</p><p>2.2 Compliance: You agree to comply with all applicable laws, regulations, and these TOS when using the Platform. You will not use the Platform for any illegal, harmful, or unauthorized purposes.</p><p>2.3 Prohibited Content: You may not post, transmit, or share any content on the Platform that is unlawful, defamatory, obscene, offensive, or infringing upon the rights of others. This includes, but is not limited to, hate speech, harassment, and explicit or pornographic material.</p><p>2.4 User Responsibility: You are solely responsible for the content you post on the Platform. Otakians does not endorse or guarantee the accuracy, integrity, or quality of user-generated content.</p>
<br /><b>3 - Intellectual Property</b><p>3.1 Ownership: Otakians and its licensors retain all rights, titles, and interests in and to the Platform, including all associated intellectual property rights. You agree not to use, reproduce, distribute, or create derivative works based on the Platform without prior written permission from Otakians.</p><p>3.2 User Content: By posting content on the Platform, you grant Otakians a non-exclusive, royalty-free, worldwide license to use, modify, adapt, reproduce, distribute, and display such content for the purpose of operating and improving the Platform.</p>
<br /><b>4 - Privacy</b><p>4.1 Collection of Information: Otakians collects and stores information as described in the Privacy Policy. By using the Platform, you consent to the collection, use, and storage of your information as outlined in the Privacy Policy.</p><p>4.2 User Safety: While Otakians strives to provide a safe platform, you acknowledge and accept that interactions with other users are at your own risk. Otakians is not responsible for the actions or behavior of its users.</p>
<br /><b>5 - Limitation of Liability</b><p>5.1 Disclaimer: The Platform is provided on an "as is" and "as available" basis, without warranties of any kind, whether express or implied. Otakians disclaims all warranties, including but not limited to merchantability, fitness for a particular purpose, and non-infringement.</p><p>5.2 Indemnification: You agree to indemnify, defend, and hold Otakians and its affiliates harmless from any claims, liabilities, damages, losses, or expenses arising out of your use of the Platform or violation of these TOS.</p><p>5.3 Limitation of Liability: In no event shall Otakians be liable for any indirect, incidental, special, consequential, or punitive damages, whether arising from the use of the Platform or any content therein.</p>
<br /><b>6 - Termination</b><p>6.1 Termination: Otakians reserves the right to suspend, terminate, or restrict your access to the Platform, in whole or in part, at any time and for any reason, without prior notice or liability. This includes the removal of any content you have posted on the Platform.</p><p>6.2 Effect of Termination: Upon termination of your access to the Platform, you will no longer have the right to use or access the Platform or any content therein. The provisions of these TOS that, by their nature, should survive termination (including, but not limited to, intellectual property rights, indemnification, and limitations of liability) shall continue to apply.</p>
<br /><b>7 - Miscellaneous</b><p>7.1 Entire Agreement: These TOS constitute the entire agreement between you and Otakians regarding your use of the Platform, superseding any prior agreements or understandings.</p><p>7.2 Governing Law: These TOS shall be governed by and construed in accordance with the laws of Zina lands. Any legal action or proceeding arising out of or relating to these TOS shall be exclusively heard in the courts located within Zina lands.</p><p>7.3 Severability: If any provision of these TOS is deemed invalid or unenforceable, that provision will be deemed severable and shall not affect the validity and enforceability of the remaining provisions.</p><p>7.4 Waiver: The failure of Otakians to enforce any right or provision of these TOS shall not constitute a waiver of such right or provision unless acknowledged and agreed to in writing.</p><p>7.5 Contact: If you have any questions, concerns, or feedback regarding these TOS, please contact us at [Insert contact information].</p><p>By using the Otakians Platform, you acknowledge that you have read, understood, and agreed to these Terms of Service.</p>
</div>

View File

@ -1,13 +1,26 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
using Blazored.LocalStorage;
using Otakians;
using System;
using System.Security.Cryptography;
using System.Text;
internal class Program
{
private static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddMudServices();
builder.Services.AddBlazoredLocalStorage(); // local storage
builder.Services.AddBlazoredLocalStorage(config =>
config.JsonSerializerOptions.WriteIndented = true); // local storage
await builder.Build().RunAsync();
}
}

View File

@ -1,6 +1,7 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop