mirror of
https://github.com/Wessel/nhl-setgame.git
synced 2026-07-25 09:47:45 +02:00
feat: Add header, game list, start screen
This commit is contained in:
@@ -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
15
frontend/public/logo.svg
Normal 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 |
@@ -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>
|
||||
|
||||
@@ -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']
|
||||
})
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
13
frontend/src/app/header/header.component.html
Normal file
13
frontend/src/app/header/header.component.html
Normal 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>
|
||||
52
frontend/src/app/header/header.component.scss
Normal file
52
frontend/src/app/header/header.component.scss
Normal 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;
|
||||
// }
|
||||
23
frontend/src/app/header/header.component.spec.ts
Normal file
23
frontend/src/app/header/header.component.spec.ts
Normal 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();
|
||||
});
|
||||
});
|
||||
17
frontend/src/app/header/header.component.ts
Normal file
17
frontend/src/app/header/header.component.ts
Normal 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]);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
.title {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
@@ -104,4 +104,8 @@ export class GameService {
|
||||
});
|
||||
this.selectedCards = [];
|
||||
}
|
||||
|
||||
public async deleteGame() {
|
||||
await axios.delete('http://localhost:5224/api/v1/Games/' + this.gameId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user