From c466348d1840355186c26e8483be8bbedd77d7d2 Mon Sep 17 00:00:00 2001 From: AzuTear Date: Mon, 29 Jun 2026 09:08:56 +0200 Subject: [PATCH] Extract season overview/workflow cards and add sponsor seed data Splits AdminSeasonsView into AdminSeasonOverviewCard and AdminSeasonWorkflowCard for cleaner separation of concerns. Adds SeedSponsorsBootstrapper with demo sponsor SVG assets and extends SeedCatalog with sponsor seed entries. Co-Authored-By: Claude Sonnet 4.6 --- Backend/Data/SeedCatalog.cs | 40 ++ Backend/Data/SeedDataBootstrapper.cs | 1 + Backend/Data/SeedSponsorsBootstrapper.cs | 40 ++ .../demo/sponsors/chibicanvas-market.svg | 17 + .../demo/sponsors/cloudbeacon-hosting.svg | 15 + .../demo/sponsors/hoshiforge-studio.svg | 13 + .../public/demo/sponsors/nekopixel-energy.svg | 17 + .../public/demo/sponsors/prismloop-audio.svg | 15 + .../admin/AdminSeasonOverviewCard.vue | 97 ++++ .../admin/AdminSeasonWorkflowCard.vue | 388 +++++++++++++++ frontend/src/views/admin/AdminSeasonsView.vue | 471 +----------------- 11 files changed, 668 insertions(+), 446 deletions(-) create mode 100644 Backend/Data/SeedSponsorsBootstrapper.cs create mode 100644 frontend/public/demo/sponsors/chibicanvas-market.svg create mode 100644 frontend/public/demo/sponsors/cloudbeacon-hosting.svg create mode 100644 frontend/public/demo/sponsors/hoshiforge-studio.svg create mode 100644 frontend/public/demo/sponsors/nekopixel-energy.svg create mode 100644 frontend/public/demo/sponsors/prismloop-audio.svg create mode 100644 frontend/src/components/admin/AdminSeasonOverviewCard.vue create mode 100644 frontend/src/components/admin/AdminSeasonWorkflowCard.vue diff --git a/Backend/Data/SeedCatalog.cs b/Backend/Data/SeedCatalog.cs index 2ebc782..608eced 100644 --- a/Backend/Data/SeedCatalog.cs +++ b/Backend/Data/SeedCatalog.cs @@ -7,6 +7,7 @@ internal sealed record CandidateSeed(string CategorySlug, string DisplayName, st internal sealed record WinnerSeed(int Year, string CategorySlug, string DisplayName, string ChannelSlug, string Platform); internal sealed record SiteFaqSeed(string Question, string Answer); internal sealed record SiteSocialSeed(string Label, string Platform, string Url, string Icon); +internal sealed record SponsorSeed(string Name, string WebsiteUrl, string LogoUrl, string Description, string Tier, int SortOrder); internal static class SeedCatalog { @@ -141,4 +142,43 @@ Partner werden im Rahmen der Show und auf den öffentlichen Kontaktflächen gena new(2023, "community-liebling-rising-star", "Sora Blau", "@sorablau", "YouTube"), new(2023, "best-collab-duo-rising-star", "Yuki & Melo", "@yukistern", "Twitch"), ]; + + internal static readonly SponsorSeed[] DemoSponsorSeeds = + [ + new( + "HoshiForge Studio", + "https://hoshiforge.example", + "/demo/sponsors/hoshiforge-studio.svg", + "Branding-, Overlay- und Debuet-Visuals fuer VTuber-Projekte und Community-Events.", + "Presenting Sponsor", + 10), + new( + "NekoPixel Energy", + "https://nekopixel.example", + "/demo/sponsors/nekopixel-energy.svg", + "Community-fokussierter Drink-Partner fuer lange Showabende, Watchpartys und Creator-Collabs.", + "Gold Partner", + 20), + new( + "PrismLoop Audio", + "https://prismloop.example", + "/demo/sponsors/prismloop-audio.svg", + "Audio-Tools, Intro-Packs und Stream-Sounddesign fuer Live-Shows und Highlight-Clips.", + "Gold Partner", + 30), + new( + "CloudBeacon Hosting", + "https://cloudbeacon.example", + "/demo/sponsors/cloudbeacon-hosting.svg", + "Skalierbares Hosting fuer Voting, Landingpages und Event-Traffic rund um Showtage.", + "Tech Partner", + 40), + new( + "ChibiCanvas Market", + "https://chibicanvas.example", + "/demo/sponsors/chibicanvas-market.svg", + "Merch-, Sticker- und Artist-Marketplace mit Fokus auf VTuber, Emotes und Fanartikel.", + "Community Partner", + 50), + ]; } diff --git a/Backend/Data/SeedDataBootstrapper.cs b/Backend/Data/SeedDataBootstrapper.cs index 15c344f..f3680ac 100644 --- a/Backend/Data/SeedDataBootstrapper.cs +++ b/Backend/Data/SeedDataBootstrapper.cs @@ -22,6 +22,7 @@ public static partial class SeedDataBootstrapper if (seasons.TryGetValue(2026, out var currentSeason)) { await EnsureCandidatesAsync(db, currentSeason, SeedCatalog.CurrentCandidateSeeds); + await EnsureSponsorsAsync(db, currentSeason); await EnsureSeedOperationalDataAsync(db, currentSeason); } diff --git a/Backend/Data/SeedSponsorsBootstrapper.cs b/Backend/Data/SeedSponsorsBootstrapper.cs new file mode 100644 index 0000000..862ecb1 --- /dev/null +++ b/Backend/Data/SeedSponsorsBootstrapper.cs @@ -0,0 +1,40 @@ +using Backend.Domain; +using Microsoft.EntityFrameworkCore; + +namespace Backend.Data; + +public static partial class SeedDataBootstrapper +{ + private static async Task EnsureSponsorsAsync(AwardsDbContext db, Season season) + { + var existingSponsors = await db.Sponsors + .Where(item => item.SeasonId == season.Id) + .ToListAsync(); + + foreach (var seed in SeedCatalog.DemoSponsorSeeds) + { + var sponsor = existingSponsors.FirstOrDefault(item => + string.Equals(item.Name, seed.Name, StringComparison.OrdinalIgnoreCase)) + ?? new Sponsor + { + SeasonId = season.Id, + CreatedAt = DateTimeOffset.UtcNow, + }; + + sponsor.Name = seed.Name; + sponsor.WebsiteUrl = seed.WebsiteUrl; + sponsor.LogoUrl = seed.LogoUrl; + sponsor.Description = seed.Description; + sponsor.Tier = seed.Tier; + sponsor.SortOrder = seed.SortOrder; + sponsor.IsVisible = true; + sponsor.UpdatedAt = DateTimeOffset.UtcNow; + + if (sponsor.Id == 0) + { + db.Sponsors.Add(sponsor); + existingSponsors.Add(sponsor); + } + } + } +} diff --git a/frontend/public/demo/sponsors/chibicanvas-market.svg b/frontend/public/demo/sponsors/chibicanvas-market.svg new file mode 100644 index 0000000..bae2b52 --- /dev/null +++ b/frontend/public/demo/sponsors/chibicanvas-market.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/frontend/public/demo/sponsors/cloudbeacon-hosting.svg b/frontend/public/demo/sponsors/cloudbeacon-hosting.svg new file mode 100644 index 0000000..546d639 --- /dev/null +++ b/frontend/public/demo/sponsors/cloudbeacon-hosting.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/frontend/public/demo/sponsors/hoshiforge-studio.svg b/frontend/public/demo/sponsors/hoshiforge-studio.svg new file mode 100644 index 0000000..d4c9852 --- /dev/null +++ b/frontend/public/demo/sponsors/hoshiforge-studio.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/frontend/public/demo/sponsors/nekopixel-energy.svg b/frontend/public/demo/sponsors/nekopixel-energy.svg new file mode 100644 index 0000000..24b3451 --- /dev/null +++ b/frontend/public/demo/sponsors/nekopixel-energy.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/frontend/public/demo/sponsors/prismloop-audio.svg b/frontend/public/demo/sponsors/prismloop-audio.svg new file mode 100644 index 0000000..77b068f --- /dev/null +++ b/frontend/public/demo/sponsors/prismloop-audio.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/frontend/src/components/admin/AdminSeasonOverviewCard.vue b/frontend/src/components/admin/AdminSeasonOverviewCard.vue new file mode 100644 index 0000000..4842dce --- /dev/null +++ b/frontend/src/components/admin/AdminSeasonOverviewCard.vue @@ -0,0 +1,97 @@ + + + diff --git a/frontend/src/components/admin/AdminSeasonWorkflowCard.vue b/frontend/src/components/admin/AdminSeasonWorkflowCard.vue new file mode 100644 index 0000000..2f23405 --- /dev/null +++ b/frontend/src/components/admin/AdminSeasonWorkflowCard.vue @@ -0,0 +1,388 @@ + + + diff --git a/frontend/src/views/admin/AdminSeasonsView.vue b/frontend/src/views/admin/AdminSeasonsView.vue index 3136961..3bfcbfb 100644 --- a/frontend/src/views/admin/AdminSeasonsView.vue +++ b/frontend/src/views/admin/AdminSeasonsView.vue @@ -1,33 +1,20 @@