Compare commits

..

No commits in common. "8b5bb787641bdbf13e3692ea383ce3f5002984d6" and "57cf5e617a2ae3b68a72bf3eed229bb542f1cb84" have entirely different histories.

27 changed files with 681 additions and 1477 deletions

114
app.go
View File

@ -3,25 +3,16 @@ package main
import (
"context"
"fmt"
"gegio-ue1/model"
"os"
"slices"
"github.com/wailsapp/wails/v2/pkg/runtime"
"gorm.io/gorm"
)
// App struct
type App struct {
ctx context.Context
db *gorm.DB
}
// NewApp creates a new App application struct
func NewApp(db *gorm.DB) *App {
return &App{
db: db,
}
func NewApp() *App {
return &App{}
}
// startup is called when the app starts. The context is saved
@ -30,102 +21,7 @@ func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
func (a *App) GetGames() (gs []model.Game, err error) {
err = a.db.Find(&gs).Error
return
}
func (a *App) GetTournaments() (ts []model.Tournament, err error) {
err = a.db.Preload("Game").Find(&ts).Error
return
}
func (a *App) GetTournament(id int) (t model.Tournament, err error) {
err = a.db.Preload("Game").Preload("Participants").Preload("Matches").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) StartTournament(t model.Tournament) {
t.TournamentState = 1
a.SaveTournament(t)
t, _ = a.GetTournament(int(t.ID))
matches := make([]model.Match, 0, len(t.Participants)/2)
for i := range len(t.Participants) / 2 {
matches = append(matches, model.Match{
TournamentID: t.ID,
Stage: 1,
Order: i,
Participant1ID: t.Participants[i].ID,
Participant2ID: t.Participants[i+len(t.Participants)/2].ID,
})
}
if len(t.Participants)%2 != 0 {
matches = append(matches, model.Match{
TournamentID: t.ID,
Stage: 1,
Order: len(t.Participants)/2 + 1,
Participant1ID: t.Participants[len(t.Participants)-1].ID,
Participant2ID: t.Participants[len(t.Participants)-1].ID,
})
}
a.db.Save(matches)
}
func (a *App) ExportTournament(t model.Tournament) {
dirname, _ := os.UserHomeDir()
str, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{DefaultDirectory: dirname, DefaultFilename: "tournament.csv"})
if err != nil {
fmt.Println(err)
}
println(str)
}
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)
}
func (a *App) GetMatches(tID uint) [][]model.Match {
matches := make([][]model.Match, 0)
for {
ms := make([]model.Match, 0)
if err := a.db.Where("tournament_id = ? AND stage = ?", tID, len(matches)).Find(&ms).Error; err != nil || len(ms) == 0 {
fmt.Println(ms)
fmt.Println(err)
return matches
}
slices.SortFunc(ms, func(a, b model.Match) int { return a.Order - b.Order })
matches = append(matches, ms)
}
// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name)
}

View File

@ -10,19 +10,19 @@
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"@tsconfig/svelte": "^3.0.0",
"autoprefixer": "^10.4.20",
"flowbite": "^3.1.1",
"flowbite-svelte": "^0.47.4",
"flowbite-svelte-icons": "^2.0.2",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"svelte-preprocess": "^6.0.0",
"svelte": "^3.49.0",
"svelte-check": "^2.8.0",
"svelte-preprocess": "^4.10.7",
"svelte-routing": "^2.13.0",
"tailwindcss": "^3.4.9",
"tslib": "^2.4.0",
"typescript": "^5.5.0",
"vite": "^5.4.4"
"typescript": "^4.6.4",
"vite": "^3.0.7"
}
}

View File

@ -1 +1 @@
6f760b83cd6ae4745bc9e5ebf4de97b2
a5a8c3695f34d6c9bafb2ee7f70bf99a

