Compare commits

...

1 Commits

Author SHA1 Message Date
7e767541cf more stuff 2026-05-01 19:48:34 -05:00
18 changed files with 1292 additions and 319 deletions

View File

@@ -22,4 +22,8 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.12" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.12" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\uploads\" />
</ItemGroup>
</Project> </Project>

View File

@@ -4,6 +4,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
font-family: 'StencilBold', sans-serif;
} }
.container { .container {
@@ -31,7 +32,7 @@
.logo { .logo {
font-size: 1.5rem; font-size: 1.5rem;
font-weight: bold; font-weight: bold;
color: #0056b3; color: black;
} }
.logo span { .logo span {
@@ -40,13 +41,13 @@
.nav-phone { .nav-phone {
text-decoration: none; text-decoration: none;
color: #0056b3; color: black;
font-weight: bold; font-weight: bold;
} }
/* Hero Section */ /* Hero Section */
.hero { .hero {
background: linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6)), url('https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?auto=format&fit=crop&w=1200&q=80'); background: linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6)), url('https://images.unsplash.com/photo-1588854337115-1c67d9247e4d?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
background-size: cover; background-size: cover;
background-position: center; background-position: center;
color: #fff; color: #fff;
@@ -60,7 +61,7 @@
} }
.hero h1 span { .hero h1 span {
color: #4cc9f0; color: #D2B48C;
} }
/* Buttons */ /* Buttons */
@@ -111,13 +112,13 @@
padding: 30px; padding: 30px;
border-radius: 8px; border-radius: 8px;
text-align: center; text-align: center;
border-bottom: 4px solid #0056b3; border-bottom: 4px solid #D2B48C;
box-shadow: 0 4px 6px rgba(0,0,0,0.05); box-shadow: 0 4px 6px rgba(0,0,0,0.05);
} }
/* Trust Section */ /* Trust Section */
.trust { .trust {
background: #0056b3; background: #D2B48C;
color: #fff; color: #fff;
padding: 40px 0; padding: 40px 0;
text-align: center; text-align: center;

View File

@@ -2,6 +2,37 @@
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin")] @attribute [Authorize(Roles = "Admin")]
@rendermode InteractiveServer @rendermode InteractiveServer
@inject IJSRuntime JS
<dialog id="imageViewerModal" class="image-viewer-modal">
@if (SelectedRequestMedia?.Any() == true)
{
<div class="image-viewer-modal-header">
<span>Request: @SelectedRequestMedia[0].RequestNumber</span>
<button class="close-btn" @onclick="CloseImageViewer">&times;</button>
</div>
}
<div class="image-viewer-carousel-container">
@if (SelectedRequestMedia?.Any() == true)
{
<button class="image-viewer-nav-btn" @onclick="ImageViewerModal_PrevImage">&#10094;</button>
<div class="image-viewer-image-stage">
<img src="@GetWebPath(SelectedRequestMedia[SelectedRequestMediaImageIndex].MediaPath)" alt="Appliance repair evidence" />
<div class="image-viewer-image-counter">
Image @(SelectedRequestMediaImageIndex + 1) of @SelectedRequestMedia.Count
</div>
</div>
<button class="image-viewer-nav-btn" @onclick="ImageViewerModal_NextImage">&#10095;</button>
}
else
{
<div class="image-viewer-no-images">No images found for this request.</div>
}
</div>
</dialog>
<div class="admin-wrapper"> <div class="admin-wrapper">
<div class="container"> <div class="container">
@@ -72,6 +103,7 @@
@foreach (var card in HomePageModel.ServicesCards) @foreach (var card in HomePageModel.ServicesCards)
{ {
<div class="content-card"> <div class="content-card">
<button class="close-btn" @onclick="async () => await DeleteContentCard(card)">&times;</button>
<div class="input-group"> <div class="input-group">
<label>Header</label> <label>Header</label>
<InputTextArea @bind-Value="card.Header" class="form-input" /> <InputTextArea @bind-Value="card.Header" class="form-input" />
@@ -93,6 +125,7 @@
@foreach (var card in HomePageModel.TrustCards) @foreach (var card in HomePageModel.TrustCards)
{ {
<div class="content-card"> <div class="content-card">
<button class="close-btn" @onclick="async () => await DeleteContentCard(card)">&times;</button>
<div class="input-group"> <div class="input-group">
<label>Header</label> <label>Header</label>
<InputTextArea @bind-Value="card.Header" class="form-input" /> <InputTextArea @bind-Value="card.Header" class="form-input" />
@@ -146,6 +179,8 @@
} }
else if (CurrentTab == AdminTab.Requests) else if (CurrentTab == AdminTab.Requests)
{ {
<div class="form-section"> <div class="form-section">
<h3><i class="icon">📋</i> Service Requests</h3> <h3><i class="icon">📋</i> Service Requests</h3>
@@ -187,7 +222,7 @@
</div> </div>
<div class="request-actions"> <div class="request-actions">
<button class="btn-small btn-view" @onclick="() => {}">View Images</button> <button class="btn-small btn-view" @onclick="async () => await ViewRequestImages(request)">View Images</button>
</div> </div>
</div> </div>
} }

View File

@@ -1,13 +1,17 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace ApplianceRepair.Components.Pages.admin namespace ApplianceRepair.Components.Pages.admin
{ {
public partial class Admin(HomePageReader homePageReader, ContentCardReader contentCardReader, BusinessConfigReader businessConfigReader, RepairRequestReader repairRequestReader) : ComponentBase public partial class Admin(HomePageReader homePageReader, ContentCardReader contentCardReader, BusinessConfigReader businessConfigReader, RepairRequestReader repairRequestReader, RepairRequestMediaReader repairRequestMediaReader) : ComponentBase
{ {
public HomePageModel? HomePageModel; public HomePageModel? HomePageModel;
public BusinessInfoModel? BusinessInfo; public BusinessInfoModel? BusinessInfo;
public List<RepairRequestModel>? RepairRequests; public List<RepairRequestModel>? RepairRequests;
public List<RepairRequestMediaRecord>? SelectedRequestMedia;
public int SelectedRequestMediaImageIndex = 0;
private enum AdminTab { Home, Requests, BusinessInfo } private enum AdminTab { Home, Requests, BusinessInfo }
private AdminTab CurrentTab = AdminTab.Home; private AdminTab CurrentTab = AdminTab.Home;
@@ -28,6 +32,29 @@ namespace ApplianceRepair.Components.Pages.admin
}); });
} }
private async void RefreshContentCards()
{
if (HomePageModel == null)
{
return;
}
var servicesList = await contentCardReader.ReadAllByPageAndGroup(HomePageModel.PageName, nameof(HomePageModel.ContentCardTypes.Services)) ?? [];
var trustList = await contentCardReader.ReadAllByPageAndGroup(HomePageModel.PageName, nameof(HomePageModel.ContentCardTypes.Trust)) ?? [];
HomePageModel.ServicesCards.Clear();
foreach (var card in servicesList)
{
HomePageModel.ServicesCards.Add(new ContentCardModel(card));
}
HomePageModel.TrustCards.Clear();
foreach (var card in trustList)
{
HomePageModel.TrustCards.Add(new ContentCardModel(card));
}
}
private async void RevertHomePageModel() private async void RevertHomePageModel()
{ {
var businessConfig = await businessConfigReader.ReadLatestRecord() ?? Defaults.DefaultBusinessConfig; var businessConfig = await businessConfigReader.ReadLatestRecord() ?? Defaults.DefaultBusinessConfig;
@@ -69,6 +96,12 @@ namespace ApplianceRepair.Components.Pages.admin
await businessConfigReader.UpdateRecord(BusinessInfo); await businessConfigReader.UpdateRecord(BusinessInfo);
} }
private async Task DeleteContentCard(ContentCardModel card)
{
await contentCardReader.DeleteRecord(card);
RefreshContentCards();
}
private void AddServiceCard() private void AddServiceCard()
{ {
HomePageModel?.ServicesCards.Add(new ContentCardModel() { HomePageModel?.ServicesCards.Add(new ContentCardModel() {
@@ -93,5 +126,58 @@ namespace ApplianceRepair.Components.Pages.admin
Text = "Short Description" Text = "Short Description"
}); });
} }
private async Task ViewRequestImages(RepairRequestModel request)
{
if (!string.IsNullOrEmpty(request.RequestNumber))
{
SelectedRequestMedia = await repairRequestMediaReader.ReadAllByRequestNumber(request.RequestNumber);
SelectedRequestMediaImageIndex = 0;
await JS.InvokeVoidAsync("eval", $"document.getElementById('imageViewerModal').showModal()");
}
}
private async Task CloseImageViewer()
{
await JS.InvokeVoidAsync("eval", $"document.getElementById('imageViewerModal').close()");
SelectedRequestMedia = [];
}
private async Task ImageViewerModal_PrevImage()
{
if (SelectedRequestMedia == null) return;
SelectedRequestMediaImageIndex++;
if (SelectedRequestMediaImageIndex >= SelectedRequestMedia.Count())
{
SelectedRequestMediaImageIndex = 0;
}
}
private async Task ImageViewerModal_NextImage()
{
if (SelectedRequestMedia == null) return;
SelectedRequestMediaImageIndex--;
if (SelectedRequestMediaImageIndex < 0)
{
SelectedRequestMediaImageIndex = SelectedRequestMedia.Count() - 1;
}
}
private string GetWebPath(string fullPath = "")
{
if (string.IsNullOrEmpty(fullPath)) return "";
var marker = "wwwroot";
var index = fullPath.IndexOf(marker);
if (index != -1)
{
// Returns "/uploads/filename.jpg"
return fullPath.Substring(index + marker.Length).Replace('\\', '/');
}
return fullPath;
}
} }
} }

