feat: Add header, game list, start screen

This commit is contained in:
2025-03-05 16:11:47 +01:00
parent e46cb671eb
commit a25ce1a11b
13 changed files with 174 additions and 23 deletions

View File

@@ -40,7 +40,6 @@ public class Game {
var handList = Hand.ToList();
Console.WriteLine("Deck Length: " + Deck.Length);
if (Deck.Length < 1) {
handList[index] = 0;
Hand = [.. handList];

15
frontend/public/logo.svg Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Laag_1" data-name="Laag 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 335.1 198.19">
<defs>
<style>
.cls-1 {
fill: url(#grad1);
}
</style>
<linearGradient id="grad1" gradientTransform="rotate(31.87)">
<stop offset="0%" style="stop-color:#06b4f9;stop-opacity:1" />
<stop offset="100%" style="stop-color:#4e40fc;stop-opacity:1" />
</linearGradient>
</defs>
<polygon class="cls-1" points="98.06 0 129.42 46.97 131.35 46.97 161.81 0 172.77 0 204 46.97 205.16 46.97 224.65 18.37 237.16 0 298.06 0 205.29 141.94 204.13 141.94 168.13 86.84 166.95 87.1 131.1 141.94 129.94 141.94 71.1 52 58.97 52 129.81 159.87 130.97 159.87 166.95 104.9 168 105.03 204 159.87 205.16 159.87 311.1 0 335.1 0 205.16 198.19 204 198.19 167.42 142.58 130.97 198.19 129.81 198.19 20.52 31.61 82.19 31.61 129.81 104.13 130.84 104.13 166.95 48.9 168.13 48.9 203.87 103.87 205.03 103.87 259.23 21.03 246.97 21.03 205.16 84.77 204 84.77 168.13 29.68 166.95 29.68 130.97 84.9 129.94 84.77 87.74 20.9 13.16 20.9 0 0 98.06 0"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,3 +1,16 @@
<style>
app-header {
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
}
.content {
padding-top: 60px; /* Adjust this value based on the height of your header */
}
</style>
<app-header></app-header>
<section class="content min-h-[100%] bg-gray-800 items-center">
<router-outlet></router-outlet> <!-- <app-start-screen /> -->
</section>

View File

@@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HeaderComponent } from './header/header.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule],
imports: [RouterModule, HeaderComponent],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})

View File

