Compare commits
6 Commits
8c18d634c8
...
f373f24c77
| Author | SHA1 | Date |
|---|---|---|
|
|
f373f24c77 | |
|
|
cf753af407 | |
|
|
55d3357683 | |
|
|
799474e9b9 | |
|
|
c6e89ecdb6 | |
|
|
99b9994c32 |
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
Ü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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 865 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 239 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 782 B |
|
Before Width: | Height: | Size: 793 B After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 454 KiB |
|
After Width: | Height: | Size: 174 KiB |
|
|
@ -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",
|
||||||
|
|
|
||||||