Refactor project structure and update configurations. Now first working version

- Updated `.air.conf` for Nix compatibility and simplified build commands.
- Enhanced `.gitignore` to include `tmp` directory.
- Improved `README.md` with clearer instructions and added language details.
- Refined CSS styles for better UI consistency and added alert styles.
- Upgraded `flake.nix` to use Go 1.24 and improved shell environment setup.
- Modified authentication logic in `auth.go` for better user handling.
- Updated `main.go` to dynamically set the listening port and improved logging.
- Added new `routes.go` file for handling game entry and history.
- Enhanced user models and added statistics tracking in `models.go`.
- Improved template rendering and added user feedback messages in HTML templates.
- Removed obsolete build error logs and binaries.
This commit is contained in:
Jonas Hahn
2025-08-24 12:08:14 +02:00
parent c9a3196ccb
commit 4b4377a24e
19 changed files with 376 additions and 278 deletions

View File

@@ -5,12 +5,14 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{block "title" .}}QRank{{end}}</title>
<title>QRank</title>
<!-- Also apple support -->
<link rel="icon" type="image/png" href="/assets/favicon.ico">
<link rel="apple-touch-icon" href="/assets/favicon.ico">
<link rel="shortcut icon" href="/assets/favicon.ico">
<!-- Only one stylesheet for now -->
<link rel="stylesheet" href="/assets/styles.css">
</head>
@@ -18,12 +20,14 @@
<div class="header">
<div class="container">
<div class="row" style="justify-content:space-between;align-items:center">
<div><strong><a href="/" style="text-decoration:none;color:#111">QRank</a></strong></div>
<div><strong><a href="/" style="text-decoration:none;color:#111">{{block "title" .}}QRank{{end}}</a></strong></div>
<!-- Navigation menu -->
<div class="nav">
{{if .CurrentUser}}
<a href="/enter">Enter scores</a>
<a href="/history">History</a>
<a href="/leaderboard">Leaderboard</a>
{{if .CurrentUser}}
<a href="/me">@{{.CurrentUser.Username}}</a>
{{else}}
<a href="/login">Log in</a>
@@ -33,6 +37,17 @@
</div>
</div>
<div class="container">
<!-- Information messages for the user -->
{{if .Error}}
<div class="alert alert-error">{{.Error}}</div>
{{end}}
{{if .Success}}
<div class="alert alert-success">{{.Success}}</div>
{{end}}
{{if .Message}}
<div class="alert alert-info">{{.Message}}</div>
{{end}}
<!-- This is shorthand for a define along with a template -->
{{block "content" .}}{{end}}
</div>

View File

@@ -1,31 +1,41 @@
{{define "title"}}Enter scores - QRank{{end}}
{{define "title"}}QRank{{end}}
{{define "content"}}
<div class="card">
<h2>Enter a game</h2>
{{if .Table}}<p class="small">Table: <span class="badge">{{.Table.Name}}</span></p>{{end}}
<form method="POST" action="{{.PostAction}}">
{{if .Table}}
<p class="small">Table: <span class="badge">{{.Table.Name}}</span></p>
{{end}}
<form method="POST" action="/enter">
<div class="row">
<div style="flex:1;min-width:280px">
<div style="flex:1;min-width:180px">
<h3>Team A</h3>
<label class="label">Player A1</label>
<input class="input" name="a1" value="{{.CurrentUser.Username}}">
<input class="input" name="a1" {{if .a1}}value="{{.a1}}"{{else}}value="{{.CurrentUser.Username}}"{{end}} placeholder="username or email">
<div style="height:6px"></div>
<label class="label">Player A2 (optional)</label>
<input class="input" name="a2" placeholder="username or email">
<input class="input" name="a2" {{if .a2}}value="{{.a2}}"{{end}} placeholder="username or email">
<div style="height:12px"></div>
<label class="label">Score A</label>
<input class="input" type="number" name="scoreA" value="10" min="0" required>
<input class="input" type="number" name="scoreA" {{if .scoreA}}value="{{.scoreA}}"{{else}}value="0"{{end}} min="0" max="10" required>
</div>
<div style="flex:1;min-width:280px">
<div style="flex:1;min-width:180px">
<h3>Team B</h3>
<label class="label">Player B1</label>
<input class="input" name="b1" placeholder="username or email">
<input class="input" name="b1" {{if .b1}}value="{{.b1}}"{{end}} placeholder="username or email">
<div style="height:6px"></div>
<label class="label">Player B2 (optional)</label>
<input class="input" name="b2" placeholder="username or email">
<input class="input" name="b2" {{if .b2}}value="{{.b2}}"{{end}} placeholder="username or email">
<div style="height:12px"></div>
<label class="label">Score B</label>
<input class="input" type="number" name="scoreB" value="8" min="0" required>
<input class="input" type="number" name="scoreB" {{if .scoreB}}value="{{.scoreB}}"{{else}}value="0"{{end}} min="0" max="10" required>
</div>
</div>
<div style="height:12px"></div>
<button class="btn btn-primary" type="submit">Submit result</button>
</form>
</div>
{{end}}
{{end}}

View File

@@ -7,7 +7,7 @@
<div class="small">{{fmtTime .CreatedAt}}</div>
<div>
{{if .Table}}<span class="badge">{{.Table.Name}}</span> {{end}}
Team A {{.ScoreA}} \u2013 {{.ScoreB}} Team B
{{if .WinnerIsA}}{{range .PlayersA}}{{.Username}} {{end}}{{.ScoreA}}/{{.ScoreB}}{{else}}{{range .PlayersB}}{{.Username}} {{end}}{{.ScoreB}}/{{.ScoreA}}{{end}}
</div>
<div class="small">
{{range .PlayersA}}@{{.Username}} {{end}}vs {{range .PlayersB}}@{{.Username}} {{end}}

View File

@@ -3,7 +3,7 @@
<h2>Leaderboard (by wins)</h2>
<ol>
{{range .Rows}}
<li>@<a href="/u/{{.Slug}}">{{.Username}}</a> \u2014 {{.Wins}} wins ({{.Games}} games)</li>
<li>@<a href="/u/{{.Slug}}">{{.Username}}</a> - {{.Wins}} wins ({{.Games}} games)</li>
{{else}}
<li class="small">No players yet.</li>
{{end}}

View File

@@ -1,7 +1,7 @@
{{define "content"}}
<div class="card">
<h2>Check the server logs</h2>
<p class="small">We just printed a magic link for <strong>{{.Email}}</strong>. Open it here to sign in.
<h2>Check your email inbox</h2>
<p class="small">We just printed a magic link for <strong>{{.Email}}</strong>. Open it to sign in.
Token expires in 30 days.</p>
<a class="btn" href="/login">Back</a>
</div>

View File

@@ -2,7 +2,7 @@
<div class="card">
<h2>@{{.Viewed.Username}}</h2>
<p class="small">Joined {{fmtTime .Viewed.CreatedAt}}</p>
<p>Games played: {{.Stats.Games}} Wins: {{.Stats.Wins}} Losses: {{.Stats.Losses}}</p>
<p>Game score {{.Stats.Games}}/{{.Stats.Wins}}/{{.Stats.Losses}}</p>
{{if .Own}}
<hr>
<h3>Update your profile</h3>