@@ -1,4 +1,6 @@
<div class="game-wrapper">
<a class="text-blue-500 hover:underline cursor-pointer mt-1 md:mt-0 md:ml-4 self-start md:self-start" (click)="returnHome()">Go back</a>
<div class="game-container text-gray-200 flex flex-col md:flex-row bg-gray-600 w-[90%] mx-auto md:mt-10 md:rounded-lg md:shadow-lg">
<div class="game-board w-full md:w-3/4 md:mr-0">
@for(card of gameService.hand; track card.id) {
@@ -24,6 +26,11 @@
<span class="font-bold">Started on</span>
<span class="float-right">{{ gameService.stats().dateStarted | date:'dd-MM-YYYY HH:mm' }}</span>
</p>
<p>
<button class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" (click)="deleteGame()">
Delete Game
</button>
</p>
<!-- <p>
<span class="font-bold">Time Played</span>
<span class="float-right">{{ timePlayed }}</span>

View File

@@ -3,7 +3,7 @@ import { GameService } from '../../service/game/game.service';
import { Card } from '../models/card';
import { CommonModule } from '@angular/common';
import { CardComponent } from '../card/card.component';
import { ActivatedRoute, UrlSegment } from '@angular/router';
import { ActivatedRoute, UrlSegment, Router } from '@angular/router';
@Component({
selector: 'app-game',
@@ -15,24 +15,30 @@ import { ActivatedRoute, UrlSegment } from '@angular/router';
export class GameComponent {
gameId: string = '';
constructor(public gameService: GameService, private route: ActivatedRoute) {
constructor(public gameService: GameService, private route: ActivatedRoute, private router: Router) {
this.route.params.subscribe(params => {
this.gameId = params['id'];
// You can use this.gameId to fetch game-specific data if needed
this.attachId(this.gameId);
});
// this.route.snapshot.url.push({ path: this.gameId });
// this.route.snapshot.params['id'] = this.gameId;
// // Update the URL without reloading the page
}
returnHome() {
this.router.navigate(['/']);
}
async attachId(i: string) {
const id = await this.gameService.initGame(i);
this.route.snapshot.url.push(new UrlSegment(id, {}));
window.history.replaceState({}, '', `/game/${id}`);
}
deleteGame() {
this.gameService.deleteGame();
this.returnHome();
}
selectCard(card: Card) {
this.gameService.selectCard(card);
card.selected = !card.selected;

View File

@@ -0,0 +1,13 @@
<header class="flex flex-col items-center bg-gray-900 text-white shadow-lg rounded-sm">
<div class="flex items-center">
<img src="logo.svg" class="w-12 h-12 mr-3">
<h1 class="text-2xl font-bold">SET</h1>
</div>
<nav class="w-full">
<ul class="flex justify-center space-x-6 text-xs mb-2">
<li><a (click)="routeTo('/game-list')" class="cursor-pointer hover:underline">Game List</a></li>
<li><a (click)="routeTo('/')" class="cursor-pointer text-white hover:underline">Back Home</a></li>
<li><a (click)="routeTo('/game')" class="cursor-pointer text-white hover:underline">New Game</a></li>
</ul>
</nav>
</header>

View File

@@ -0,0 +1,52 @@
// .header-container {
// display: flex;
// flex-direction: column;
// align-items: center;
// padding: 20px;
// background-color: #333;
// color: #fff;
// }
// .logo-section {
// display: flex;
// flex-direction: column;
// align-items: center;
// margin-bottom: 20px;
// }
// .logo-image {
// width: 50px;
// }
// .logo-text {
// font-size: 24px;
// font-weight: bold;
// margin-top: 10px;
// }
// .main-nav ul {
// list-style: none;
// padding: 0;
// display: flex;
// gap: 20px;
// }
// .main-nav .nav-link {
// color: #fff;
// text-decoration: none;
// font-size: 18px;
// }
// .main-nav .nav-link:hover {
// text-decoration: underline;
// }
// .new-game-button {
// background-color: #007bff;
// padding: 10px 20px;
// border-radius: 5px;
// }
// .new-game-button:hover {
// background-color: #0056b3;
// }

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HeaderComponent]
})
.compileComponents();
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,17 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-header',
imports: [],
templateUrl: './header.component.html',
styleUrl: './header.component.scss'
})
export class HeaderComponent {
constructor(private router: Router) {}
routeTo(target: string) {
this.router.navigate([target]);
}
}

View File

@@ -1,27 +1,25 @@
<p>yo</p>
<div class="flex flex-col items-center justify-center min-h-screen bg-gray-800">
<div class="flex flex-col items-center justify-center min-h-[100%] mt-20 bg-gray-800">
<div class="text-center p-8 bg-gray-700 rounded-lg shadow-lg max-w-md w-full">
<h1 class="text-4xl font-bold text-gray-100 mb-6">Set Game</h1>
<div class="flex justify-center items-center mb-6">
<!-- <img src="logo.svg" alt="logo" class="w-32 mr-2"> -->
<h1 class="text-4xl font-bold text-gray-100 uppercase italic title">SETGame</h1>
</div>
<div class="space-y-4">
<button
class="w-full py-3 px-6 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-lg transition duration-200 shadow-md cursor-pointer"
(click)="startNewGame()">
class="w-[40%] mx-2 py-3 bg-blue-600 hover:bg-blue-700 text-white font-bold
rounded-xs transition duration-100 shadow-md cursor-pointer"
(click)="startNewGame()"
>
Start New Game
</button>
<button
class="w-full py-3 px-6 bg-gray-500 hover:bg-gray-600 text-white font-bold rounded-lg transition duration-200 shadow-md cursor-pointer"
class="w-[40%] mx-2 py-3 bg-gray-500 hover:bg-gray-600 text-white font-bold
rounded-xs transition duration-100 shadow-md cursor-pointer"
(click)="viewGames()">
View Past Games
</button>
</div>
<div class="mt-8 text-sm text-gray-300">
<p>Match sets of cards based on their properties!</p>
<p class="mt-2">Find as many sets as you can before the deck runs out.</p>
</div>
</div>
</div>
<!-- <app-game /> -->
</div>

View File

@@ -0,0 +1,3 @@
.title {
font-family: 'Courier New', Courier, monospace;
}

View File

@@ -104,4 +104,8 @@ export class GameService {
});
this.selectedCards = [];
}
public async deleteGame() {
await axios.delete('http://localhost:5224/api/v1/Games/' + this.gameId);
}
}