View File

@@ -5,6 +5,107 @@
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
} }
/* Image Viewer Modal */
.image-viewer-modal[open] {
border: none;
border-radius: 12px;
padding: 0;
max-width: 90vw;
width: 1000px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
background-color: #fff;
overflow: hidden;
}
.image-viewer-modal::backdrop {
background-color: rgba(0, 0, 0, 0.75);
backdrop-filter: blur(4px);
}
.image-viewer-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
background-color: #f8f9fa;
border-bottom: 1px solid #e9ecef;
font-weight: 600;
}
.image-viewer-image-stage {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 400px;
max-height: 70vh;
background-color: #000;
border-radius: 8px;
position: relative;
overflow: hidden;
}
.image-viewer-image-stage img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
display: block;
}
.image-viewer-carousel-container {
display: flex;
align-items: center;
padding: 1.5rem;
gap: 1rem;
background-color: #f1f3f5;
}
.image-viewer-nav-btn {
background-color: #fff;
border: 1px solid #dee2e6;
border-radius: 50%;
width: 45px;
height: 45px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 1.2rem;
transition: all 0.2s ease;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
z-index: 10;
}
.image-viewer-nav-btn:hover {
background-color: #007bff;
color: white;
transform: scale(1.1);
}
.image-viewer-nav-btn:active {
transform: scale(0.95);
}
.image-viewer-image-counter {
position: absolute;
bottom: 10px;
background: rgba(0, 0, 0, 0.6);
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.85rem;
}
.image-viewer-no-images {
width: 100%;
text-align: center;
padding: 3rem;
color: #6c757d;
font-style: italic;
}
/* Image viewer modal */
.admin-header { .admin-header {
text-align: center; text-align: center;
margin-bottom: 40px; margin-bottom: 40px;
@@ -109,12 +210,12 @@ label {
border: 1px solid #e0e6ed; border: 1px solid #e0e6ed;
border-radius: 12px; border-radius: 12px;
padding: 20px; padding: 20px;
transition: transform 0.2s ease; transition: transform 0.2s ease;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-content: center; align-content: center;
position: relative;
} }
.content-card:hover { .content-card:hover {
@@ -294,6 +395,17 @@ label {
animation: fadeIn 0.5s ease; animation: fadeIn 0.5s ease;
} }
.close-btn {
position: absolute;
top: 5px;
right: 5px;
background: none;
border: none;
font-size: 20px;
cursor: pointer;
line-height: 1;
}
@keyframes fadeIn { @keyframes fadeIn {
from { from {
opacity: 0; opacity: 0;

View File

@@ -1,173 +0,0 @@
// <auto-generated />
using System;
using ApplianceRepair;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ApplianceRepair.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20260424050555_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.12");
modelBuilder.Entity("ApplianceRepair.BusinessConfigRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<string>("SupportEmail")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("BusinessConfig");
});
modelBuilder.Entity("ApplianceRepair.ContentCardRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BelongsToPage")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Group")
.HasColumnType("TEXT");
b.Property<string>("Header")
.HasColumnType("TEXT");
b.Property<string>("Text")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("ContentCards");
});
modelBuilder.Entity("ApplianceRepair.HomePageRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BookHeaderText")
.HasColumnType("TEXT");
b.Property<string>("CallHeaderText")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("HeaderLine1")
.HasColumnType("TEXT");
b.Property<string>("HeaderLine2")
.HasColumnType("TEXT");
b.Property<string>("HeaderText")
.HasColumnType("TEXT");
b.Property<string>("SecondaryHeaderText")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("HomePage");
});
modelBuilder.Entity("ApplianceRepair.RepairRequestMediaRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("MediaPath")
.HasColumnType("TEXT");
b.Property<string>("RequestNumber")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("RepairRequestMedia");
});
modelBuilder.Entity("ApplianceRepair.RepairRequestRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Brand")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Notes")
.HasColumnType("TEXT");
b.Property<string>("Phone")
.HasColumnType("TEXT");
b.Property<string>("RequestNumber")
.HasColumnType("TEXT");
b.Property<string>("Type")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("RepairRequests");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,125 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ApplianceRepair.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "BusinessConfig",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumber = table.Column<string>(type: "TEXT", nullable: true),
SupportEmail = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BusinessConfig", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ContentCards",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
BelongsToPage = table.Column<string>(type: "TEXT", nullable: true),
Group = table.Column<string>(type: "TEXT", nullable: true),
Header = table.Column<string>(type: "TEXT", nullable: true),
Text = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_ContentCards", x => x.Id);
});
migrationBuilder.CreateTable(
name: "HomePage",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
HeaderLine1 = table.Column<string>(type: "TEXT", nullable: true),
HeaderLine2 = table.Column<string>(type: "TEXT", nullable: true),
HeaderText = table.Column<string>(type: "TEXT", nullable: true),
CallHeaderText = table.Column<string>(type: "TEXT", nullable: true),
BookHeaderText = table.Column<string>(type: "TEXT", nullable: true),
SecondaryHeaderText = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_HomePage", x => x.Id);
});
migrationBuilder.CreateTable(
name: "RepairRequestMedia",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
RequestNumber = table.Column<string>(type: "TEXT", nullable: true),
MediaPath = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RepairRequestMedia", x => x.Id);
});
migrationBuilder.CreateTable(
name: "RepairRequests",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
RequestNumber = table.Column<string>(type: "TEXT", nullable: true),
Type = table.Column<string>(type: "TEXT", nullable: true),
Brand = table.Column<string>(type: "TEXT", nullable: true),
Notes = table.Column<string>(type: "TEXT", nullable: true),
Name = table.Column<string>(type: "TEXT", nullable: true),
Phone = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RepairRequests", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BusinessConfig");
migrationBuilder.DropTable(
name: "ContentCards");
migrationBuilder.DropTable(
name: "HomePage");
migrationBuilder.DropTable(
name: "RepairRequestMedia");
migrationBuilder.DropTable(
name: "RepairRequests");
}
}
}

