fix dashboard
This commit is contained in:
parent
fb712bbcab
commit
cc7fb93439
9 changed files with 500 additions and 73 deletions
125
src/Interlinked.Core/Pages/Dashboard.razor
Normal file
125
src/Interlinked.Core/Pages/Dashboard.razor
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
@page "/dashboard"
|
||||||
|
@using System.ComponentModel.DataAnnotations;
|
||||||
|
@using System.Net
|
||||||
|
@inject HttpClient req
|
||||||
|
@inject UserManager usr
|
||||||
|
|
||||||
|
<PageTitle>Dashboard</PageTitle>
|
||||||
|
|
||||||
|
<h1>Your profile</h1>
|
||||||
|
|
||||||
|
@if (!string.IsNullOrWhiteSpace(_err))
|
||||||
|
{
|
||||||
|
<p class="text-danger">@_err</p>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="profile">
|
||||||
|
<h2>Profile settings</h2>
|
||||||
|
<EditForm class="form" Model="@_pdr" OnValidSubmit="@UpdateProfile">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cc">Country</label>
|
||||||
|
<InputText @bind-Value="_pdr.CC" id="cc" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="city">City</label>
|
||||||
|
<InputText @bind-Value="_pdr.City" id="city" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="bio">Bio</label>
|
||||||
|
<InputText @bind-Value="_pdr.Bio" id="bio" />
|
||||||
|
</div>
|
||||||
|
<button type="submit">Update profile</button>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="security">
|
||||||
|
<h2>Security settings</h2>
|
||||||
|
|
||||||
|
<EditForm class="form" Model="@_pwc" OnValidSubmit="@ChangePassword">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="oldpw">Old password</label>
|
||||||
|
<InputText @bind-Value="_pwc.PasswordOld" id="oldpw" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="npw">New password</label>
|
||||||
|
<InputText @bind-Value="_pwc.PasswordNew" id="npw" />
|
||||||
|
</div>
|
||||||
|
<button type="submit">Change password</button>
|
||||||
|
</EditForm>
|
||||||
|
|
||||||
|
<EditForm class="form" Model="@_emc" OnValidSubmit="@ChangeEmail">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="oldpw">Email</label>
|
||||||
|
<InputText @bind-Value="_emc.Email" id="eml" />
|
||||||
|
</div>
|
||||||
|
<button type="submit">Change email</button>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _err = "";
|
||||||
|
private PasswordChangeRequest _pwc = new();
|
||||||
|
private EmailChangeRequest _emc = new();
|
||||||
|
private ProfileRequest _pdr = new();
|
||||||
|
|
||||||
|
public record PasswordChangeRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string PasswordOld { get; set; } = default!;
|
||||||
|
[Required]
|
||||||
|
public string PasswordNew { get; set; } = default!;
|
||||||
|
};
|
||||||
|
|
||||||
|
public record EmailChangeRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; } = default!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ProfileRequest
|
||||||
|
{
|
||||||
|
public string? Bio { get; set; }
|
||||||
|
public string? CC { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public ICollection<string> Interests { get; set; } = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async override Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangePassword()
|
||||||
|
{
|
||||||
|
var resp = await req.PostAsJsonAsync("/api/auth/changepass", _pwc);
|
||||||
|
if (!resp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_err = await resp.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
this._pwc = new();
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeEmail()
|
||||||
|
{
|
||||||
|
var resp = await req.PostAsJsonAsync("/api/auth/changemail", _emc);
|
||||||
|
if (!resp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_err = await resp.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
this._emc = new();
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateProfile()
|
||||||
|
{
|
||||||
|
var resp = await req.PostAsJsonAsync("/api/auth/profile/update", _pdr);
|
||||||
|
if (!resp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_err = await resp.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
this._pdr = new();
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
@page "/fetchdata"
|
|
||||||
@inject HttpClient Http
|
|
||||||
|
|
||||||
<PageTitle>Weather forecast</PageTitle>
|
|
||||||
|
|
||||||
<h1>Weather forecast</h1>
|
|
||||||
|
|
||||||
<p>This component demonstrates fetching data from the server.</p>
|
|
||||||
|
|
||||||
@if (forecasts == null)
|
|
||||||
{
|
|
||||||
<p><em>Loading...</em></p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Temp. (C)</th>
|
|
||||||
<th>Temp. (F)</th>
|
|
||||||
<th>Summary</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var forecast in forecasts)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@forecast.Date.ToShortDateString()</td>
|
|
||||||
<td>@forecast.TemperatureC</td>
|
|
||||||
<td>@forecast.TemperatureF</td>
|
|
||||||
<td>@forecast.Summary</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private WeatherForecast[]? forecasts;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
public 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +1,58 @@
|
||||||
@page "/user/{username}"
|
@page "/profile/{username}"
|
||||||
|
@inject HttpClient cli
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Username { get; set; } = "johndoeUwU";
|
public string Username { get; set; } = "johndoeUwU";
|
||||||
private string FullName = "meow uwu";
|
private UserModel _user = null!;
|
||||||
private string Bio = "Software Developer";
|
private bool _valid = true;
|
||||||
private List<string> Skills = new List<string> { "C#", "ASP.NET Core", "Blazor" };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="user-profile">
|
@if (!_valid)
|
||||||
|
{
|
||||||
|
<h1>User not found @(":<")</h1>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_user != null)
|
||||||
|
{
|
||||||
|
<div class="user-profile">
|
||||||
<img class="background" src="images/background.jpg" alt="Background" />
|
<img class="background" src="images/background.jpg" alt="Background" />
|
||||||
<img class="profile-img" src="images/kuba.jpg" alt="Profile Picture" />
|
<img class="profile-img" src="images/kuba.jpg" alt="Profile Picture" />
|
||||||
<div class="profile-names">
|
<div class="profile-names">
|
||||||
<h1 class="profile-username">@($"@{Username}")</h1>
|
<h1 class="profile-username">@($"@{_user.Username}")</h1>
|
||||||
<h3 class="profile-fullname">(@FullName)</h3>
|
@if (_user.Name != null)
|
||||||
</div>
|
|
||||||
<p>@Bio</p>
|
|
||||||
<h2>Skills</h2>
|
|
||||||
<ul>
|
|
||||||
@foreach (var skill in Skills)
|
|
||||||
{
|
{
|
||||||
<li>@skill</li>
|
<h3 class="profile-fullname">(@_user.Name)</h3>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<p>@(_user.Bio ?? "~")</p>
|
||||||
|
@if (_user.Interests != null)
|
||||||
|
{
|
||||||
|
<h2>Interested in:</h2>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
@foreach (var interest in _user.Interests)
|
||||||
|
{
|
||||||
|
<li>@interest?.Name</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var resp = await cli.GetAsync($"/api/profile/{Username}");
|
||||||
|
if (!resp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_user = (await resp.Content.ReadFromJsonAsync<UserModel>())!;
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Interlinked.Shared.Model;
|
namespace Interlinked.Shared.Model;
|
||||||
|
|
||||||
public class UserModel
|
public record UserModel
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
@ -34,6 +34,8 @@ public class UserModel
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
public DateTime CreatedTimestamp { get; set; }
|
public DateTime CreatedTimestamp { get; set; }
|
||||||
|
|
||||||
|
public string? Bio { get; set; }
|
||||||
|
|
||||||
public static byte[] HashPassword(string password, byte[] salt)
|
public static byte[] HashPassword(string password, byte[] salt)
|
||||||
{
|
{
|
||||||
return Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(password), salt, 1000, HashAlgorithmName.SHA256, 64);
|
return Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(password), salt, 1000, HashAlgorithmName.SHA256, 64);
|
||||||
|
|
|
@ -108,5 +108,43 @@ public class AuthController : ControllerBase
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record ProfileRequest
|
||||||
|
{
|
||||||
|
public string? Bio { get; set; }
|
||||||
|
public string? CC { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public ICollection<string> Interests { get; set; } = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("profile/update")]
|
||||||
|
public async Task<IActionResult> UpdateProfile([FromBody] ProfileRequest req)
|
||||||
|
{
|
||||||
|
if (await _auth.RetrieveCookie() is not AuthSession sess)
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
var u = await _db.Users.SingleAsync(s => s.Id == sess.UserId);
|
||||||
|
|
||||||
|
if (u is null)
|
||||||
|
{
|
||||||
|
return this.BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
u.Bio = req.Bio;
|
||||||
|
if (req.CC is not null)
|
||||||
|
{
|
||||||
|
u.CountryCode = req.CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.City is not null)
|
||||||
|
{
|
||||||
|
u.City = req.City;
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.Users.Update(u);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
31
src/Interlinked.User/Controllers/DataController.cs
Normal file
31
src/Interlinked.User/Controllers/DataController.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Interlinked.User.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api")]
|
||||||
|
public class DataController : ControllerBase
|
||||||
|
{
|
||||||
|
public DataController(StoreContext db)
|
||||||
|
{
|
||||||
|
_db = db;
|
||||||
|
}
|
||||||
|
private readonly StoreContext _db;
|
||||||
|
|
||||||
|
[HttpGet("profile/{username}")]
|
||||||
|
public async Task<IActionResult> GetProfile([FromRoute] string username)
|
||||||
|
{
|
||||||
|
var usr = await _db.Users.AsNoTracking().SingleOrDefaultAsync(u => u.Username == username);
|
||||||
|
if (usr is null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(usr with { Email = null! });
|
||||||
|
}
|
||||||
|
}
|
225
src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs
generated
Normal file
225
src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs
generated
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Interlinked.User;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Interlinked.User.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(StoreContext))]
|
||||||
|
[Migration("20231001092331_bio")]
|
||||||
|
partial class bio
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.11");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.AuthSession", b =>
|
||||||
|
{
|
||||||
|
b.Property<byte[]>("Key")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("LastAddress")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Secret")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<long>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Key");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AuthSessions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.Project", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("OwnerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.ToTable("Projects");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.Tag", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Identifier")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Identifier");
|
||||||
|
|
||||||
|
b.ToTable("Tags");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Bio")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("City")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CountryCode")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(2)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedTimestamp")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DayOfBirth")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Hash")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(96)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Salt")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(32)
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.UseCollation("NOCASE");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ProjectTag", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("ProjectsId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("TagsIdentifier")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("ProjectsId", "TagsIdentifier");
|
||||||
|
|
||||||
|
b.HasIndex("TagsIdentifier");
|
||||||
|
|
||||||
|
b.ToTable("ProjectTag");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("TagUserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("InterestsIdentifier")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("UsersId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("InterestsIdentifier", "UsersId");
|
||||||
|
|
||||||
|
b.HasIndex("UsersId");
|
||||||
|
|
||||||
|
b.ToTable("TagUserModel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.AuthSession", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Interlinked.Shared.Model.UserModel", "User")
|
||||||
|
.WithMany("AuthSessions")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.Project", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Interlinked.Shared.Model.UserModel", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ProjectTag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Interlinked.Shared.Model.Project", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ProjectsId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Interlinked.Shared.Model.Tag", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("TagsIdentifier")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("TagUserModel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Interlinked.Shared.Model.Tag", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InterestsIdentifier")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Interlinked.Shared.Model.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UsersId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Interlinked.Shared.Model.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AuthSessions");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/Interlinked.User/Migrations/20231001092331_bio.cs
Normal file
28
src/Interlinked.User/Migrations/20231001092331_bio.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Interlinked.User.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class bio : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Bio",
|
||||||
|
table: "Users",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Bio",
|
||||||
|
table: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,6 +82,9 @@ namespace Interlinked.User.Migrations
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Bio")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("City")
|
b.Property<string>("City")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue