diff --git a/Components/Pages/Book.razor b/Components/Pages/Book.razor new file mode 100644 index 0000000..e27ca70 --- /dev/null +++ b/Components/Pages/Book.razor @@ -0,0 +1,86 @@ +@page "/book" +@using Microsoft.AspNetCore.Components.Forms + +
+
+

Request an Appointment

+

Complete the form below and a technician will review your case.

+
+ + + + +
+
+

1. Appliance Details

+ +
+ + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+

2. Photos & Contact

+ +
+

Upload Photos/Video

+

Tip: A photo of the model number sticker helps us arrive with the right parts!

+ + + + @if (SelectedFiles.Any()) + { +
@SelectedFiles.Count files attached
+ } +
+ +
+ + +
+ +
+ + +
+
+
+ + +
+
diff --git a/Components/Pages/Book.razor.cs b/Components/Pages/Book.razor.cs new file mode 100644 index 0000000..d3f0737 --- /dev/null +++ b/Components/Pages/Book.razor.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Components.Forms; + +namespace ApplianceRepair.Components.Pages +{ + public partial class Book() + { + private RepairRequestModel Model = new(); + private List SelectedFiles = new(); + + private void HandleFiles(InputFileChangeEventArgs e) => SelectedFiles.AddRange(e.GetMultipleFiles()); + + private async Task HandleSubmit() + { + // Logic to process the request + } + } +} diff --git a/Components/Pages/Book.razor.css b/Components/Pages/Book.razor.css new file mode 100644 index 0000000..a2b25cf --- /dev/null +++ b/Components/Pages/Book.razor.css @@ -0,0 +1,105 @@ +.booking-page { + padding: 60px 20px; +} + +.booking-form-wrapper { + background: #fff; + padding: 40px; + border-radius: 8px; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); + border-top: 5px solid #0056b3; +} + +.form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; +} + +.form-heading { + color: #0056b3; + margin-bottom: 20px; + font-size: 1.3rem; + border-bottom: 1px solid #eee; + padding-bottom: 10px; +} + +.field-group { + margin-bottom: 20px; + margin-right: 20px; +} + +.field-group label { + display: block; + font-weight: bold; + margin-bottom: 8px; + color: #333; +} + +::deep .custom-input { + width: 100%; + padding: 12px; + border: 1px solid #ddd; + border-radius: 5px; + font-size: 1rem; +} + +::deep .textarea { + height: 120px; + resize: none; +} + +/* Upload Styling */ +.upload-zone { + background: #f8f9fa; + border: 2px dashed #0056b3; + padding: 20px; + text-align: center; + border-radius: 8px; + margin-bottom: 25px; +} + +.small-text { + font-size: 0.85rem; + color: #666; + margin: 10px 0; +} + +.file-input { + display: none; +} + +.file-count { + margin-top: 10px; + font-size: 0.9rem; + color: #0056b3; + font-weight: bold; +} + +.form-footer { + text-align: center; + margin-top: 30px; +} + +.btn-large { + background: #4CAF50; + color: white; + border: none; + padding: 15px 40px; + border-radius: 50px; + font-weight: 700; + cursor: pointer; + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); + transition: all 0.3s ease; +} + +/* Match your mobile responsiveness */ +@media (max-width: 768px) { + .form-grid { + grid-template-columns: 1fr; + } + + .booking-form-wrapper { + padding: 20px; + } +} diff --git a/Components/Pages/Home.Razor.cs b/Components/Pages/Home.Razor.cs index fce5cda..2bb8ccb 100644 --- a/Components/Pages/Home.Razor.cs +++ b/Components/Pages/Home.Razor.cs @@ -10,31 +10,7 @@ namespace ApplianceRepair.Components.Pages { if (!cache.TryGetValue(nameof(HomePageModel), out Model)) { - Model = Defaults.DefaultHomePageContent; - - var homePageRecord = await homePageReader.ReadLatestRecord(); - if (homePageRecord != null) - { - Model = new HomePageModel(homePageRecord); - - var serviceCardRecords = await contentCardReader.ReadAllByPageAndGroup(nameof(Home), "Services"); - if (serviceCardRecords != null) - { - foreach (var record in serviceCardRecords) - { - Model.ServicesCards!.Add(new ContentCardModel(record)); - } - } - - var trustCardRecords = await contentCardReader.ReadAllByPageAndGroup(nameof(Home), "Trust"); - if (trustCardRecords != null) - { - foreach (var record in trustCardRecords) - { - Model.TrustCards!.Add(new ContentCardModel(record)); - } - } - } + Model = await homePageReader.ReadLatestRecordWithModel(contentCardReader) ?? Defaults.DefaultHomePageContent; var cacheOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromHours(24)) @@ -43,6 +19,5 @@ namespace ApplianceRepair.Components.Pages cache.Set(nameof(HomePageModel), Model, cacheOptions); } } - } } diff --git a/Components/Pages/Home.razor b/Components/Pages/Home.razor index 8f137dc..540ef72 100644 --- a/Components/Pages/Home.razor +++ b/Components/Pages/Home.razor @@ -21,8 +21,8 @@ else

@Model.HeaderLine1
@Model.HeaderLine2

@Model.HeaderText

- @Model.HeaderButton1Text - @Model.HeaderButton2Text + Call for Same-Day Service + Request an Appointment
diff --git a/Components/Pages/admin/EditPages.razor b/Components/Pages/admin/EditPages.razor new file mode 100644 index 0000000..fb8802a --- /dev/null +++ b/Components/Pages/admin/EditPages.razor @@ -0,0 +1,111 @@ +@page "/admin/editpages" +@rendermode InteractiveServer + +
+
+
+

Page Content Management

+

Update your business details and home page content below.

+
+ + @if (HomePageModel == null) + { +
+
+

Loading your settings...

+
+ } + else + { +
+
+
+
+ +
+
+ + @if (currentTab == AdminTab.Home) + { + + + +
+

🏠 Hero Section

+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+

🛠️ Services

+
+ @foreach (var card in HomePageModel.ServicesCards) + { +
+
+ + +
+ +
+ + +
+
+ } +
+ +
+ +
+

🛡️ Trust

+
+ @foreach (var card in HomePageModel.TrustCards) + { +
+
+ + +
+ +
+ + +
+
+ } +
+ +
+ + +
+ } + else + { +

Another page

+ } +
+
+ } +
+
diff --git a/Components/Pages/admin/EditPages.razor.cs b/Components/Pages/admin/EditPages.razor.cs new file mode 100644 index 0000000..2ca5fe9 --- /dev/null +++ b/Components/Pages/admin/EditPages.razor.cs @@ -0,0 +1,64 @@ +namespace ApplianceRepair.Components.Pages.admin +{ + public partial class EditPages(HomePageReader homePageReader, ContentCardReader contentCardReader) + { + public HomePageModel? HomePageModel; + + private enum AdminTab { Home, About } + private AdminTab currentTab = AdminTab.Home; + + override + protected async void OnInitialized() + { + HomePageModel = await homePageReader.ReadLatestRecordWithModel(contentCardReader) ?? Defaults.DefaultHomePageContent; + } + + private async void RevertHomePageModel() + { + HomePageModel = await homePageReader.ReadLatestRecordWithModel(contentCardReader) ?? Defaults.DefaultHomePageContent; + } + + private async void SaveHomePageModel() + { + HomePageModel.CreatedAt = DateTime.Now; + HomePageModel.UpdatedAt = DateTime.Now; + + foreach (var card in HomePageModel.ServicesCards) + { + await contentCardReader.UpdateRecord(card); + } + + foreach (var card in HomePageModel.TrustCards) + { + await contentCardReader.UpdateRecord(card); + } + + await homePageReader.AddRecord(HomePageModel); + } + + private void AddServiceCard() + { + HomePageModel?.ServicesCards.Add(new ContentCardModel() { + CreatedAt = DateTime.Now, + UpdatedAt = DateTime.Now, + BelongsToPage = HomePageModel.PageName, + Group = HomePageModel.ContentCardTypes.Service.ToString(), + Header = "Service Name", + Text = "Short Description" + }); + } + + private async void AddTrustCard() + { + HomePageModel?.TrustCards.Add(new ContentCardModel() + { + CreatedAt = DateTime.Now, + UpdatedAt = DateTime.Now, + BelongsToPage = HomePageModel.PageName, + Group = HomePageModel.ContentCardTypes.Trust.ToString(), + Header = "Header", + Text = "Short Description" + }); + } + } +} diff --git a/Components/Pages/admin/EditPages.razor.css b/Components/Pages/admin/EditPages.razor.css new file mode 100644 index 0000000..77a3f83 --- /dev/null +++ b/Components/Pages/admin/EditPages.razor.css @@ -0,0 +1,240 @@ +.admin-wrapper { + background-color: #f4f7f6; + min-height: 100vh; + padding: 60px 0; + font-family: 'Open Sans', sans-serif; +} + +.admin-header { + text-align: center; + margin-bottom: 40px; +} + +.admin-footer { + text-align: center; +} + +.tab-container { + display: inline-flex; + background: #e0e6ed; + padding: 5px; + border-radius: 50px; + margin-top: 20px; +} + +.tab-btn { + padding: 10px 25px; + border: none; + background: transparent; + font-family: 'Montserrat', sans-serif; + font-weight: 600; + cursor: pointer; + border-radius: 50px; + transition: all 0.3s ease; + color: #666; +} + +.tab-btn.active { + background: #2a5298; /* Your Trust Blue */ + color: white; + box-shadow: 0 4px 10px rgba(42, 82, 152, 0.2); +} + +h1 { + font-family: 'Montserrat', sans-serif; + color: #2a5298; + font-weight: 700; +} + +.form-section { + background: #fff; + padding: 100px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.05); + margin-bottom: 30px; + border: 1px solid #f0f0f0; + font-family: 'Montserrat', sans-serif; +} + +.text-center { + text-align: center; + max-width: 70vw; + margin-left: auto; + margin-right: auto; +} + +.form-section h3 { + color: #2a5298; + margin-bottom: 20px; + font-size: 1.2rem; + border-bottom: 2px solid #f4f7f6; + padding-bottom: 10px; +} + +.input-group { + margin-bottom: 20px; +} + +.input-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; +} + +label { + display: block; + font-family: 'Montserrat', sans-serif; + font-weight: 600; + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.5px; + color: #2a5298; + margin-bottom: 8px; + margin-top: 15px; +} + +.cards-grid { + display: flex; + flex-direction: row; + align-content: center; + justify-content: center; + column-gap: 2rem; + + padding-top: 2rem; + padding-bottom: 2rem; +} + +.content-card { + background: #fcfcfc; + border: 1px solid #e0e6ed; + border-radius: 12px; + padding: 20px; + + transition: transform 0.2s ease; + + display: flex; + flex-direction: column; + align-content: center; +} + +.content-card:hover { + border-color: #2a5298; + box-shadow: 0 5px 15px rgba(0,0,0,0.05); +} + +.content-card .input-group { + max-width: 100%; + + display: flex; + flex-direction: column; + align-content: center; +} + +.content-card ::deep .form-input { + max-width: 80%; + align-self: center; +} + +::deep .form-input, +::deep textarea.form-input { + width: 100%; + padding: 14px 18px; + font-size: 1rem; + font-family: 'Open Sans', sans-serif; + color: #444; + background-color: #ffffff; + border: 2px solid #e0e6ed; + border-radius: 12px; + transition: all 0.2s ease-in-out; + display: block; + box-shadow: inset 0 1px 2px rgba(0,0,0,0.02); +} + +::deep .form-input:focus, +::deep textarea.form-input:focus { + outline: none; + border-color: #2a5298; + background-color: #fff; + box-shadow: 0 0 0 4px rgba(42, 82, 152, 0.1); +} + +::deep textarea.form-input { + min-height: 120px; + resize: vertical; + line-height: 1.5; +} + +.btn-save { + background: #4CAF50; + color: white; + border: none; + padding: 15px 40px; + border-radius: 50px; + font-weight: 700; + cursor: pointer; + box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3); + transition: all 0.3s ease; + max-width: 10vw; +} + +.btn-save:hover { + transform: translateY(-2px); + background: #43a047; +} + +.btn-revert { + background: transparent; + color: #666; + border: 2px solid #ccc; + padding: 15px 30px; + border-radius: 50px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + margin-left: 10px; + max-width: 30vw; +} + +.btn-revert:hover { + background: #eee; + color: #333; + border-color: #999; +} + +.status-msg { + margin-left: 20px; + color: #4CAF50; + font-weight: 600; + animation: fadeIn 0.5s ease; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@media (max-width: 768px) { + .input-row { + grid-template-columns: 1fr; + } + + .btn-save { + max-width: 40vw; + } + + .btn-revert { + max-width: 40vw; + } + + .cards-grid { + flex-direction: column; + align-content: center; + justify-content: center; + row-gap: 2rem; + } +} \ No newline at end of file diff --git a/Data.cs b/Data.cs index 51d99ff..2f950b8 100644 --- a/Data.cs +++ b/Data.cs @@ -44,4 +44,13 @@ public string? PhoneNumber { get; set; } public string? SupportEmail { get; set; } } + + public class RepairRequestRecord + { + public string? Type { get; set; } + public string? Brand { get; set; } + public string? Notes { get; set; } + public string? Name { get; set; } + public string? Phone { get; set; } + } } diff --git a/DatabaseContext.cs b/DatabaseContext.cs index 54f598c..d4be826 100644 --- a/DatabaseContext.cs +++ b/DatabaseContext.cs @@ -7,5 +7,6 @@ namespace ApplianceRepair public DbSet HomePage { get; set; } public DbSet ContentCards { get; set; } public DbSet BusinessConfig { get; set; } + public DbSet RepairRequests { get; set; } } } diff --git a/Migrations/20260202020516_InitialCreate.Designer.cs b/Migrations/20260202020516_InitialCreate.Designer.cs deleted file mode 100644 index 60f1b63..0000000 --- a/Migrations/20260202020516_InitialCreate.Designer.cs +++ /dev/null @@ -1,124 +0,0 @@ -// -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("20260202020516_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.12"); - - modelBuilder.Entity("ApplianceRepair.BusinessConfigRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("SupportEmail") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("BusinessConfig"); - }); - - modelBuilder.Entity("ApplianceRepair.ContentCardRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("BelongsToPage") - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Group") - .HasColumnType("TEXT"); - - b.Property("Header") - .HasColumnType("TEXT"); - - b.Property("Text") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("ContentCards"); - }); - - modelBuilder.Entity("ApplianceRepair.HomePageRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CopyrightText") - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("HeaderButton1Link") - .HasColumnType("TEXT"); - - b.Property("HeaderButton1Text") - .HasColumnType("TEXT"); - - b.Property("HeaderButton2Link") - .HasColumnType("TEXT"); - - b.Property("HeaderButton2Text") - .HasColumnType("TEXT"); - - b.Property("HeaderLine1") - .HasColumnType("TEXT"); - - b.Property("HeaderLine2") - .HasColumnType("TEXT"); - - b.Property("HeaderText") - .HasColumnType("TEXT"); - - b.Property("SecondaryHeaderText") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("HomePage"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Migrations/20260202020516_InitialCreate.cs b/Migrations/20260202020516_InitialCreate.cs deleted file mode 100644 index 5dfe9ad..0000000 --- a/Migrations/20260202020516_InitialCreate.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ApplianceRepair.Migrations -{ - /// - public partial class InitialCreate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "BusinessConfig", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CreatedAt = table.Column(type: "TEXT", nullable: false), - UpdatedAt = table.Column(type: "TEXT", nullable: false), - Name = table.Column(type: "TEXT", nullable: true), - PhoneNumber = table.Column(type: "TEXT", nullable: true), - SupportEmail = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_BusinessConfig", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "ContentCards", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CreatedAt = table.Column(type: "TEXT", nullable: false), - UpdatedAt = table.Column(type: "TEXT", nullable: false), - BelongsToPage = table.Column(type: "TEXT", nullable: true), - Group = table.Column(type: "TEXT", nullable: true), - Header = table.Column(type: "TEXT", nullable: true), - Text = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ContentCards", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HomePage", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CreatedAt = table.Column(type: "TEXT", nullable: false), - UpdatedAt = table.Column(type: "TEXT", nullable: false), - HeaderLine1 = table.Column(type: "TEXT", nullable: true), - HeaderLine2 = table.Column(type: "TEXT", nullable: true), - HeaderText = table.Column(type: "TEXT", nullable: true), - HeaderButton1Text = table.Column(type: "TEXT", nullable: true), - HeaderButton2Text = table.Column(type: "TEXT", nullable: true), - HeaderButton1Link = table.Column(type: "TEXT", nullable: true), - HeaderButton2Link = table.Column(type: "TEXT", nullable: true), - SecondaryHeaderText = table.Column(type: "TEXT", nullable: true), - CopyrightText = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_HomePage", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "BusinessConfig"); - - migrationBuilder.DropTable( - name: "ContentCards"); - - migrationBuilder.DropTable( - name: "HomePage"); - } - } -} diff --git a/Migrations/DatabaseContextModelSnapshot.cs b/Migrations/DatabaseContextModelSnapshot.cs deleted file mode 100644 index 5dbb96e..0000000 --- a/Migrations/DatabaseContextModelSnapshot.cs +++ /dev/null @@ -1,121 +0,0 @@ -// -using System; -using ApplianceRepair; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace ApplianceRepair.Migrations -{ - [DbContext(typeof(DatabaseContext))] - partial class DatabaseContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.12"); - - modelBuilder.Entity("ApplianceRepair.BusinessConfigRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Name") - .HasColumnType("TEXT"); - - b.Property("PhoneNumber") - .HasColumnType("TEXT"); - - b.Property("SupportEmail") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("BusinessConfig"); - }); - - modelBuilder.Entity("ApplianceRepair.ContentCardRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("BelongsToPage") - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Group") - .HasColumnType("TEXT"); - - b.Property("Header") - .HasColumnType("TEXT"); - - b.Property("Text") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("ContentCards"); - }); - - modelBuilder.Entity("ApplianceRepair.HomePageRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CopyrightText") - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("HeaderButton1Link") - .HasColumnType("TEXT"); - - b.Property("HeaderButton1Text") - .HasColumnType("TEXT"); - - b.Property("HeaderButton2Link") - .HasColumnType("TEXT"); - - b.Property("HeaderButton2Text") - .HasColumnType("TEXT"); - - b.Property("HeaderLine1") - .HasColumnType("TEXT"); - - b.Property("HeaderLine2") - .HasColumnType("TEXT"); - - b.Property("HeaderText") - .HasColumnType("TEXT"); - - b.Property("SecondaryHeaderText") - .HasColumnType("TEXT"); - - b.Property("UpdatedAt") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("HomePage"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Models.cs b/Models.cs index 97420c7..773f2e7 100644 --- a/Models.cs +++ b/Models.cs @@ -21,6 +21,13 @@ public class HomePageModel : HomePageRecord { + public static string PageName = "Home"; + public enum ContentCardTypes + { + Service, + Trust, + } + public string BusinessName { get; set; } public string FormattedPhoneNumber { get; set; } public string PhoneNumberCallLink { get; set; } @@ -69,7 +76,7 @@ } } - public class BusinessConfig : BusinessConfigRecord + public class RepairRequestModel : RepairRequestRecord { } diff --git a/Program.cs b/Program.cs index 8a4698f..0206065 100644 --- a/Program.cs +++ b/Program.cs @@ -26,7 +26,6 @@ using (var scope = app.Services.CreateScope()) try { services.GetRequiredService().Database.EnsureCreated(); - services.GetRequiredService().Database } catch (Exception ex) { diff --git a/Services.cs b/Services.cs index 70cdaf7..c51fc85 100644 --- a/Services.cs +++ b/Services.cs @@ -6,7 +6,40 @@ namespace ApplianceRepair { public async Task ReadLatestRecord() { - return await db.HomePage.OrderByDescending(page => page.Id).FirstAsync(); + var records = await db.HomePage.OrderByDescending(page => page.Id).FirstOrDefaultAsync(); + return records; + } + + public async Task ReadLatestRecordWithModel(ContentCardReader contentCardReader) + { + var record = await db.HomePage.OrderByDescending(page => page.Id).FirstOrDefaultAsync(); + if (record == null) + { + return null; + } + + var model = new HomePageModel(record); + var pageName = HomePageModel.PageName; + + var services = await contentCardReader.ReadAllByPageAndGroup(pageName, HomePageModel.ContentCardTypes.Service.ToString()) ?? []; + foreach (var card in services) + { + model.ServicesCards.Add(new ContentCardModel(card)); + } + + var trust = await contentCardReader.ReadAllByPageAndGroup(pageName, HomePageModel.ContentCardTypes.Trust.ToString()) ?? []; + foreach (var card in trust) + { + model.TrustCards.Add(new ContentCardModel(card)); + } + + return model; + } + + public async Task AddRecord(HomePageRecord record) + { + await db.AddAsync(record); + await db.SaveChangesAsync(); } } @@ -21,6 +54,25 @@ namespace ApplianceRepair { return await db.ContentCards.Where(card => card.BelongsToPage == belongsToPage).ToListAsync(); } + + public async Task AddRecord(ContentCardRecord record) + { + await db.ContentCards.AddAsync(record); + } + + public async Task UpdateRecord(ContentCardRecord record) + { + var found = db.ContentCards.Where((card) => card.Id == record.Id).FirstOrDefault(); + if (found == null) + { + await AddRecord(record); + } + else + { + db.ContentCards.Update(record); + } + await db.SaveChangesAsync(); + } } public class BusinessConfigReader(DatabaseContext db)