View File

@@ -0,0 +1,421 @@
// <auto-generated />
using System;
using ApplianceRepair;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ApplianceRepair.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20260502001727_InitialDeployment")]
partial class InitialDeployment
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.12");
modelBuilder.Entity("ApplianceRepair.BusinessConfigRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<string>("SupportEmail")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("BusinessConfig");
});
modelBuilder.Entity("ApplianceRepair.ContentCardRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BelongsToPage")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Group")
.HasColumnType("TEXT");
b.Property<string>("Header")
.HasColumnType("TEXT");
b.Property<string>("Text")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("ContentCards");
});
modelBuilder.Entity("ApplianceRepair.HomePageRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("BookHeaderText")
.HasColumnType("TEXT");
b.Property<string>("CallHeaderText")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("HeaderLine1")
.HasColumnType("TEXT");
b.Property<string>("HeaderLine2")
.HasColumnType("TEXT");
b.Property<string>("HeaderText")
.HasColumnType("TEXT");
b.Property<string>("SecondaryHeaderText")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("HomePage");
});
modelBuilder.Entity("ApplianceRepair.RepairRequestMediaRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("MediaPath")
.HasColumnType("TEXT");
b.Property<string>("RequestNumber")
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("RepairRequestMedia");
});
modelBuilder.Entity("ApplianceRepair.RepairRequestRecord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Brand")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Phone")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("RequestNumber")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("RepairRequests");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,328 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ApplianceRepair.Migrations
{
/// <inheritdoc />
public partial class InitialDeployment : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(type: "TEXT", nullable: false),
UserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
Email = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
PasswordHash = table.Column<string>(type: "TEXT", nullable: true),
SecurityStamp = table.Column<string>(type: "TEXT", nullable: true),
ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumber = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumberConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
LockoutEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
AccessFailedCount = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "BusinessConfig",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumber = table.Column<string>(type: "TEXT", nullable: true),
SupportEmail = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BusinessConfig", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ContentCards",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
BelongsToPage = table.Column<string>(type: "TEXT", nullable: true),
Group = table.Column<string>(type: "TEXT", nullable: true),
Header = table.Column<string>(type: "TEXT", nullable: true),
Text = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_ContentCards", x => x.Id);
});
migrationBuilder.CreateTable(
name: "HomePage",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
HeaderLine1 = table.Column<string>(type: "TEXT", nullable: true),
HeaderLine2 = table.Column<string>(type: "TEXT", nullable: true),
HeaderText = table.Column<string>(type: "TEXT", nullable: true),
CallHeaderText = table.Column<string>(type: "TEXT", nullable: true),
BookHeaderText = table.Column<string>(type: "TEXT", nullable: true),
SecondaryHeaderText = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_HomePage", x => x.Id);
});
migrationBuilder.CreateTable(
name: "RepairRequestMedia",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
RequestNumber = table.Column<string>(type: "TEXT", nullable: true),
MediaPath = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RepairRequestMedia", x => x.Id);
});
migrationBuilder.CreateTable(
name: "RepairRequests",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
RequestNumber = table.Column<string>(type: "TEXT", nullable: true),
Type = table.Column<string>(type: "TEXT", nullable: false),
Brand = table.Column<string>(type: "TEXT", nullable: false),
Notes = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Phone = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RepairRequests", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
ProviderKey = table.Column<string>(type: "TEXT", nullable: false),
ProviderDisplayName = table.Column<string>(type: "TEXT", nullable: true),
UserId = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(type: "TEXT", nullable: false),
RoleId = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(type: "TEXT", nullable: false),
LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "BusinessConfig");
migrationBuilder.DropTable(
name: "ContentCards");
migrationBuilder.DropTable(
name: "HomePage");
migrationBuilder.DropTable(
name: "RepairRequestMedia");
migrationBuilder.DropTable(
name: "RepairRequests");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

