09349cb7b7
Introduced `RegistryItemCategory` entity for grouping and ordering items within registries. Updated `RegistryItem` and `Registry` entities to support categorization. Added database migrations for `RegistryItemCategories` and updated `RegistryItems` with `CategoryId` and `SortOrder`. Implemented drag-and-drop functionality for reordering categories and items using JavaScript and Blazor. Enhanced `RegistryAdmin` and `RegistryPublic` components to manage and display categories with collapsible sections. Updated `RegistryService` to handle category operations, including adding, renaming, removing, and reordering. Added new view models and updated CSS for category styling. Refactored logic to ensure proper ordering and fallback for unassigned items.
155 lines
6.7 KiB
C#
155 lines
6.7 KiB
C#
using BirthList.Domain.Entities;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace BirthList.Infrastructure.Persistence;
|
|
|
|
public class RegistryDbContext(DbContextOptions<RegistryDbContext> options) : DbContext(options)
|
|
{
|
|
public DbSet<Registry> Registries => Set<Registry>();
|
|
public DbSet<RegistryAdmin> RegistryAdmins => Set<RegistryAdmin>();
|
|
public DbSet<RegistryAdminInvite> RegistryAdminInvites => Set<RegistryAdminInvite>();
|
|
public DbSet<RegistrySettings> RegistrySettings => Set<RegistrySettings>();
|
|
public DbSet<RegistryItemCategory> RegistryItemCategories => Set<RegistryItemCategory>();
|
|
public DbSet<RegistryItem> RegistryItems => Set<RegistryItem>();
|
|
public DbSet<ItemPurchase> ItemPurchases => Set<ItemPurchase>();
|
|
public DbSet<ItemContribution> ItemContributions => Set<ItemContribution>();
|
|
public DbSet<RegistryVisit> RegistryVisits => Set<RegistryVisit>();
|
|
public DbSet<UserActionLog> UserActionLogs => Set<UserActionLog>();
|
|
public DbSet<PlatformOwner> PlatformOwners => Set<PlatformOwner>();
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.Entity<Registry>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.Title).HasMaxLength(250);
|
|
entity.Property(x => x.PublicLinkCode).HasMaxLength(100);
|
|
entity.HasIndex(x => x.PublicLinkCode).IsUnique();
|
|
entity.Property(x => x.BabyName).HasMaxLength(100);
|
|
entity.Property(x => x.CurrencyCode).HasMaxLength(3);
|
|
entity.Property(x => x.ThemeKey).HasMaxLength(100);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistryAdmin>(entity =>
|
|
{
|
|
entity.HasKey(x => new { x.RegistryId, x.UserId });
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.Admins)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistryAdminInvite>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.Token).HasMaxLength(120);
|
|
entity.HasIndex(x => x.Token).IsUnique();
|
|
entity.Property(x => x.SentToEmail).HasMaxLength(320);
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.AdminInvites)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistrySettings>(entity =>
|
|
{
|
|
entity.HasKey(x => x.RegistryId);
|
|
entity.Property(x => x.BankAccountIban).HasMaxLength(34);
|
|
entity.Property(x => x.BankAccountBic).HasMaxLength(11);
|
|
entity.Property(x => x.BankAccountDisplayName).HasMaxLength(120);
|
|
entity.Property(x => x.ContributionQrCodeUrl).HasMaxLength(2048);
|
|
entity.Property(x => x.ContributionAmountQrCodesJson).HasMaxLength(4000);
|
|
entity.HasOne(x => x.Registry)
|
|
.WithOne()
|
|
.HasForeignKey<RegistrySettings>(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistryItemCategory>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.Name).HasMaxLength(100);
|
|
entity.HasIndex(x => new { x.RegistryId, x.SortOrder });
|
|
entity.HasIndex(x => new { x.RegistryId, x.Name });
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.ItemCategories)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistryItem>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.Name).HasMaxLength(300);
|
|
entity.Property(x => x.PictureUrl).HasMaxLength(2048);
|
|
entity.Property(x => x.ProductUrl).HasMaxLength(2048);
|
|
entity.Property(x => x.CurrencyCode).HasMaxLength(3);
|
|
entity.Property(x => x.PriceAmount).HasPrecision(18, 2);
|
|
entity.Property(x => x.ParticipationTargetAmount).HasPrecision(18, 2);
|
|
entity.Property(x => x.MoneyFulfilledAmount).HasPrecision(18, 2);
|
|
entity.HasIndex(x => new { x.CategoryId, x.SortOrder });
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.Items)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
entity.HasOne(x => x.Category)
|
|
.WithMany(x => x.Items)
|
|
.HasForeignKey(x => x.CategoryId)
|
|
.OnDelete(DeleteBehavior.NoAction);
|
|
});
|
|
|
|
modelBuilder.Entity<ItemPurchase>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.HasOne(x => x.RegistryItem)
|
|
.WithMany(x => x.Purchases)
|
|
.HasForeignKey(x => x.RegistryItemId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<ItemContribution>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.Property(x => x.CurrencyCode).HasMaxLength(3);
|
|
entity.Property(x => x.Amount).HasPrecision(18, 2);
|
|
entity.Property(x => x.TransferMessage).HasMaxLength(500);
|
|
entity.HasOne(x => x.RegistryItem)
|
|
.WithMany(x => x.Contributions)
|
|
.HasForeignKey(x => x.RegistryItemId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<RegistryVisit>(entity =>
|
|
{
|
|
entity.HasKey(x => new { x.RegistryId, x.UserId });
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.Visits)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<UserActionLog>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.Property(x => x.Amount).HasPrecision(18, 2);
|
|
entity.Property(x => x.Details).HasMaxLength(500);
|
|
entity.HasOne(x => x.Registry)
|
|
.WithMany(x => x.ActionLogs)
|
|
.HasForeignKey(x => x.RegistryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<PlatformOwner>(entity =>
|
|
{
|
|
entity.HasKey(x => x.Id);
|
|
entity.Property(x => x.UserId).HasMaxLength(450);
|
|
entity.HasIndex(x => x.UserId).IsUnique();
|
|
});
|
|
}
|
|
}
|