From 2b031b4b2471cdc3ac5d7456d89f2423a8f86a32 Mon Sep 17 00:00:00 2001 From: ForkBench <robinvandemerghel@protonmail.com> Date: Wed, 10 Jul 2024 23:56:26 +0200 Subject: [PATCH] Base of Svelte, and Back management. --- astro/services/Competition.go | 81 ++---- astro/services/Person.go | 21 +- astro/services/Session.go | 59 +++- astro/services/Stage.go | 1 + frontend/index.html | 27 +- frontend/package-lock.json | 25 ++ frontend/package.json | 9 +- frontend/public/style.css | 67 +---- frontend/src/App.svelte | 27 +- frontend/src/components/NavBar.svelte | 94 +++++++ frontend/src/components/Registrations.svelte | 268 +++++++++++++++++++ main.go | 9 +- 12 files changed, 514 insertions(+), 174 deletions(-) create mode 100644 frontend/src/components/NavBar.svelte create mode 100644 frontend/src/components/Registrations.svelte diff --git a/astro/services/Competition.go b/astro/services/Competition.go index 4c85011..6af2f67 100644 --- a/astro/services/Competition.go +++ b/astro/services/Competition.go @@ -1,7 +1,5 @@ package services -import "math" - // Competition : Competition details type Competition struct { CompetitionID uint8 // 255 competitions max @@ -10,8 +8,8 @@ type Competition struct { CompetitionWeapon Weapon CompetitionState State CompetitionMaxStageNumber uint8 - CompetitionStages []Stage - CompetitionPlayers []Player + CompetitionStages map[uint8]*Stage + CompetitionPlayers map[uint16]*Player } func (c *Competition) String() string { @@ -27,50 +25,12 @@ func CreateCompetition(competitionID uint8, competitionName string, competitionC c.CompetitionWeapon = competitionWeapon c.CompetitionState = REGISTERING c.CompetitionMaxStageNumber = competitionMaxStageNumber - c.CompetitionStages = []Stage{} - c.CompetitionPlayers = []Player{} + c.CompetitionStages = map[uint8]*Stage{} + c.CompetitionPlayers = map[uint16]*Player{} return c } -func (c *Competition) AddStage(stage Stage) bool { - if c.CompetitionState != IDLE { - return false - } - - if len(c.CompetitionStages) >= int(c.CompetitionMaxStageNumber) { - return false - } - - c.CompetitionStages = append(c.CompetitionStages, stage) - - return true -} - -func (c *Competition) StagePosition(stage Stage) uint16 { - for i, competitionStage := range c.CompetitionStages { - if competitionStage == stage { - return uint16(i) - } - } - - return math.MaxInt16 -} - -func (c *Competition) RemoveStage(stage Stage) bool { - if c.CompetitionState != IDLE { - return false - } - - if c.StagePosition(stage) == math.MaxInt16 { - return false - } - - c.CompetitionStages = append(c.CompetitionStages[:c.StagePosition(stage)], c.CompetitionStages[c.StagePosition(stage)+1:]...) - - return true -} - func (c *Competition) StartCompetition() bool { if c.CompetitionState != REGISTERING { return false @@ -93,38 +53,26 @@ func (c *Competition) FinishCompetition() bool { return true } -func (c *Competition) AddPlayer(player Player) bool { +func (c *Competition) AddPlayer(player *Player) bool { if c.CompetitionState != REGISTERING { return false } - c.CompetitionPlayers = append(c.CompetitionPlayers, player) + c.CompetitionPlayers[player.PlayerID] = player return true } -func (c *Competition) PlayerPosition(player Player) uint16 { - for i, competitionPlayer := range c.CompetitionPlayers { - if competitionPlayer == player { - return uint16(i) - } - } - - return math.MaxInt16 -} - -func (c *Competition) RemovePlayer(player Player) bool { +func (c *Competition) RemovePlayer(player *Player) bool { if c.CompetitionState != REGISTERING { return false } - pos := c.PlayerPosition(player) - - if pos == math.MaxInt16 { + if _, ok := c.CompetitionPlayers[player.PlayerID]; !ok { return false } - c.CompetitionPlayers = append(c.CompetitionPlayers[:pos], c.CompetitionPlayers[pos+1:]...) + delete(c.CompetitionPlayers, player.PlayerID) return true } @@ -136,3 +84,14 @@ func (c *Competition) AddPlayerToStage(player Player, stage Stage) bool { func (c *Competition) RemovePlayerFromStage(player Player, stage Stage) bool { return stage.RemovePlayer(player) } + +func (c *Competition) UpdatePlayer(player *Player) bool { + // Check if player is in competition + if _, ok := c.CompetitionPlayers[player.PlayerID]; !ok { + return false + } + + c.CompetitionPlayers[player.PlayerID] = player + + return true +} diff --git a/astro/services/Person.go b/astro/services/Person.go index 4161d08..8233f4c 100644 --- a/astro/services/Person.go +++ b/astro/services/Person.go @@ -5,9 +5,9 @@ type Player struct { PlayerID uint16 // More than 255 players PlayerFirstname string PlayerLastname string - PlayerNationID uint16 - PlayerRegionID uint16 - PlayerClubID uint16 + PlayerNation *Nation + PlayerRegion *Region + PlayerClub *Club PlayerInitialRank uint16 } @@ -15,15 +15,12 @@ func (p Player) String() string { return "Player : " + p.PlayerFirstname + " " + p.PlayerLastname } -func CreatePlayer(playerID uint16, playerFirstname string, playerLastname string) Player { - var p Player - - p.PlayerID = playerID - p.PlayerFirstname = playerFirstname - p.PlayerLastname = playerLastname - p.PlayerInitialRank = 10000 - - return p +func CreatePlayer(playerID uint16, playerFirstname string, playerLastname string) *Player { + return &Player{ + PlayerID: playerID, + PlayerFirstname: playerFirstname, + PlayerLastname: playerLastname, + } } // Referee : Person details diff --git a/astro/services/Session.go b/astro/services/Session.go index 2d6fae9..b673da6 100644 --- a/astro/services/Session.go +++ b/astro/services/Session.go @@ -4,7 +4,7 @@ const MinStageSize = 3 // Session : Session details type Session struct { - Competitions []Competition + Competitions [](*Competition) CompetitionNumber uint8 } @@ -16,7 +16,7 @@ func (s *Session) AddCompetition(name string, category string, weapon string) { CreateWeapon(weapon), MinStageSize) - s.Competitions = append(s.Competitions, competition) + s.Competitions = append(s.Competitions, &competition) s.CompetitionNumber++ } @@ -30,28 +30,49 @@ func (s *Session) RemoveCompetition(competitionID uint8) { } func (s *Session) GetCompetitions() []Competition { - return s.Competitions + comps := []Competition{} + for _, competition := range s.Competitions { + comps = append(comps, *competition) + } + return comps } -func (s *Session) GetCompetition(competitionID uint8) Competition { +func (s *Session) GetCompetition(competitionID uint8) *Competition { for _, competition := range s.Competitions { if competition.CompetitionID == competitionID { return competition } } - return Competition{} + return nil } -func (s *Session) AddPlayerToCompetition(competitionID uint8, player Player) bool { +func (s *Session) AddPlayerToCompetition(competitionID uint8, player *Player) bool { competition := s.GetCompetition(competitionID) - if competition.CompetitionName == "" { + if competition == nil { + return false + } + + if player == nil { return false } + // If player id is UINT16MAX, set it + var id uint16 = 0 + for { + // Check if id is already taken + _, ok := competition.CompetitionPlayers[id] + if !ok { + break + } + id++ + } + + player.PlayerID = id + return competition.AddPlayer(player) } -func (s *Session) RemovePlayerFromCompetition(competitionID uint8, player Player) bool { +func (s *Session) RemovePlayerFromCompetition(competitionID uint8, player *Player) bool { competition := s.GetCompetition(competitionID) if competition.CompetitionName == "" { return false @@ -59,3 +80,25 @@ func (s *Session) RemovePlayerFromCompetition(competitionID uint8, player Player return competition.RemovePlayer(player) } + +func (s *Session) GetAllPlayersFromCompetition(competitionID uint8) []*Player { + competition := s.GetCompetition(competitionID) + if competition.CompetitionName == "" { + return []*Player{} + } + + players := []*Player{} + for _, player := range competition.CompetitionPlayers { + players = append(players, player) + } + return players +} + +func (s *Session) UpdateCompetitionPlayer(competitionID uint8, player *Player) bool { + competition := s.GetCompetition(competitionID) + if competition.CompetitionName == "" { + return false + } + + return competition.UpdatePlayer(player) +} diff --git a/astro/services/Stage.go b/astro/services/Stage.go index a222597..1360124 100644 --- a/astro/services/Stage.go +++ b/astro/services/Stage.go @@ -6,4 +6,5 @@ type Stage interface { PlayerPosition(player Player) uint16 AddPlayer(player Player) bool RemovePlayer(player Player) bool + GetID() uint8 } diff --git a/frontend/index.html b/frontend/index.html index 4a3d896..11475b3 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,14 +1,17 @@ <!DOCTYPE html> <html lang="en"> - <head> - <meta charset="UTF-8" /> - <link rel="icon" type="image/svg+xml" href="/wails.png" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <link rel="stylesheet" href="/style.css" /> - <title>AstroProject</title> - </head> - <body> - <div id="app"></div> - <script type="module" src="/src/main.ts"></script> - </body> -</html> + +<head> + <meta charset="UTF-8" /> + <link rel="icon" type="image/svg+xml" href="/wails.png" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <link rel="stylesheet" href="/style.css" /> + <title>AstroProject</title> +</head> + +<body> + <div id="app"></div> + <script type="module" src="/src/main.ts"></script> +</body> + +</html> \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c9ab675..6fecb76 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "frontend", "version": "0.0.0", + "dependencies": { + "sweetalert": "^2.1.2" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.1", "@tsconfig/svelte": "^5.0.2", @@ -981,6 +984,12 @@ "node": ">=8" } }, + "node_modules/es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", + "license": "MIT" + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", @@ -1415,6 +1424,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/promise-polyfill": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", + "integrity": "sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ==", + "license": "MIT" + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1666,6 +1681,16 @@ } } }, + "node_modules/sweetalert": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz", + "integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==", + "license": "MIT", + "dependencies": { + "es6-object-assign": "^1.1.0", + "promise-polyfill": "^6.0.2" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 231af17..0122387 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,11 +12,14 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.1", "@tsconfig/svelte": "^5.0.2", + "@wailsio/runtime": "latest", "svelte": "^4.2.8", "svelte-check": "^3.6.2", "tslib": "^2.6.2", "typescript": "^5.2.2", - "vite": "^5.0.8", - "@wailsio/runtime": "latest" + "vite": "^5.0.8" + }, + "dependencies": { + "sweetalert": "^2.1.2" } -} \ No newline at end of file +} diff --git a/frontend/public/style.css b/frontend/public/style.css index 4ef5666..7a1be50 100644 --- a/frontend/public/style.css +++ b/frontend/public/style.css @@ -1,7 +1,7 @@ :root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", - "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; font-size: 16px; line-height: 24px; font-weight: 400; @@ -26,8 +26,7 @@ font-family: "Inter"; font-style: normal; font-weight: 400; - src: local(""), - url("./Inter-Medium.ttf") format("truetype"); + src: local(""), url("./Inter-Medium.ttf") format("truetype"); } h3 { @@ -45,17 +44,6 @@ a:hover { color: #535bf2; } -button { - width: 60px; - height: 30px; - line-height: 30px; - border-radius: 3px; - border: none; - margin: 0 0 0 20px; - padding: 0 8px; - cursor: pointer; -} - .result { height: 20px; line-height: 20px; @@ -63,60 +51,14 @@ button { body { margin: 0; - display: flex; - place-items: center; - place-content: center; - min-width: 320px; min-height: 100vh; } -.container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} - h1 { font-size: 3.2em; line-height: 1.1; } -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; -} - -.logo:hover { - filter: drop-shadow(0 0 2em #e80000aa); -} - -.logo.vanilla:hover { - filter: drop-shadow(0 0 2em #f7df1eaa); -} - -.result { - height: 20px; - line-height: 20px; - margin: 1.5rem auto; - text-align: center; -} - -.footer { - margin-top: 1rem; - align-content: center; - text-align: center; - color: rgba(255, 255, 255, 0.67); -} - @media (prefers-color-scheme: light) { :root { color: #213547; @@ -132,7 +74,6 @@ h1 { } } - .input-box .btn:hover { background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); color: #333333; @@ -158,4 +99,4 @@ h1 { .input-box .input:focus { border: none; background-color: rgba(255, 255, 255, 1); -} \ No newline at end of file +} diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 634fb3f..9e86756 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -1,24 +1,25 @@ <script lang="ts"> - import { Competition } from "../bindings/changeme/astro/services/models"; + import { onMount } from "svelte"; + + import NavBar from "./components/NavBar.svelte"; + import Registrations from "./components/Registrations.svelte"; import * as Session from "../bindings/changeme/astro/services/session"; + import { Competition } from "../bindings/changeme/astro/services/models"; let competitions: Competition[] = []; - function getCompetitions() { - Session.GetCompetitions().then((data) => { - competitions = data; - }); - } + onMount(async () => { + competitions = await Session.GetCompetitions(); + }); </script> <div class="container"> - <h1>Competitions</h1> - <button on:click={getCompetitions}>Get</button> - <ul> - {#each competitions as competition} - <li>{competition.CompetitionName}</li> - {/each} - </ul> + <NavBar /> + {#if competitions.length === 0} + <p>Loading...</p> + {:else} + <Registrations competition={competitions[0]} /> + {/if} </div> <style> diff --git a/frontend/src/components/NavBar.svelte b/frontend/src/components/NavBar.svelte new file mode 100644 index 0000000..84c48c7 --- /dev/null +++ b/frontend/src/components/NavBar.svelte @@ -0,0 +1,94 @@ +<script lang="ts"> + import { Competition } from "../../bindings/changeme/astro/services/models"; + import { randomColor, rightBrighness } from "../Util"; + import { + GetCompetitions, + AddCompetition, + RemoveCompetition, + } from "../../bindings/changeme/astro/services/session"; + import { onMount } from "svelte"; + + let competitions: Competition[] = []; + + async function loadCompetitions() { + competitions = await GetCompetitions(); + } + + onMount(loadCompetitions); +</script> + +<div class="nav-bar"> + <div class="competition-container"> + {#each competitions as competition} + <div + class="competition-el" + style="background-color: {randomColor(rightBrighness)};" + > + <span>{competition.CompetitionName}</span> + <button + on:click={async () => { + await RemoveCompetition(competition.CompetitionID); + loadCompetitions(); + }}>X</button + > + </div> + {/each} + </div> + <div class="competition-modifier"> + <button + on:click={async () => { + const newCompetition = await AddCompetition( + "Nouvelle compet", + "U20", + "Foil" + ); + loadCompetitions(); + }}>Add competition</button + > + </div> +</div> + +<style> + .nav-bar { + padding: 50px 10px 25px; + display: grid; + /* 70% for competitions, 30% for button */ + grid-template-columns: 70% 30%; + gap: 10px; + border-bottom: solid #003566 3px; + } + + .competition-container { + display: grid; + overflow-x: scroll; + grid-auto-flow: column; + gap: 10px; + } + + .competition-modifier { + display: flex; + justify-content: center; + align-items: center; + } + + button { + padding: 10px; + border: none; + border-radius: 5px; + background-color: #003566; + color: white; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + } + + .competition-el { + min-width: 20vw; + display: flex; + justify-content: space-between; + padding: 10px; + border: 1px solid #ccc; + border-radius: 5px; + } +</style> diff --git a/frontend/src/components/Registrations.svelte b/frontend/src/components/Registrations.svelte new file mode 100644 index 0000000..6e53d03 --- /dev/null +++ b/frontend/src/components/Registrations.svelte @@ -0,0 +1,268 @@ +<script lang="ts"> + import { onMount } from "svelte"; + import * as Models from "../../bindings/changeme/astro/services/models"; + import * as Session from "../../bindings/changeme/astro/services/session"; + import swal from "sweetalert"; + + export let competition: Models.Competition; + + let players: (Models.Player | null)[] = []; + let filteredPlayers: (Models.Player | null)[] = []; + + async function loadPlayers() { + Session.GetAllPlayersFromCompetition(competition.CompetitionID).then( + (result) => { + players = result; + } + ); + } + + onMount(async () => { + await loadPlayers(); + }); + + function getPlayerValueByKey(player: Models.Player | null, key: string) { + if (player === null) { + return ""; + } + + switch (key) { + case "PlayerInitialRank": + return player.PlayerInitialRank; + case "PlayerFirstname": + return player.PlayerFirstname; + case "PlayerLastname": + return player.PlayerLastname; + case "PlayerClub": + return player.PlayerClub; + default: + return ""; + } + } + + let sortBy = { key: "PlayerInitialRank", asc: true }; + + $: players = players.sort((a, b) => { + let aValue = getPlayerValueByKey(a, sortBy.key); + let bValue = getPlayerValueByKey(b, sortBy.key); + if (aValue === null || bValue === null) { + return 0; + } + if (aValue < bValue) { + return sortBy.asc ? -1 : 1; + } + if (aValue > bValue) { + return sortBy.asc ? 1 : -1; + } + return 0; + }); + + let searchTerms = ""; + + $: filteredPlayers = players.filter((player) => { + if (player === null) { + return []; + } + + return ( + player.PlayerFirstname.toLowerCase().includes( + searchTerms.toLowerCase() + ) || + player.PlayerLastname.toLowerCase().includes( + searchTerms.toLowerCase() + ) + ); + }); +</script> + +<div class="registration-container"> + <input + type="text" + bind:value={searchTerms} + placeholder="Search for a player" + /> + <table> + <thead> + <tr> + <th + on:click={() => { + sortBy = { key: "PlayerInitialRank", asc: !sortBy.asc }; + }}>Initial Rank</th + > + <th + on:click={() => { + sortBy = { key: "PlayerFirstname", asc: !sortBy.asc }; + }}>Firstname</th + > + <th + on:click={() => { + sortBy = { key: "PlayerLastname", asc: !sortBy.asc }; + }}>Lastname</th + > + <th + on:click={() => { + sortBy = { key: "PlayerClub", asc: !sortBy.asc }; + }}>Club</th + > + </tr> + </thead> + <tbody> + {#each filteredPlayers as player} + {#if player != null} + <tr> + <td + on:dblclick={async () => { + let newRank = await swal({ + content: { + element: "input", + attributes: { + placeholder: "New rank", + type: "number", + }, + }, + buttons: { + cancel: true, + confirm: true, + }, + }); + + if (newRank) { + player.PlayerInitialRank = + parseInt(newRank); + await Session.UpdateCompetitionPlayer( + competition.CompetitionID, + player + ).then(() => { + loadPlayers(); + }); + } + }}>{player.PlayerInitialRank}</td + > + <td + on:dblclick={async () => { + let newFirstname = await swal({ + content: { + element: "input", + attributes: { + placeholder: "New firstname", + }, + }, + buttons: { + cancel: true, + confirm: true, + }, + }); + + if (newFirstname) { + player.PlayerFirstname = newFirstname; + await Session.UpdateCompetitionPlayer( + competition.CompetitionID, + player + ).then(() => { + loadPlayers(); + }); + } + }}>{player.PlayerFirstname}</td + > + <td + on:dblclick={async () => { + let newLastname = await swal({ + content: { + element: "input", + attributes: { + placeholder: "New lastname", + }, + }, + buttons: { + cancel: true, + confirm: true, + }, + }); + + if (newLastname) { + player.PlayerLastname = newLastname; + await Session.UpdateCompetitionPlayer( + competition.CompetitionID, + player + ).then(() => { + loadPlayers(); + }); + } + }}>{player.PlayerLastname}</td + > + <td + >{#if player.PlayerClub}{player.PlayerClub}{/if}</td + > + </tr> + {/if} + {/each} + <tr id="add-player-tr"> + <td colspan="4"> + <button + on:click={async () => { + var player = Models.Player.createFrom({ + PlayerID: 65535, + PlayerFirstname: "Firstname", + PlayerLastname: "Lastname", + PlayerNationID: 0, + PlayerClubID: 0, + PlayerRegionID: 0, + PlayerInitialRank: 2, + }); + await Session.AddPlayerToCompetition( + competition.CompetitionID, + player + ).then(() => { + loadPlayers(); + }); + }} + > + Add Player + </button></td + > + </tr> + </tbody> + </table> +</div> + +<style> + .registration-container { + margin-top: 5vh; + display: flex; + flex-direction: column; + align-items: center; + } + + input { + width: 200px; + margin-bottom: 10px; + padding: 10px; + font-size: 1em; + border-radius: 10px; + border: solid 1px #003566; + } + + table { + width: 90%; + border-collapse: collapse; + } + + th, + td { + padding: 8px; + text-align: left; + } + + td { + border-bottom: 1px solid #e9ecef; + } + + #add-player-tr td { + border: none; + } + + th { + background-color: #f8f9fa; + cursor: pointer; + } +</style> diff --git a/main.go b/main.go index 845d444..6cc102e 100644 --- a/main.go +++ b/main.go @@ -14,7 +14,11 @@ var assets embed.FS func main() { session := services.Session{} - session.AddCompetition("Competition 1", "Category 1", "Weapon 1") + session.AddCompetition("Premier League", "U17", "Foil") + session.AddCompetition("Premier League", "U17", "Foil") + session.AddCompetition("Premier League", "U17", "Foil") + session.AddCompetition("Premier League", "U17", "Foil") + session.Competitions[0].AddPlayer(services.CreatePlayer(1, "John", "Doe")) app := application.New(application.Options{ Name: "AstroProject", @@ -24,6 +28,7 @@ func main() { application.NewService(&services.Competition{}), application.NewService(&services.Club{}), application.NewService(&services.Pool{}), + application.NewService(&services.Player{}), }, Assets: application.AssetOptions{ Handler: application.AssetFileServerFS(assets), @@ -42,7 +47,7 @@ func main() { }, BackgroundColour: application.NewRGB(27, 38, 54), URL: "/", - Width: 500, + Width: 1080, Height: 720, Centered: false, }) -- GitLab