1146
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,22 @@
<script lang="ts">
import "./app.css";
import { Navbar, NavBrand, DarkMode, Button } from "flowbite-svelte";
import { Router, Route, Link } from "svelte-routing";
import { Navbar, NavBrand, DarkMode } from "flowbite-svelte";
import { Router, Route } from "svelte-routing";
import Home from "./routes/Home.svelte";
import "./app.css";
import Tournament from "./routes/Tournament.svelte";
export let url = "";
</script>
<main class="flex-col h-screen items-center bg-gray-50 dark:bg-gray-800">
<Router bind:url>
<Navbar>
<NavBrand>
<Link to="/">Tournaments</Link>
</NavBrand>
<DarkMode />
</Navbar>
<Navbar>
<NavBrand>
<span>Wails</span>
</NavBrand>
<DarkMode />
</Navbar>
<Router {url}>
<div>
<Route path="/"><Home /></Route>
<Route path="/tournament/:id" let:params>
<Tournament id={parseInt(params.id)} />
</Route>
</div>
</Router>
</main>

View File

@ -1,8 +1,7 @@
import './style.css'
import App from './App.svelte'
import { mount } from "svelte";
const app = mount(App, {
const app = new App({
target: document.getElementById('app')
})

View File

@ -1,8 +1,14 @@
<script lang="ts">
import { onMount } from "svelte";
import { GetTournaments } from "../../wailsjs/go/main/App";
import { model } from "../../wailsjs/go/models";
import {
GetThings,
DeleteThing,
NewThing,
} from "../../wailsjs/go/things/Service";
import { things } from "../../wailsjs/go/models";
import {
Label,
Input,
Button,
Table,
TableHead,
@ -10,61 +16,60 @@
TableBody,
TableBodyRow,
TableBodyCell,
Modal,
} from "flowbite-svelte";
import TourCreator from "./TourCreator.svelte";
import { Link } from "svelte-routing";
let thingsList: model.Tournament[] = $state([]);
let newThing: boolean = $state(false);
let name: string;
let thingsList: things.Thing[] = [];
function update() {
GetTournaments().then((ts) => {
GetThings().then((ts) => {
thingsList = ts;
});
}
function submit(e: Event) {
e.preventDefault();
NewThing(name).then(update);
name = "";
}
function deleteEvent(id: number) {
DeleteThing(id).then(update);
}
onMount(update);
</script>
<form class="max-w-96 m-5 grid-cols-1 gap-10" on:submit={submit}>
<div class="m-5">
<Label for="first_name" class="mb-2">First name</Label>
<Input type="text" placeholder="John" bind:value={name} required />
</div>
<div class="m-5">
<Button type="submit">Submit</Button>
</div>
</form>
<Table>
<TableHead>
<TableHeadCell>Title</TableHeadCell>
<TableHeadCell>Game</TableHeadCell>
<TableHeadCell>Winner</TableHeadCell>
<TableHeadCell></TableHeadCell>
<TableHeadCell>ID</TableHeadCell>
<TableHeadCell>Name</TableHeadCell>
<TableHeadCell>Delete</TableHeadCell>
</TableHead>
<TableBody>
{#each thingsList as t}
<TableBodyRow>
<TableBodyCell>
{t.Title}
</TableBodyCell>
<TableBodyCell>
{t.Game.Name}
</TableBodyCell>
<TableBodyCell>
{t.WinnierParticipant.Name}
{t.ID}
</TableBodyCell>
<TableBodyCell>
<Link class="text-primary-500 underline" to={`/tournament/${t.ID}`}
>Edit</Link
>
{t.Name}
</TableBodyCell>
<TableBodyCell>
<Button on:click={(_) => deleteEvent(t.ID)}>Delete</Button>
</TableBodyCell>
</TableBodyRow>
{/each}
</TableBody>
<div class="flex-row justify-evenly p-5">
<Button>View</Button>
<Button on:click={(_) => (newThing = true)}>New Tournament</Button>
</div>
<Modal bind:open={newThing}>
<TourCreator
onCreated={() => {
update();
newThing = false;
}}
/>
</Modal>
</Table>

View File

@ -1,39 +0,0 @@
<script lang="ts">
import { onMount } from "svelte";
import {
GetMatches,
GetTournament,
StartTournament,
} from "../../wailsjs/go/main/App";
import { model } from "../../wailsjs/go/models";
import { Button, TabItem, Tabs } from "flowbite-svelte";
let { tournamentID }: { tournamentID: number } = $props();
let tournament: model.Tournament = $state(new model.Tournament());
let matches: model.Match[][] = $state([]);
function update() {
GetTournament(tournamentID).then((t) => {
console.log(t);
tournament = t;
});
GetMatches(tournamentID).then((ms) => (matches = ms));
}
$effect(update);
onMount(update);
</script>
{#if tournament.TournamentState == 0}
<Button
onclick={() => {
StartTournament(tournament).then(update);
}}>Start</Button
>
{:else}
<Tabs>
{#each matches as ms, i}
<TabItem title={`Stage: ${i}`}></TabItem>
{/each}
</Tabs>
{/if}

View File

@ -1,131 +0,0 @@
<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>

View File

@ -1,48 +0,0 @@
<script lang="ts">
import { Button, Input, Label, Select } from "flowbite-svelte";
import { model } from "../../wailsjs/go/models";
import { GetGames, SaveTournament } from "../../wailsjs/go/main/App";
import { onMount } from "svelte";
let tournament = $state(new model.Tournament());
let games: model.Game[] = $state([]);
interface Props {
onCreated?: (t: model.Tournament) => void;
}
let { onCreated = (_) => {} }: Props = $props();
function submit(e: Event) {
e.preventDefault();
SaveTournament(tournament).then(() => {
onCreated(tournament);
});
}
onMount(() => {
GetGames().then((gs) => {
games = gs;
});
});
</script>
<form onsubmit={submit}>
<div>
<Label>Title</Label>
<Input type="text" bind:value={tournament.Title} />
</div>
<div>
e
<Label>Game</Label>
<Select
items={games.map((g) => {
return { value: g.ID, name: g.Name };
})}
bind:value={tournament.GameID}
/>
</div>
<div>
<Label>Size</Label>
<Input type="number" step="1" min="1" bind:value={tournament.Size} />
</div>
<Button type="submit">Save</Button>
</form>

View File

@ -1,41 +0,0 @@
<script lang="ts">
import { Link, navigate } from "svelte-routing";
import { GetTournament, ExportTournament } 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;
}
let { id = $bindable(null) }: Props = $props();
let tournament: model.Tournament = $state();
function update() {
GetTournament(id).then((t) => {
console.log(t);
tournament = t;
});
}
$effect(update);
onMount(update);
</script>
<div></div>
{#if tournament}
<section class="grid grid-cols-2 p-5">
<Heading>{tournament.Title}</Heading>
<Button on:click={() => ExportTournament(tournament)}>Export</Button>
</section>
<Tabs>
<TabItem open title="Participants">
<Participants tournamentID={tournament.ID} />
</TabItem>
<TabItem title="Matches">
<Matches tournamentID={tournament.ID} />
</TabItem>
</Tabs>
{/if}

View File

@ -1,5 +1,7 @@
import sveltePreprocess from 'svelte-preprocess'
export default {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: sveltePreprocess()
}

View File

@ -12,7 +12,6 @@
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"verbatimModuleSyntax": true,
"allowJs": true,
"checkJs": true,
"isolatedModules": true

View File

@ -1,10 +0,0 @@
// 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

View File

@ -1,27 +1,4 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {model} from '../models';
export function DeleteParticipat(arg1:model.Participant):Promise<void>;
export function ExportTournament(arg1:model.Tournament):Promise<void>;
export function FillRandom(arg1:model.Tournament):Promise<void>;
export function GetGames():Promise<Array<model.Game>>;
export function GetMatches(arg1:number):Promise<Array<any>>;
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>;
export function StartTournament(arg1:model.Tournament):Promise<void>;
export function Greet(arg1:string):Promise<string>;

View File

@ -2,50 +2,6 @@
// 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 ExportTournament(arg1) {
return window['go']['main']['App']['ExportTournament'](arg1);
}
export function FillRandom(arg1) {
return window['go']['main']['App']['FillRandom'](arg1);
}
export function GetGames() {
return window['go']['main']['App']['GetGames']();
}
export function GetMatches(arg1) {
return window['go']['main']['App']['GetMatches'](arg1);
}
export function GetParticipants() {
return window['go']['main']['App']['GetParticipants']();
}
export function GetTournament(arg1) {
return window['go']['main']['App']['GetTournament'](arg1);
}
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);
}
export function StartTournament(arg1) {
return window['go']['main']['App']['StartTournament'](arg1);
export function Greet(arg1) {
return window['go']['main']['App']['Greet'](arg1);
}

View File

@ -1,208 +1,19 @@
export namespace model {
export namespace things {
export class Game {
export class Thing {
ID: number;
// Go type: time
CreatedAt: any;
// Go type: time
UpdatedAt: any;
// Go type: gorm
DeletedAt: any;
Name: string;
static createFrom(source: any = {}) {
return new Game(source);
return new Thing(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
this.CreatedAt = this.convertValues(source["CreatedAt"], null);
this.UpdatedAt = this.convertValues(source["UpdatedAt"], null);
this.DeletedAt = this.convertValues(source["DeletedAt"], null);
this.Name = source["Name"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Tournament {
ID: number;
// Go type: time
CreatedAt: any;
// Go type: time
UpdatedAt: any;
// Go type: gorm
DeletedAt: any;
Title: string;
GameID: number;
Game: Game;
Size: number;
TournamentState: number;
WinnierParticipantID: number;
WinnierParticipant: Participant;
Participants: Participant[];
Matches: Match[];
static createFrom(source: any = {}) {
return new Tournament(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
this.CreatedAt = this.convertValues(source["CreatedAt"], null);
this.UpdatedAt = this.convertValues(source["UpdatedAt"], null);
this.DeletedAt = this.convertValues(source["DeletedAt"], null);
this.Title = source["Title"];
this.GameID = source["GameID"];
this.Game = this.convertValues(source["Game"], Game);
this.Size = source["Size"];
this.TournamentState = source["TournamentState"];
this.WinnierParticipantID = source["WinnierParticipantID"];
this.WinnierParticipant = this.convertValues(source["WinnierParticipant"], Participant);
this.Participants = this.convertValues(source["Participants"], Participant);
this.Matches = this.convertValues(source["Matches"], Match);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Participant {
ID: number;
// Go type: time
CreatedAt: any;
// Go type: time
UpdatedAt: any;
// Go type: gorm
DeletedAt: any;
Name: string;
Size?: boolean;
IsTeam: boolean;
Tournaments: Tournament[];
static createFrom(source: any = {}) {
return new Participant(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
this.CreatedAt = this.convertValues(source["CreatedAt"], null);
this.UpdatedAt = this.convertValues(source["UpdatedAt"], null);
this.DeletedAt = this.convertValues(source["DeletedAt"], null);
this.Name = source["Name"];
this.Size = source["Size"];
this.IsTeam = source["IsTeam"];
this.Tournaments = this.convertValues(source["Tournaments"], Tournament);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Match {
ID: number;
// Go type: time
CreatedAt: any;
// Go type: time
UpdatedAt: any;
// Go type: gorm
DeletedAt: any;
TournamentID: number;
Stage: number;
Order: number;
Participant1ID: number;
Participant1: Participant;
Participant2ID: number;
Participant2: Participant;
WinnierParticipantID: number;
WinnierParticipant: Participant;
static createFrom(source: any = {}) {
return new Match(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ID = source["ID"];
this.CreatedAt = this.convertValues(source["CreatedAt"], null);
this.UpdatedAt = this.convertValues(source["UpdatedAt"], null);
this.DeletedAt = this.convertValues(source["DeletedAt"], null);
this.TournamentID = source["TournamentID"];
this.Stage = source["Stage"];
this.Order = source["Order"];
this.Participant1ID = source["Participant1ID"];
this.Participant1 = this.convertValues(source["Participant1"], Participant);
this.Participant2ID = source["Participant2ID"];
this.Participant2 = this.convertValues(source["Participant2"], Participant);
this.WinnierParticipantID = source["WinnierParticipantID"];
this.WinnierParticipant = this.convertValues(source["WinnierParticipant"], Participant);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}

9
frontend/wailsjs/go/things/Service.d.ts vendored Executable file
View File

@ -0,0 +1,9 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {things} from '../models';
export function DeleteThing(arg1:number):Promise<void>;
export function GetThings():Promise<Array<things.Thing>>;
export function NewThing(arg1:string):Promise<void>;

View File

@ -0,0 +1,15 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export function DeleteThing(arg1) {
return window['go']['things']['Service']['DeleteThing'](arg1);
}
export function GetThings() {
return window['go']['things']['Service']['GetThings']();
}
export function NewThing(arg1) {
return window['go']['things']['Service']['NewThing'](arg1);
}

13
go.mod
View File

@ -1,12 +1,8 @@
module gegio-ue1
module wails-svelte-tailwind-ts
go 1.23
require (
github.com/wailsapp/wails/v2 v2.9.2
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.25.12
)
require github.com/wailsapp/wails/v2 v2.9.2
require (
github.com/bep/debounce v1.2.1 // indirect
@ -14,8 +10,6 @@ require (
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
@ -24,7 +18,6 @@ require (
github.com/leaanthony/u v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
@ -38,7 +31,7 @@ require (
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/text v0.15.0 // indirect
)
// replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/u80864958/go/pkg/mod

14
go.sum
View File

@ -11,10 +11,6 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
@ -39,8 +35,6 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -90,15 +84,11 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

View File

@ -2,7 +2,7 @@ package main
import (
"embed"
"gegio-ue1/model"
"wails-svelte-tailwind-ts/things"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
@ -14,8 +14,8 @@ var assets embed.FS
func main() {
// Create an instance of the app structure
db := model.InitDB()
app := NewApp(db)
app := NewApp()
things := things.NewThingsService()
// Create application with options
err := wails.Run(&options.App{
@ -29,6 +29,7 @@ func main() {
OnStartup: app.startup,
Bind: []interface{}{
app,
things,
},
})

View File

@ -1,36 +0,0 @@
package model
import (
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func InitDB() *gorm.DB {
db, err := gorm.Open(sqlite.Open("tournament.db"))
if err != nil {
log.Panic(err)
}
db.AutoMigrate(&Game{}, &Participant{}, &Tournament{}, &Match{})
db.Save(&Game{
Model: gorm.Model{
ID: 1,
},
Name: "CS:GO",
})
db.Save(&Game{
Model: gorm.Model{
ID: 2,
},
Name: "Overwatch",
})
db.Save(&Game{
Model: gorm.Model{
ID: 3,
},
Name: "Minecraft",
})
return db
}

View File

@ -1,44 +0,0 @@
package model
import (
"gorm.io/gorm"
)
type Game struct {
gorm.Model
Name string
}
type Participant struct {
gorm.Model
Name string
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 // number of prarticipants
TournamentState int
WinnierParticipantID int
WinnierParticipant Participant `gorm:"foreignKey:WinnierParticipantID"`
Participants []*Participant `gorm:"many2many:partcipant_tournaments;"`
Matches []Match
}
type Match struct {
gorm.Model
TournamentID uint
Stage int
Order int
Participant1ID uint
Participant1 Participant `gorm:"foreignKey:Participant1ID"`
Participant2ID uint
Participant2 Participant `gorm:"foreignKey:Participant2ID"`
WinnierParticipantID uint
WinnierParticipant Participant `gorm:"foreignKey:WinnierParticipantID"`
}

View File

@ -1,65 +0,0 @@
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()]
}

43
things/resource.go Normal file
View File

@ -0,0 +1,43 @@
package things
import "slices"
type Thing struct {
ID int
Name string
}
type Service struct {
things map[int]Thing
maxID int
}
func NewThingsService() *Service {
return &Service{
things: make(map[int]Thing),
}
}
func (s *Service) NewThing(name string) {
s.maxID++
s.things[s.maxID] = Thing{
Name: name,
ID: s.maxID,
}
print(name)
}
func (s *Service) GetThings() []Thing {
things := make([]Thing, 0, len(s.things))
for _, t := range s.things {
things = append(things, t)
}
slices.SortFunc(things, func(a, b Thing) int { return a.ID - b.ID })
return things
}
func (s *Service) DeleteThing(id int) {
delete(s.things, id)
}

Binary file not shown.