View File

@@ -137,24 +137,29 @@ namespace ApplianceRepair.Migrations
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("Brand") b.Property<string>("Brand")
.IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Notes") b.Property<string>("Notes")
.IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Phone") b.Property<string>("Phone")
.IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("RequestNumber") b.Property<string>("RequestNumber")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Type") b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<DateTime>("UpdatedAt") b.Property<DateTime>("UpdatedAt")
@@ -164,6 +169,249 @@ namespace ApplianceRepair.Migrations
b.ToTable("RepairRequests"); b.ToTable("RepairRequests");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }

View File

@@ -12,6 +12,9 @@
public ContentCardModel(ContentCardRecord record) public ContentCardModel(ContentCardRecord record)
{ {
Id = record.Id;
CreatedAt = record.CreatedAt;
UpdatedAt = record.UpdatedAt;
BelongsToPage = record.BelongsToPage; BelongsToPage = record.BelongsToPage;
Group = record.Group; Group = record.Group;
Header = record.Header; Header = record.Header;
@@ -98,6 +101,9 @@
List<ContentCardRecord> serviceCards, List<ContentCardRecord> serviceCards,
List<ContentCardRecord> trustCards) List<ContentCardRecord> trustCards)
{ {
Id = homePageRecord.Id;
CreatedAt = homePageRecord.CreatedAt;
UpdatedAt = homePageRecord.UpdatedAt;
HeaderLine1 = homePageRecord.HeaderLine1; HeaderLine1 = homePageRecord.HeaderLine1;
HeaderLine2 = homePageRecord.HeaderLine2; HeaderLine2 = homePageRecord.HeaderLine2;
HeaderText = homePageRecord.HeaderText; HeaderText = homePageRecord.HeaderText;
@@ -155,6 +161,9 @@
public RepairRequestModel(RepairRequestRecord record) public RepairRequestModel(RepairRequestRecord record)
{ {
Id = record.Id;
CreatedAt = record.CreatedAt;
UpdatedAt = record.UpdatedAt;
RequestNumber = record.RequestNumber; RequestNumber = record.RequestNumber;
Type = record.Type; Type = record.Type;
Brand = record.Brand; Brand = record.Brand;
@@ -168,6 +177,9 @@
{ {
public BusinessInfoModel(BusinessConfigRecord record) public BusinessInfoModel(BusinessConfigRecord record)
{ {
Id = record.Id;
CreatedAt = record.CreatedAt;
UpdatedAt = record.UpdatedAt;
Name = record.Name; Name = record.Name;
PhoneNumber = record.PhoneNumber; PhoneNumber = record.PhoneNumber;
SupportEmail = record.SupportEmail; SupportEmail = record.SupportEmail;

View File

@@ -6,14 +6,14 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DatabaseContextConnectionString") ?? throw new InvalidOperationException("Connection string 'DatabaseContextConnectionString' not found."); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
// Add services to the container. // Add services to the container.
builder.Services.AddRazorComponents() builder.Services.AddRazorComponents()
.AddInteractiveServerComponents(); .AddInteractiveServerComponents();
builder.Services.AddDbContext<DatabaseContext>(options => builder.Services.AddDbContext<DatabaseContext>(options =>
options.UseSqlite("Data Source=site.db")); options.UseSqlite(connectionString));
builder.Services.AddMemoryCache(); builder.Services.AddMemoryCache();
builder.Services.AddLogging(); builder.Services.AddLogging();
@@ -45,6 +45,12 @@ builder.Services.AddIdentityCore<IdentityUser>(options => options.SignIn.Require
.AddSignInManager() .AddSignInManager()
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
builder.Services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.MaximumReceiveMessageSize = 10 * 1024 * 1024; // 10MB
});
builder.Services.AddSingleton<IEmailSender<IdentityUser>, IdentityNoOpEmailSender>(); builder.Services.AddSingleton<IEmailSender<IdentityUser>, IdentityNoOpEmailSender>();
var app = builder.Build(); var app = builder.Build();

View File

@@ -27,7 +27,7 @@ namespace ApplianceRepair
} }
else else
{ {
db.HomePage.Update(record); db.Entry(found).CurrentValues.SetValues(record);
} }
await db.SaveChangesAsync(); await db.SaveChangesAsync();
} }
@@ -60,10 +60,20 @@ namespace ApplianceRepair
} }
else else
{ {
db.ContentCards.Update(record); db.Entry(found).CurrentValues.SetValues(record);
} }
await db.SaveChangesAsync(); await db.SaveChangesAsync();
} }
public async Task DeleteRecord(ContentCardRecord record)
{
var found = db.ContentCards.Where((card) => card.Id == record.Id).FirstOrDefault();
if (found != null)
{
db.ContentCards.Remove(found);
await db.SaveChangesAsync();
}
}
} }
public class BusinessConfigReader(DatabaseContext db) public class BusinessConfigReader(DatabaseContext db)
@@ -88,7 +98,7 @@ namespace ApplianceRepair
} }
else else
{ {
db.BusinessConfig.Update(record); db.Entry(found).CurrentValues.SetValues(record);
} }
await db.SaveChangesAsync(); await db.SaveChangesAsync();
} }
@@ -121,7 +131,7 @@ namespace ApplianceRepair
} }
else else
{ {
db.RepairRequests.Update(record); db.Entry(found).CurrentValues.SetValues(record);
} }
await db.SaveChangesAsync(); await db.SaveChangesAsync();
} }

View File

@@ -7,7 +7,7 @@
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": { "ConnectionStrings": {
"DatabaseContextConnectionString": "Data Source=site.db" "DefaultConnection": "Data Source=/var/www/site_data/site.db"
}, },
"SiteDomain": "titanappliancerepair.net" "SiteDomain": "yoursitename.net"
} }

View File

@@ -1,5 +1,13 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@600;700&family=Open+Sans:wght@400;600&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@600;700&family=Open+Sans:wght@400;600&display=swap');
@font-face {
font-family: 'StencilBold';
src: url('fonts/Stencil Std Bold.ttf') format('truetype');
font-weight: Bold;
font-style: normal;
font-display: swap;
}
h1:focus { h1:focus {
outline: none; outline: none;
} }

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB