Compare commits

...

6 Commits

Author SHA1 Message Date
beo3000 f373f24c77 optimierung PinPanel Layout 2026-01-11 16:36:34 +01:00
beo3000 cf753af407 mod css 2026-01-11 15:18:14 +01:00
beo3000 55d3357683 fix goodwood 2026-01-11 15:17:21 +01:00
beo3000 799474e9b9 design koogle -> GoodWood 2026-01-11 14:39:50 +01:00
beo3000 c6e89ecdb6 added gameevents 2026-01-11 13:11:27 +01:00
beo3000 99b9994c32 added gif test-runs 2026-01-11 12:39:10 +01:00
36 changed files with 215 additions and 52 deletions

View File

@ -8,7 +8,7 @@ The development guidelines to consider are descibed in [docs/development_guideli
Blazor Server app (.NET 9.0) with Clean Architecture: Domain, Application, Infrastructure, Web layers. Uses ASP.NET Core Identity with dual DbContext pattern (AppDbContext for domain, AppIdentityDbContext for auth), MudBlazor UI, and Fluxor state management. Blazor Server app (.NET 9.0) with Clean Architecture: Domain, Application, Infrastructure, Web layers. Uses ASP.NET Core Identity with dual DbContext pattern (AppDbContext for domain, AppIdentityDbContext for auth), MudBlazor UI, and Fluxor state management.
The name for the App is KOOGLE. Koogle is an app for club management. The name for the App is GOODWOOD. GoodWood is an app for club management.
### Functional ### Functional
- Club management - Club management

View File

@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{63E5B7FE-3
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
docs\build.md = docs\build.md docs\build.md = docs\build.md
CLAUDE.md = CLAUDE.md CLAUDE.md = CLAUDE.md
design.md = design.md
..\..\..\..\Users\d-chrka\Downloads\Moodboard.png = ..\..\..\..\Users\d-chrka\Downloads\Moodboard.png
todos.md = todos.md todos.md = todos.md
EndProjectSection EndProjectSection
EndProject EndProject

0
design.md Normal file
View File

View File

@ -286,6 +286,17 @@ public class ChristmasTreeGameLogicService : IGameLogicService
// Get winner ID (first player of winning team) // Get winner ID (first player of winning team)
Guid? winnerId = model.Teams[winnerIndex].PlayerIds.FirstOrDefault(); Guid? winnerId = model.Teams[winnerIndex].PlayerIds.FirstOrDefault();
var winningTeam = model.Teams[winnerIndex];
// Create game event for winning team
var gameEvents = new List<GameEvent>
{
new TeamWonEvent
{
TeamName = winningTeam.Name,
PlayerIds = winningTeam.PlayerIds
}
};
// Calculate penalties for losing teams // Calculate penalties for losing teams
foreach (var (teamIndex, state) in teamTrees) foreach (var (teamIndex, state) in teamTrees)
@ -318,7 +329,8 @@ public class ChristmasTreeGameLogicService : IGameLogicService
WinnerTeamIndex = winnerIndex, WinnerTeamIndex = winnerIndex,
IsInContinueMode = false, IsInContinueMode = false,
ContinueThrowsRemaining = 0, ContinueThrowsRemaining = 0,
OpponentSelectingTeamIndex = null OpponentSelectingTeamIndex = null,
PendingGameEvents = gameEvents
}; };
return (model, new ThrowResult return (model, new ThrowResult
@ -577,6 +589,17 @@ public class ChristmasTreeGameLogicService : IGameLogicService
} }
Guid? winnerId = model.Teams[winnerIndex].PlayerIds.FirstOrDefault(); Guid? winnerId = model.Teams[winnerIndex].PlayerIds.FirstOrDefault();
var winningTeam = model.Teams[winnerIndex];
// Create game event for winning team
var gameEvents = new List<GameEvent>
{
new TeamWonEvent
{
TeamName = winningTeam.Name,
PlayerIds = winningTeam.PlayerIds
}
};
// Calculate penalties // Calculate penalties
foreach (var (teamIndex, state) in teamTrees) foreach (var (teamIndex, state) in teamTrees)
@ -605,7 +628,8 @@ public class ChristmasTreeGameLogicService : IGameLogicService
OpponentSelectingTeamIndex = null, OpponentSelectingTeamIndex = null,
IsGameOver = true, IsGameOver = true,
WinnerId = winnerId, WinnerId = winnerId,
WinnerTeamIndex = winnerIndex WinnerTeamIndex = winnerIndex,
PendingGameEvents = gameEvents
}; };
return GameActionResult.SuccessResult( return GameActionResult.SuccessResult(

View File

@ -64,6 +64,7 @@ namespace Koogle.Application.Games.FoxHunt
var playerStates = new Dictionary<Guid, FoxHuntPlayerState>(model.PlayerStates); var playerStates = new Dictionary<Guid, FoxHuntPlayerState>(model.PlayerStates);
var triggers = new List<TriggerEvent>(); var triggers = new List<TriggerEvent>();
var gameEvents = new List<GameEvent>();
var foxId = model.PlayerOrder[model.FoxIndex]; var foxId = model.PlayerOrder[model.FoxIndex];
//var lastHunterId = model.GetPrev(model.PlayerOrder, model.FoxIndex); //var lastHunterId = model.GetPrev(model.PlayerOrder, model.FoxIndex);
@ -134,6 +135,7 @@ namespace Koogle.Application.Games.FoxHunt
if (playerStates[key].PinCountFox - playerStates[key].PinCountHunters == maxLeading) if (playerStates[key].PinCountFox - playerStates[key].PinCountHunters == maxLeading)
{ {
playerStates[key].IsWinner = true; playerStates[key].IsWinner = true;
gameEvents.Add(new PlayerWonEvent { PlayerId = key });
} }
} }
} }
@ -146,7 +148,8 @@ namespace Koogle.Application.Games.FoxHunt
FoxIndex = model.FoxIndex, FoxIndex = model.FoxIndex,
FoxTurn = model.FoxTurn, FoxTurn = model.FoxTurn,
FoxTurnsRemaining = model.FoxTurnsRemaining, FoxTurnsRemaining = model.FoxTurnsRemaining,
NonFoxIndex = model.NonFoxIndex NonFoxIndex = model.NonFoxIndex,
PendingGameEvents = gameEvents
}; };
var result = new ThrowResult var result = new ThrowResult

