generated from schreifuchs/wails-template
status after 3h & 30min
This commit is contained in:
parent
5f8842b140
commit
6cfea2e8dc
32
app.go
32
app.go
@ -38,10 +38,40 @@ func (a *App) GetTournaments() (ts []model.Tournament, err error) {
|
||||
}
|
||||
|
||||
func (a *App) GetTournament(id int) (t model.Tournament, err error) {
|
||||
err = a.db.Preload("Game").First(&t, id).Error
|
||||
err = a.db.Preload("Game").Preload("Participants").First(&t, id).Error
|
||||
return
|
||||
}
|
||||
func (a *App) SaveTournament(t model.Tournament) error {
|
||||
err := a.db.Save(&t).Error
|
||||
return err
|
||||
}
|
||||
func (a *App) FillRandom(t model.Tournament) {
|
||||
for range t.Size - len(t.Participants) {
|
||||
t.Participants = append(t.Participants, &model.Participant{
|
||||
Name: model.RandomName(),
|
||||
IsTemporary: true,
|
||||
IsTeam: true,
|
||||
})
|
||||
}
|
||||
a.db.Save(&t.Participants)
|
||||
a.db.Save(&t)
|
||||
|
||||
}
|
||||
|
||||
func (a *App) GetParticipants() (ps []model.Participant, err error) {
|
||||
err = a.db.Find(&ps).Error
|
||||
return
|
||||
}
|
||||
func (a *App) SaveParticipant(p model.Participant) error {
|
||||
return a.db.Save(&p).Error
|
||||
}
|
||||
func (a *App) DeleteParticipat(p model.Participant) {
|
||||
a.db.Delete(&p)
|
||||
}
|
||||
func (a *App) RemoveParticipantFromTournament(p model.Participant, t model.Tournament) {
|
||||
if p.IsTemporary {
|
||||
a.db.Delete(&p)
|
||||
return
|
||||
}
|
||||
a.db.Model(&t).Association("Participants").Delete(&p)
|
||||
}
|
||||
|
@ -1,32 +1,26 @@
|
||||
<script lang="ts">
|
||||
import "./app.css";
|
||||
import { Navbar, NavBrand, DarkMode } from "flowbite-svelte";
|
||||
import { Router, Route, Link, navigate } from "svelte-routing";
|
||||
import { Navbar, NavBrand, DarkMode, Button } from "flowbite-svelte";
|
||||
import { Router, Route, Link } from "svelte-routing";
|
||||
import Home from "./routes/Home.svelte";
|
||||
import "./app.css";
|
||||
import Tournament from "./routes/Tournament.svelte";
|
||||
interface Props {
|
||||
url?: string;
|
||||
}
|
||||
|
||||
let { url = $bindable("") }: Props = $props();
|
||||
export let url = "";
|
||||
</script>
|
||||
|
||||
<main class="flex-col h-screen items-center bg-gray-50 dark:bg-gray-800">
|
||||
<Navbar>
|
||||
<NavBrand on:click={() => navigate("", { replace: true })}>
|
||||
<span>Tournamenter</span>
|
||||
</NavBrand>
|
||||
<DarkMode />
|
||||
</Navbar>
|
||||
<Router bind:url>
|
||||
<Navbar>
|
||||
<NavBrand>
|
||||
<Link to="/">Tournaments</Link>
|
||||
</NavBrand>
|
||||
<DarkMode />
|
||||
</Navbar>
|
||||
<div>
|
||||
<Route path="/"><Home /></Route>
|
||||
<Route path="/tournament/:id"
|
||||
>{#snippet children({ params })}
|
||||
<Tournament id={params.id} /> {/snippet}
|
||||
</Route
|
||||
>
|
||||
<Route path="/tournament/:id" let:params>
|
||||
<Tournament id={parseInt(params.id)} />
|
||||
</Route>
|
||||
</div>
|
||||
</Router>
|
||||
</main>
|
||||
|
@ -32,6 +32,7 @@
|
||||
<TableHeadCell>Title</TableHeadCell>
|
||||
<TableHeadCell>Game</TableHeadCell>
|
||||
<TableHeadCell>Winner</TableHeadCell>
|
||||
<TableHeadCell></TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{#each thingsList as t}
|
||||
@ -47,7 +48,9 @@
|
||||
</TableBodyCell>
|
||||
|
||||
<TableBodyCell>
|
||||
<Link to={`/tournament/${t.ID}`}>Edit</Link>
|
||||
<Link class="text-primary-500 underline" to={`/tournament/${t.ID}`}
|
||||
>Edit</Link
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
|
27
frontend/src/routes/Matches.svelte
Normal file
27
frontend/src/routes/Matches.svelte
Normal file
@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { GetTournament, SaveTournament } from "../../wailsjs/go/main/App";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import { Button } from "flowbite-svelte";
|
||||
|
||||
let { tournamentID }: { tournamentID: number } = $props();
|
||||
|
||||
let tournament: model.Tournament = $state(new model.Tournament());
|
||||
function update() {
|
||||
GetTournament(tournamentID).then((t) => {
|
||||
console.log(t);
|
||||
tournament = t;
|
||||
});
|
||||
}
|
||||
$effect(update);
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
{#if tournament.TournamentState == 0}
|
||||
<Button
|
||||
onclick={() => {
|
||||
tournament.TournamentState++;
|
||||
SaveTournament(tournament).then(update);
|
||||
}}>Start</Button
|
||||
>
|
||||
{:else}{/if}
|
131
frontend/src/routes/Participants.svelte
Normal file
131
frontend/src/routes/Participants.svelte
Normal file
@ -0,0 +1,131 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Heading,
|
||||
Input,
|
||||
Label,
|
||||
Modal,
|
||||
Radio,
|
||||
Table,
|
||||
TableBody,
|
||||
TableBodyCell,
|
||||
TableBodyRow,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import {
|
||||
GetParticipants,
|
||||
GetTournament,
|
||||
RemoveParticipantFromTournament,
|
||||
SaveParticipant,
|
||||
DeleteParticipat,
|
||||
SaveTournament,
|
||||
FillRandom,
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let { tournamentID }: { tournamentID: number } = $props();
|
||||
|
||||
let participants: model.Participant[] = $state([]);
|
||||
let newOpen: boolean = $state(false);
|
||||
let participant: model.Participant = $state(
|
||||
new model.Participant({ IsTeam: false }),
|
||||
);
|
||||
let tournament: model.Tournament = $state();
|
||||
|
||||
function update() {
|
||||
GetParticipants().then((ps) => (participants = ps));
|
||||
if (tournamentID) {
|
||||
GetTournament(tournamentID).then((t) => {
|
||||
console.log(t);
|
||||
tournament = t;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function saveNewPart(e: Event) {
|
||||
e.preventDefault();
|
||||
SaveParticipant(participant).then(update);
|
||||
newOpen = false;
|
||||
}
|
||||
$effect(update);
|
||||
onMount(() => setTimeout(update, 0));
|
||||
</script>
|
||||
|
||||
{#if tournament}
|
||||
<section class="grid grid-cols-2 gap-5 p-5 text-center text-2xl text-white">
|
||||
<p>{tournament.Participants.length}</p>
|
||||
<p>{tournament.Size}</p>
|
||||
<p>Participants</p>
|
||||
<p>Max Participants</p>
|
||||
</section>
|
||||
{/if}
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableHeadCell>Name</TableHeadCell>
|
||||
<TableHeadCell />
|
||||
<TableHeadCell />
|
||||
<TableHeadCell />
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{#each participants as p}
|
||||
<TableBodyRow>
|
||||
<TableBodyCell>
|
||||
{p.Name}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
{#if tournament.Participants.find((pa) => pa.ID == p.ID)}
|
||||
<Button
|
||||
onclick={() => {
|
||||
RemoveParticipantFromTournament(p, tournament).then(update);
|
||||
}}>Remove</Button
|
||||
>
|
||||
{:else}
|
||||
<Button
|
||||
disabled={tournament.Participants.length >= tournament.Size}
|
||||
onclick={() => {
|
||||
tournament.Participants.push(p);
|
||||
SaveTournament(tournament).then(update);
|
||||
}}>Add</Button
|
||||
>
|
||||
{/if}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell>
|
||||
<Button onclick={() => DeleteParticipat(p).then(update)}
|
||||
>Delete</Button
|
||||
>
|
||||
</TableBodyCell>
|
||||
</TableBodyRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div class="grid p-5 gap-5 grid-cols-2">
|
||||
<Button onclick={() => (newOpen = true)}>+ Participant</Button>
|
||||
<Button onclick={() => FillRandom(tournament).then(update)}
|
||||
>Fill Random</Button
|
||||
>
|
||||
</div>
|
||||
<Modal bind:open={newOpen}>
|
||||
<form onsubmit={saveNewPart}>
|
||||
<Heading tag="h3">New Participant</Heading>
|
||||
<div class="m-5">
|
||||
<Label>Name</Label>
|
||||
<Input type="text" required bind:value={participant.Name} />
|
||||
</div>
|
||||
<div class="m-5 grid grid-cols-3">
|
||||
<Label>Type:</Label>
|
||||
<Radio required value={false} bind:group={participant.IsTeam}
|
||||
>Single Player</Radio
|
||||
>
|
||||
<Radio required value={true} bind:group={participant.IsTeam}>Team</Radio>
|
||||
</div>
|
||||
<div class=" m-5 grid grid-cols-3">
|
||||
<Label>Teporary:</Label>
|
||||
<Checkbox bind:value={participant.IsTemporary} />
|
||||
</div>
|
||||
|
||||
<Button class="m-5" type="submit">Save</Button>
|
||||
</form>
|
||||
</Modal>
|
@ -1,10 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
import { run } from "svelte/legacy";
|
||||
|
||||
import { Link } from "svelte-routing";
|
||||
import { Link, navigate } from "svelte-routing";
|
||||
import { GetTournament } from "../../wailsjs/go/main/App";
|
||||
import { model } from "../../wailsjs/go/models";
|
||||
import { onMount } from "svelte";
|
||||
import { Button, Heading, TabItem, Tabs } from "flowbite-svelte";
|
||||
import Participants from "./Participants.svelte";
|
||||
import Matches from "./Matches.svelte";
|
||||
|
||||
interface Props {
|
||||
id?: number | null;
|
||||
@ -26,9 +29,18 @@
|
||||
onMount(update);
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Link to="/" replace="true">Home</Link>
|
||||
</div>
|
||||
<div></div>
|
||||
{#if tournament}
|
||||
{tournament.Title}
|
||||
<section class="grid grid-cols-2 p-5">
|
||||
<Heading>{tournament.Title}</Heading>
|
||||
<Button on:click={() => navigate("/", { replace: true })}>Export</Button>
|
||||
</section>
|
||||
<Tabs>
|
||||
<TabItem open title="Participants">
|
||||
<Participants tournamentID={tournament.ID} />
|
||||
</TabItem>
|
||||
<TabItem title="Matches">
|
||||
<Matches tournamentID={tournament.ID} />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
{/if}
|
||||
|
@ -0,0 +1,10 @@
|
||||
// vite.config.ts
|
||||
import { defineConfig } from "file:///home/schreifuchs/go/src/git.schreifuchs.ch/schreifuchs/regio-ue1/frontend/node_modules/.pnpm/vite@5.4.14_sass@1.83.4/node_modules/vite/dist/node/index.js";
|
||||
import { svelte } from "file:///home/schreifuchs/go/src/git.schreifuchs.ch/schreifuchs/regio-ue1/frontend/node_modules/.pnpm/@sveltejs+vite-plugin-svelte@4.0.4_svelte@5.19.9_vite@5.4.14_sass@1.83.4_/node_modules/@sveltejs/vite-plugin-svelte/src/index.js";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [svelte()]
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS9zY2hyZWlmdWNocy9nby9zcmMvZ2l0LnNjaHJlaWZ1Y2hzLmNoL3NjaHJlaWZ1Y2hzL3JlZ2lvLXVlMS9mcm9udGVuZFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL2hvbWUvc2NocmVpZnVjaHMvZ28vc3JjL2dpdC5zY2hyZWlmdWNocy5jaC9zY2hyZWlmdWNocy9yZWdpby11ZTEvZnJvbnRlbmQvdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL2hvbWUvc2NocmVpZnVjaHMvZ28vc3JjL2dpdC5zY2hyZWlmdWNocy5jaC9zY2hyZWlmdWNocy9yZWdpby11ZTEvZnJvbnRlbmQvdml0ZS5jb25maWcudHNcIjtpbXBvcnQge2RlZmluZUNvbmZpZ30gZnJvbSAndml0ZSdcbmltcG9ydCB7c3ZlbHRlfSBmcm9tICdAc3ZlbHRlanMvdml0ZS1wbHVnaW4tc3ZlbHRlJ1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW3N2ZWx0ZSgpXVxufSlcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBZ1osU0FBUSxvQkFBbUI7QUFDM2EsU0FBUSxjQUFhO0FBR3JCLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxPQUFPLENBQUM7QUFDcEIsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
10
frontend/wailsjs/go/main/App.d.ts
vendored
10
frontend/wailsjs/go/main/App.d.ts
vendored
@ -2,10 +2,20 @@
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {model} from '../models';
|
||||
|
||||
export function DeleteParticipat(arg1:model.Participant):Promise<void>;
|
||||
|
||||
export function FillRandom(arg1:model.Tournament):Promise<void>;
|
||||
|
||||
export function GetGames():Promise<Array<model.Game>>;
|
||||
|
||||
export function GetParticipants():Promise<Array<model.Participant>>;
|
||||
|
||||
export function GetTournament(arg1:number):Promise<model.Tournament>;
|
||||
|
||||
export function GetTournaments():Promise<Array<model.Tournament>>;
|
||||
|
||||
export function RemoveParticipantFromTournament(arg1:model.Participant,arg2:model.Tournament):Promise<void>;
|
||||
|
||||
export function SaveParticipant(arg1:model.Participant):Promise<void>;
|
||||
|
||||
export function SaveTournament(arg1:model.Tournament):Promise<void>;
|
||||
|
@ -2,10 +2,22 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function DeleteParticipat(arg1) {
|
||||
return window['go']['main']['App']['DeleteParticipat'](arg1);
|
||||
}
|
||||
|
||||
export function FillRandom(arg1) {
|
||||
return window['go']['main']['App']['FillRandom'](arg1);
|
||||
}
|
||||
|
||||
export function GetGames() {
|
||||
return window['go']['main']['App']['GetGames']();
|
||||
}
|
||||
|
||||
export function GetParticipants() {
|
||||
return window['go']['main']['App']['GetParticipants']();
|
||||
}
|
||||
|
||||
export function GetTournament(arg1) {
|
||||
return window['go']['main']['App']['GetTournament'](arg1);
|
||||
}
|
||||
@ -14,6 +26,14 @@ export function GetTournaments() {
|
||||
return window['go']['main']['App']['GetTournaments']();
|
||||
}
|
||||
|
||||
export function RemoveParticipantFromTournament(arg1, arg2) {
|
||||
return window['go']['main']['App']['RemoveParticipantFromTournament'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function SaveParticipant(arg1) {
|
||||
return window['go']['main']['App']['SaveParticipant'](arg1);
|
||||
}
|
||||
|
||||
export function SaveTournament(arg1) {
|
||||
return window['go']['main']['App']['SaveTournament'](arg1);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export namespace model {
|
||||
Title: string;
|
||||
GameID: number;
|
||||
Game: Game;
|
||||
Size?: number;
|
||||
Size: number;
|
||||
TournamentState: number;
|
||||
WinnierParticipantID: number;
|
||||
WinnierParticipant: Participant;
|
||||
@ -105,7 +105,7 @@ export namespace model {
|
||||
// Go type: gorm
|
||||
DeletedAt: any;
|
||||
Name: string;
|
||||
IsTemporary: boolean;
|
||||
Size?: boolean;
|
||||
IsTeam: boolean;
|
||||
Tournaments: Tournament[];
|
||||
|
||||
@ -120,7 +120,7 @@ export namespace model {
|
||||
this.UpdatedAt = this.convertValues(source["UpdatedAt"], null);
|
||||
this.DeletedAt = this.convertValues(source["DeletedAt"], null);
|
||||
this.Name = source["Name"];
|
||||
this.IsTemporary = source["IsTemporary"];
|
||||
this.Size = source["Size"];
|
||||
this.IsTeam = source["IsTeam"];
|
||||
this.Tournaments = this.convertValues(source["Tournaments"], Tournament);
|
||||
}
|
||||
|
@ -12,19 +12,18 @@ type Game struct {
|
||||
type Participant struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
IsTemporary bool // only for one tournament
|
||||
IsTemporary bool `json:"Size,string,omitempty"` // only for one tournament
|
||||
IsTeam bool
|
||||
Tournaments []*Tournament `gorm:"many2many:partcipant_tournaments;"`
|
||||
}
|
||||
|
||||
type Tournament struct {
|
||||
gorm.Model
|
||||
Title string
|
||||
GameID int
|
||||
Game Game `gorm:"foreignKey:GameID"`
|
||||
Size int `json:"Size,string,omitempty"` // number of prarticipants
|
||||
TournamentState int
|
||||
|
||||
Title string
|
||||
GameID int
|
||||
Game Game `gorm:"foreignKey:GameID"`
|
||||
Size int // number of prarticipants
|
||||
TournamentState int
|
||||
WinnierParticipantID int
|
||||
WinnierParticipant Participant `gorm:"foreignKey:WinnierParticipantID"`
|
||||
Participants []*Participant `gorm:"many2many:partcipant_tournaments;"`
|
||||
|
65
model/names.go
Normal file
65
model/names.go
Normal file
@ -0,0 +1,65 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var funnyNames = []string{
|
||||
"Captain Quirk",
|
||||
"Giggle Muffin",
|
||||
"Bubbles McFarty",
|
||||
"Dapper Dingle",
|
||||
"Wacky McWiggles",
|
||||
"Sir Laughs-a-Lot",
|
||||
"Chuckles the Chipmunk",
|
||||
"Fuzzy Pickles",
|
||||
"Snickerdoodle Sprout",
|
||||
"Zany Zucchini",
|
||||
"Professor Pudding",
|
||||
"Bumbling Bumblebee",
|
||||
"Cheeky Monkey",
|
||||
"Silly Sausage",
|
||||
"Wobble Bottom",
|
||||
"Grinning Goblin",
|
||||
"Fluffy Fiasco",
|
||||
"Tickle Tortilla",
|
||||
"Jolly Jester",
|
||||
"Merry Marmalade",
|
||||
"Wacky Wonka",
|
||||
"Noodle Nugget",
|
||||
"Bubblegum Bandit",
|
||||
"Funky Ferret",
|
||||
"Giggle Gopher",
|
||||
"Happy Hiccup",
|
||||
"Nifty Noodle",
|
||||
"Dizzy Donut",
|
||||
"Bouncy Biscuit",
|
||||
"Frolic Fox",
|
||||
"Whimsical Wombat",
|
||||
"Peppy Pumpernickel",
|
||||
"Loco Lobster",
|
||||
"Sassy Sasquatch",
|
||||
"Rambunctious Radish",
|
||||
"Prankster Panda",
|
||||
"Zippy Zebra",
|
||||
"Giggling Giraffe",
|
||||
"Funky Flamingo",
|
||||
"Silly Sphinx",
|
||||
"Guffawing Gopher",
|
||||
"Cheerful Cucumber",
|
||||
"Hapless Hedgehog",
|
||||
"Jovial Jalapeño",
|
||||
"Bubbly Banana",
|
||||
"Quirky Quokka",
|
||||
"Dandy Dodo",
|
||||
"Laughing Llama",
|
||||
"Zany Zephyr",
|
||||
}
|
||||
|
||||
func RandomName() string {
|
||||
x := big.NewInt(int64(len(funnyNames) - 1))
|
||||
i, _ := rand.Int(rand.Reader, x)
|
||||
|
||||
return funnyNames[i.Int64()]
|
||||
}
|
BIN
tournament.db
BIN
tournament.db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user