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 @@