View File

@ -59,6 +59,7 @@ public class ShitGameLogicService : IGameLogicService
bool shouldRotate = false; bool shouldRotate = false;
var triggers = new List<TriggerEvent>(); var triggers = new List<TriggerEvent>();
var gameEvents = new List<GameEvent>();
if (isShitNumber || isGutter) if (isShitNumber || isGutter)
{ {
@ -103,10 +104,13 @@ public class ShitGameLogicService : IGameLogicService
// Check for winner // Check for winner
if (newPoints == 0) if (newPoints == 0)
{ {
gameEvents.Add(new PlayerWonEvent { PlayerId = playerId });
model = model with model = model with
{ {
WinnerId = playerId, WinnerId = playerId,
IsGameOver = true IsGameOver = true,
PendingGameEvents = gameEvents
}; };
// Fire triggers for losers (all players except winner) // Fire triggers for losers (all players except winner)

View File

@ -6,8 +6,8 @@
<style> <style>
.pin { .pin {
width: 48px; width: 64px;
height: 48px; height: 64px;
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
@ -16,9 +16,9 @@
user-select: none; user-select: none;
transition: all 0.15s ease; transition: all 0.15s ease;
font-weight: bold; font-weight: bold;
font-size: 1.2rem; font-size: 1.5rem;
border: 3px solid transparent; border: 3px solid transparent;
box-shadow: 0 2px 4px rgba(0,0,0,0.2); box-shadow: 0 3px 6px rgba(0,0,0,0.25);
} }
.pin:hover:not(.pin-disabled) { .pin:hover:not(.pin-disabled) {
@ -54,9 +54,9 @@
@@media (max-width: 600px) { @@media (max-width: 600px) {
.pin { .pin {
width: 40px; width: 52px;
height: 40px; height: 52px;
font-size: 1rem; font-size: 1.25rem;
} }
} }
</style> </style>

View File

@ -37,26 +37,54 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 8px; gap: 12px;
padding: 16px; padding: 20px;
background: var(--mud-palette-surface); background: var(--mud-palette-surface);
border-radius: 8px; border-radius: 8px;
width: 100%;
max-width: 400px;
} }
.pin-row { .pin-row {
display: flex; display: flex;
gap: 8px; justify-content: center;
width: 100%;
}
.pin-row-1 {
justify-content: center;
}
.pin-row-2 {
gap: 80px;
}
.pin-row-3 {
gap: 70px;
}
.pin-row-4 {
gap: 80px;
}
.pin-row-5 {
justify-content: center; justify-content: center;
} }
@@media (max-width: 600px) { @@media (max-width: 600px) {
.pin-panel { .pin-panel {
gap: 6px; gap: 10px;
padding: 12px; padding: 16px;
max-width: 320px;
} }
.pin-row { .pin-row-2,
gap: 6px; .pin-row-4 {
gap: 60px;
}
.pin-row-3 {
gap: 50px;
} }
} }
</style> </style>

View File

@ -8,7 +8,7 @@
@code { @code {
// Default theme - configurable for future theme selection // Default theme - configurable for future theme selection
private MudTheme _theme = CustomThemes.DefaultTheme; private MudTheme _theme = CustomThemes.GoodwoodTheme;
} }
<main> <main>

View File

@ -22,7 +22,7 @@
<MudLayout> <MudLayout>
<MudAppBar Elevation="1" Dense="true" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudAppBar Elevation="1" Dense="true" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="ToggleDrawer" /> <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="ToggleDrawer" />
<MudText Typo="Typo.h6">KOOGLE</MudText> <MudText Typo="Typo.h6">KOOGLE</MudText>
<MudSpacer/> <MudSpacer/>
@ -100,7 +100,7 @@
} }
// Default theme - can be changed per user in future // Default theme - can be changed per user in future
private MudTheme _theme = CustomThemes.DefaultTheme; private MudTheme _theme = CustomThemes.GoodwoodTheme;
private void ClearAuthError() private void ClearAuthError()
{ {

View File

@ -8,7 +8,7 @@
<MudSnackbarProvider /> <MudSnackbarProvider />
<MudLayout> <MudLayout>
<MudAppBar Elevation="1" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%);"> <MudAppBar Elevation="1" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%);">
@* Mobile Menu Button (unter lg: 1280px) - LINKS *@ @* Mobile Menu Button (unter lg: 1280px) - LINKS *@
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Class="mobile-only" OnClick="ToggleDrawer" /> <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Class="mobile-only" OnClick="ToggleDrawer" />
@ -23,8 +23,8 @@
<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
<MudButton Href="/dashboard" Variant="Variant.Filled" Color="Color.Success" StartIcon="@Icons.Material.Filled.Dashboard"> <MudButton Href="/dashboard" Variant="Variant.Filled" Color="Color.Secondary" StartIcon="@Icons.Material.Filled.Dashboard">
Dashboard &Uuml;bersicht
</MudButton> </MudButton>
</Authorized> </Authorized>
<NotAuthorized> <NotAuthorized>
@ -40,7 +40,7 @@
@* Logo - RECHTS *@ @* Logo - RECHTS *@
<MudLink Href="/" Class="d-flex align-center" Style="text-decoration: none;"> <MudLink Href="/" Class="d-flex align-center" Style="text-decoration: none;">
<MudPaper Class="pa-0 rounded-lg" Style="background: #2d5a4d;" Elevation="2"> <MudPaper Class="pa-0 rounded-lg" Style="background: #2d5a4d;" Elevation="2">
<MudImage Src="logo6_bg.png" Alt="KOOGLE" Height="32" /> <MudImage Src="gw_app_icon2.png" Alt="KOOGLE" Height="32" />
</MudPaper> </MudPaper>
</MudLink> </MudLink>
</MudAppBar> </MudAppBar>
@ -93,7 +93,7 @@
</MudLayout> </MudLayout>
@code { @code {
private MudTheme _theme = CustomThemes.DefaultTheme; private MudTheme _theme = CustomThemes.GoodwoodTheme;
private bool _drawerOpen; private bool _drawerOpen;
private void ToggleDrawer() => _drawerOpen = !_drawerOpen; private void ToggleDrawer() => _drawerOpen = !_drawerOpen;

View File

@ -6,7 +6,7 @@
<MudContainer MaxWidth="MaxWidth.Large" Class="py-8"> <MudContainer MaxWidth="MaxWidth.Large" Class="py-8">
@* Hero Section *@ @* Hero Section *@
<MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Von der Totenkiste zum Cloud-System</MudText> <MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Von der Totenkiste zum Cloud-System</MudText>
<MudText Typo="Typo.h6" Style="opacity: 0.9;">Unsere Story</MudText> <MudText Typo="Typo.h6" Style="opacity: 0.9;">Unsere Story</MudText>
</MudPaper> </MudPaper>

View File

@ -4,6 +4,8 @@
@using Koogle.Application.DTOs @using Koogle.Application.DTOs
@using Koogle.Application.Interfaces @using Koogle.Application.Interfaces
@using Koogle.Domain.Enums @using Koogle.Domain.Enums
@using Koogle.Web.Components.Game
@using Koogle.Web.Store.GifState
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@inject IClubGifService GifService @inject IClubGifService GifService
@ -11,9 +13,13 @@
@inject ISnackbar Snackbar @inject ISnackbar Snackbar
@inject IDialogService DialogService @inject IDialogService DialogService
@inject IClubTerminologyService Term @inject IClubTerminologyService Term
@inject IDispatcher Dispatcher
<PageTitle>GIF-Verwaltung</PageTitle> <PageTitle>GIF-Verwaltung</PageTitle>
<!-- GIF Player Overlay -->
<GifPlayer ShowRating="true" />
<MudText Typo="Typo.h4" Class="mb-2">GIF-Verwaltung</MudText> <MudText Typo="Typo.h4" Class="mb-2">GIF-Verwaltung</MudText>
<MudText Typo="Typo.body2" Color="Color.Secondary" Class="mb-4"> <MudText Typo="Typo.body2" Color="Color.Secondary" Class="mb-4">
GIFs und Videos fuer Wurf-Ereignisse verwalten GIFs und Videos fuer Wurf-Ereignisse verwalten
@ -104,6 +110,12 @@
</MudTd> </MudTd>
<MudTd> <MudTd>
<MudStack Row="true" Spacing="1"> <MudStack Row="true" Spacing="1">
<MudTooltip Text="Gif testen">
<MudIconButton Icon="@Icons.Material.Filled.RunCircle"
Size="Size.Small"
Color="Color.Success"
OnClick="@(() => TestGif(context))" />
</MudTooltip>
<MudTooltip Text="Bearbeiten"> <MudTooltip Text="Bearbeiten">
<MudIconButton Icon="@Icons.Material.Filled.Edit" <MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="Size.Small" Size="Size.Small"
@ -573,4 +585,19 @@
public void CopyTo(Stream target) => _stream.CopyTo(target); public void CopyTo(Stream target) => _stream.CopyTo(target);
public async Task CopyToAsync(Stream target, CancellationToken ct = default) => await _stream.CopyToAsync(target, ct); public async Task CopyToAsync(Stream target, CancellationToken ct = default) => await _stream.CopyToAsync(target, ct);
} }
private async Task TestGif(ClubGifDto gifdto)
{
var ev = gifdto.AssignedEvents;
var p = new GifPlaybackDto
{
Id = gifdto.Id,
Url = gifdto.Url,
ContentType = gifdto.ContentType,
Name = gifdto.Name,
EventType = ev
};
Dispatcher.Dispatch(new GifPlaybackStartedAction(p, ev));
}
} }

View File

@ -6,7 +6,7 @@
<MudContainer MaxWidth="MaxWidth.Large" Class="py-8"> <MudContainer MaxWidth="MaxWidth.Large" Class="py-8">
@* Hero Section *@ @* Hero Section *@
<MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Blog</MudText> <MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Blog</MudText>
<MudText Typo="Typo.h6" Style="opacity: 0.9;">Neuigkeiten rund um KOOGLE</MudText> <MudText Typo="Typo.h6" Style="opacity: 0.9;">Neuigkeiten rund um KOOGLE</MudText>
</MudPaper> </MudPaper>
@ -30,7 +30,7 @@
</MudPaper> </MudPaper>
@* Newsletter Teaser *@ @* Newsletter Teaser *@
<MudPaper Class="pa-6 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-6 rounded-lg" Style="background:linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h6" Align="Align.Center" Class="font-weight-bold mb-2"> <MudText Typo="Typo.h6" Align="Align.Center" Class="font-weight-bold mb-2">
Bleib auf dem Laufenden! Bleib auf dem Laufenden!
</MudText> </MudText>

View File

@ -8,7 +8,7 @@
<MudContainer MaxWidth="MaxWidth.Large" Class="py-0"> <MudContainer MaxWidth="MaxWidth.Large" Class="py-0">
<MudImage src="logo6_bg.png" alt="KOOGLE Logo" Height="80" />
@* Hero Section *@ @* Hero Section *@
<div class="hero-section mb-8 rounded-lg"> <div class="hero-section mb-8 rounded-lg">
<div class="hero-overlay"> <div class="hero-overlay">
@ -17,7 +17,8 @@
<MudItem xs="12" md="8"> <MudItem xs="12" md="8">
<MudStack Spacing="4"> <MudStack Spacing="4">
<MudStack Spacing="3" Class="hero-stack"> <MudStack Spacing="3" Class="hero-stack">
<MudText Typo="Typo.h3" Class="hero-title" Style="color: white;">KOOGLE - Die smarte Lösung für Kegelclubs</MudText> <MudImage src="logo7.png" alt="GoodWood Logo" Height="120" />
<MudText Typo="Typo.h3" Class="hero-title" Style="color: white;">GOODWOOD - Die smarte Lösung für Kegelclubs</MudText>
</MudStack> </MudStack>
<MudText Typo="Typo.h6" Style="color: white; opacity: 0.9;"> <MudText Typo="Typo.h6" Style="color: white; opacity: 0.9;">
Mehr Zeit fürs Kegeln, weniger für den Papierkram. Mehr Zeit fürs Kegeln, weniger für den Papierkram.
@ -29,7 +30,7 @@
<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
<MudButton Variant="Variant.Filled" Color="Color.Success" StartIcon="@Icons.Material.Filled.Dashboard" Href="/dashboard"> <MudButton Variant="Variant.Filled" Color="Color.Secondary" StartIcon="@Icons.Material.Filled.Dashboard" Href="/dashboard">
zur Anwendung zur Anwendung
</MudButton> </MudButton>
</Authorized> </Authorized>
@ -62,7 +63,7 @@
@* Features Section *@ @* Features Section *@
<div id="features"> <div id="features">
<MudText Typo="Typo.h5" Class="mb-4 font-weight-bold" Color="Color.Primary"> <MudText Typo="Typo.h5" Class="mb-4 font-weight-bold" Color="Color.Primary">
Deine Vorteile mit KOOGLE Deine Vorteile mit GoodWood
</MudText> </MudText>
@ -234,14 +235,14 @@
<MudStack Row AlignItems="AlignItems.Center" Spacing="2"> <MudStack Row AlignItems="AlignItems.Center" Spacing="2">
<MudIcon Icon="@Icons.Material.Filled.Circle" Color="Color.Success" Size="Size.Small" /> <MudIcon Icon="@Icons.Material.Filled.Circle" Color="Color.Success" Size="Size.Small" />
<MudText> <MudText>
Schon über <strong>1</strong> Kegelclubs vertrauen auf KOOGLE. ;-) Schon über <strong>1</strong> Kegelclubs vertrauen auf GoodWood. ;-)
</MudText> </MudText>
</MudStack> </MudStack>
</MudPaper> </MudPaper>
@* Footer Slogan *@ @* Footer Slogan *@
<MudPaper Class="pa-6 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-6 rounded-lg" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h5" Align="Align.Center" Class="font-weight-bold"> <MudText Typo="Typo.h5" Align="Align.Center" Class="font-weight-bold">
"Weniger Verwaltung, mehr Kegeln!" "Weniger Verwaltung, mehr Kegeln!"
</MudText> </MudText>
@ -249,7 +250,7 @@
@* Copyright Footer *@ @* Copyright Footer *@
<MudStack Row Justify="Justify.Center" AlignItems="AlignItems.Center" Spacing="4" Class="mt-6"> <MudStack Row Justify="Justify.Center" AlignItems="AlignItems.Center" Spacing="4" Class="mt-6">
<MudText Typo="Typo.caption" Color="Color.Secondary">© 2026 KOOGLE. Alle Rechte vorbehalten.</MudText> <MudText Typo="Typo.caption" Color="Color.Secondary">© 2026 GoodWood. Alle Rechte vorbehalten.</MudText>
<MudLink Href="/about" Typo="Typo.caption" Color="Color.Secondary">Über uns</MudLink> <MudLink Href="/about" Typo="Typo.caption" Color="Color.Secondary">Über uns</MudLink>
<MudLink Href="/impressum" Typo="Typo.caption" Color="Color.Secondary">Impressum</MudLink> <MudLink Href="/impressum" Typo="Typo.caption" Color="Color.Secondary">Impressum</MudLink>
<MudLink Href="/datenschutz" Typo="Typo.caption" Color="Color.Secondary">Datenschutz</MudLink> <MudLink Href="/datenschutz" Typo="Typo.caption" Color="Color.Secondary">Datenschutz</MudLink>
@ -271,12 +272,22 @@
position: relative; position: relative;
} }
.hero-overlay { /* .hero-overlay {
background: linear-gradient(135deg, rgba(26, 54, 93, 0.92) 0%, rgba(45, 90, 77, 0.75) 100%); background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%);
min-height: 400px; min-height: 400px;
display: flex; display: flex;
align-items: center; align-items: center;
border-radius: inherit; border-radius: inherit;
} */
.hero-overlay {
/* Wir nutzen RGBA, um die Farben des Moodboards mit Transparenz zu mischen */
/* 0.85 bedeutet 85% Deckkraft - das Bild schimmert dezent durch */
background: linear-gradient(135deg, rgba(27, 48, 34, 0.9) 0%, rgba(74, 93, 78, 0.7) 100%);
min-height: 400px;
display: flex;
align-items: center;
border-radius: inherit;
width: 100%; /* Sicherstellen, dass es die volle Breite einnimmt */
} }
.hero-overlay .mud-typography { .hero-overlay .mud-typography {

View File

@ -6,7 +6,7 @@
<MudContainer MaxWidth="MaxWidth.Large" Class="py-8"> <MudContainer MaxWidth="MaxWidth.Large" Class="py-8">
@* Hero Section *@ @* Hero Section *@
<MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-8 mb-8 rounded-lg" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Preise</MudText> <MudText Typo="Typo.h4" Class="font-weight-bold mb-2">Preise</MudText>
<MudText Typo="Typo.h6" Style="opacity: 0.9;">Faire Konditionen für alle Kegelvereine</MudText> <MudText Typo="Typo.h6" Style="opacity: 0.9;">Faire Konditionen für alle Kegelvereine</MudText>
</MudPaper> </MudPaper>
@ -40,7 +40,7 @@
</MudPaper> </MudPaper>
@* CTA *@ @* CTA *@
<MudPaper Class="pa-6 rounded-lg" Style="background: linear-gradient(135deg, #1a365d 0%, #2d5a4d 100%); color: white;"> <MudPaper Class="pa-6 rounded-lg" Style="background: linear-gradient(135deg, #1B3022 0%, #4A5D4E 100%); color: white;">
<MudText Typo="Typo.h6" Align="Align.Center" Class="font-weight-bold mb-4"> <MudText Typo="Typo.h6" Align="Align.Center" Class="font-weight-bold mb-4">
Worauf wartest du noch? Worauf wartest du noch?
</MudText> </MudText>

View File

@ -42,6 +42,70 @@ namespace Koogle.Web.Services
// } // }
}; };
public static readonly MudTheme GoodwoodTheme = new()
{
PaletteLight = new PaletteLight()
{
// Hintergrund & Oberflächen (Moodboard: Soft Sand #F5F2ED)
Background = "#F5F2ED",
Surface = "#FFFFFF",
AppbarBackground = "#1B3022", // Deep Forest Green für Kontrast
AppbarText = "#F5F2ED",
// Markenfarben
Primary = "#1B3022", // Deep Forest Green
PrimaryContrastText = "#F5F2ED",
Secondary = "#B66D35", // Burnt Ochre / Wood
SecondaryContrastText = "#FFFFFF",
Tertiary = "#4A5D4E", // Ein weicheres Waldgrün für Akzente
// Status & Feedback
Info = "#4A708B",
Success = "#6B8E23", // Olive-Grün passend zum Naturthema
Warning = "#D2691E",
Error = "#8B0000",
// Texte & Linien
TextPrimary = "#1A1A1A",
TextSecondary = "#4A5D4E",
Divider = "rgba(27, 48, 34, 0.12)",
LinesDefault = "rgba(27, 48, 34, 0.2)",
DrawerBackground = "#F5F2ED",
DrawerText = "#1B3022",
DrawerIcon = "#1B3022",
},
PaletteDark = new PaletteDark()
{
// Dark Mode Umkehrung für professionelle Software
Background = "#121A14", // Extrem dunkles Grün/Schwarz
Surface = "#1B3022",
Primary = "#F5F2ED", // Im Darkmode wird Sand zur Kontrastfarbe
Secondary = "#B66D35",
AppbarBackground = "#0D1811",
TextPrimary = "#F5F2ED",
TextSecondary = "rgba(245, 242, 237, 0.7)",
DrawerBackground = "#0D1811",
},
LayoutProperties = new LayoutProperties()
{
DefaultBorderRadius = "6px", // Etwas weicher als Standard, aber modern flach
AppbarHeight = "64px",
},
Typography = new Typography()
{
Default = new DefaultTypography
{
FontFamily = new[] { "Inter", "Roboto", "Helvetica", "Arial", "sans-serif" },
FontSize = ".875rem",
FontWeight = "400"
},
H1 = new H1Typography { FontWeight = "700", FontSize = "3.5rem", LetterSpacing = "-.02em" },
H2 = new H2Typography { FontWeight = "600", FontSize = "2.5rem", LetterSpacing = "-.01em" },
Button = new ButtonTypography { FontWeight = "600", TextTransform = "none" } // "none" wirkt moderner als All-Caps
}
};
public static readonly MudTheme SandstoneTheme = new() public static readonly MudTheme SandstoneTheme = new()
{ {
PaletteLight = new PaletteLight() PaletteLight = new PaletteLight()

View File

@ -6,8 +6,8 @@
"EnableSeeding": true, "EnableSeeding": true,
"CreateDefaultClub": true, "CreateDefaultClub": true,
"SuperAdmin": { "SuperAdmin": {
"Email": "ch@koogle.de", "Email": "ch@goodwood.de",
"UserName": "ch@koogle.de", "UserName": "ch@goodwood.de",
"Password": "DEV_only3000!" "Password": "DEV_only3000!"
}, },
"DefaultClub": { "DefaultClub": {
@ -15,7 +15,7 @@
}, },
"Demo": { "Demo": {
"Enabled": true, "Enabled": true,
"Email": "demo@koogle.de", "Email": "demo@goodwood.de",
"Password": "Demo123!", "Password": "Demo123!",
"ClubName": "Demo Club", "ClubName": "Demo Club",
"LoginName": "demo" "LoginName": "demo"

View File

@ -34,11 +34,11 @@
"SmtpSettings": { "SmtpSettings": {
"Host": "smtp.ionos.de", "Host": "smtp.ionos.de",
"Port": 587, "Port": 587,
"Username": "koogle@straso.com", "Username": "goodwood@straso.com",
"Password": "bX3MrtX2ps95&pZodh&Ui0JlWL&oA&", "Password": "bX3MrtX2ps95&pZodh&Ui0JlWL&oA&",
"UseSsl": true, "UseSsl": true,
"DefaultSenderEmail": "koogle@straso.com", "DefaultSenderEmail": "goodwood@straso.com",
"DefaultSenderName": "KOOGLE", "DefaultSenderName": "GoodWood",
"Enabled": true "Enabled": true
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 865 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

View File

@ -1,11 +1,11 @@
{ {
"name": "KOOGLE", "name": "GOODWOOD",
"short_name": "KOOGLE", "short_name": "GOODWOOD",
"description": "Koogle Club Management App", "description": "GoodWood Kegel & Vereinsverwaltung",
"start_url": "/", "start_url": "/",
"display": "standalone", "display": "standalone",
"background_color": "#2c3e50", "background_color": "#F5F2ED",
"theme_color": "#2c3e50", "theme_color": "#F5F2ED",
"icons": [ "icons": [
{ {
"src": "/icons/icon-192x192.png", "src": "/icons/icon-192x192.png",