summaryrefslogtreecommitdiff
path: root/views
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-10-13 12:48:48 +0200
committerTor Andersson <tor@ccxvii.net>2024-10-13 18:49:00 +0200
commit4d7bdc955a2e6dd2c222f985c7fbc9b4febbccc4 (patch)
treea344e7c011b07e83ab0abf57e1aa043a9a81dff2 /views
parent88d909a874499f9d3d18e76ff30c1155caa2e48e (diff)
downloadserver-4d7bdc955a2e6dd2c222f985c7fbc9b4febbccc4.tar.gz
Tournaments!
Diffstat (limited to 'views')
-rw-r--r--views/about.pug13
-rw-r--r--views/games_active.pug7
-rw-r--r--views/games_list.pug48
-rw-r--r--views/games_public.pug2
-rw-r--r--views/head.pug69
-rw-r--r--views/header.pug1
-rw-r--r--views/info.pug2
-rw-r--r--views/tm_active.pug24
-rw-r--r--views/tm_finished.pug18
-rw-r--r--views/tm_list.pug28
-rw-r--r--views/tm_pool.pug159
-rw-r--r--views/tm_seed.pug100
-rw-r--r--views/user.pug7
13 files changed, 465 insertions, 13 deletions
diff --git a/views/about.pug b/views/about.pug
index b19a45e..f2f9964 100644
--- a/views/about.pug
+++ b/views/about.pug
@@ -11,17 +11,20 @@ html
p.
Here you can play board games online with other players.
- You can invite your friends or look in the waiting room to see whether someone wants to play.
+ You can invite your friends, compete in tournaments, or look in the public room to see whether someone wants to play.
Your opponents don't have to be online, but if they are you can play live.
p.
Registration and use is free, and there are no ads.
- p.
- Please read the <a href="/docs/tips.html">Tips &amp; Tricks</a> before playing!
+ p!= process.env.SITE_INVITE
- p.
- Read the developer <a href="/docs/">documentation</a> if you want to create modules.
+ h2 About
+
+ ul
+ li Read the <a href="/docs/tips.html">Tips &amp; Tricks</a> before playing!
+ li Read the <a href="/docs/tournaments.html">tournament information</a> before joining a tournament.
+ li Study the <a href="/docs/">developer documentation</a> if you want to create modules.
p.
The source code is available on #[a(href="https://git.rally-the-troops.com/") git.rally-the-troops.com].
diff --git a/views/games_active.pug b/views/games_active.pug
index 76ac030..eaa1076 100644
--- a/views/games_active.pug
+++ b/views/games_active.pug
@@ -25,6 +25,11 @@ html
p
a(href="/create") Create a new game
+ +tourlist(seeds, active_pools, finished_pools)
+
+ p
+ a(href="/tm/list") Join a tournament
+
if move_games.length > 0
h2 Move
+gamelist(move_games)
@@ -47,3 +52,5 @@ html
p
a(href="/games/finished") All your finished games
+ br
+ a(href="/tm/finished") All your finished tournaments
diff --git a/views/games_list.pug b/views/games_list.pug
new file mode 100644
index 0000000..52c14d9
--- /dev/null
+++ b/views/games_list.pug
@@ -0,0 +1,48 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ +social(SITE_NAME, "Play historic board games on the web.")
+ meta(name="keywords" content="wargames, war games, block games")
+ title= SITE_NAME
+ style.
+ .list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
+ grid-auto-rows: 190px;
+ gap: 8px;
+ }
+ .list a {
+ display: grid;
+ grid-template-rows: 146px 40px;
+ text-align: center;
+ font-family: var(--font-small);
+ font-size: 14px;
+ line-height: 20px;
+ text-wrap: balance;
+ gap: 4px;
+ }
+ .list img {
+ display: block;
+ margin: auto auto;
+ min-width: 108px;
+ min-height: 108px;
+ max-width: 144px;
+ max-height: 144px;
+ background-color: silver;
+ box-shadow: var(--drop-shadow);
+ border: var(--thin-border);
+ }
+ body
+ include header
+ article.wide
+
+ h1 Games
+
+ div.list
+ each title in TITLE_LIST
+ unless title.is_hidden
+ a.black(href="/"+title.title_id)
+ img(src="/"+title.title_id+"/thumbnail.jpg")
+ div= title.title_name
diff --git a/views/games_public.pug b/views/games_public.pug
index cf102f0..54591cd 100644
--- a/views/games_public.pug
+++ b/views/games_public.pug
@@ -9,7 +9,7 @@ html
body
include header
article.wide
- h1 Public Games
+ h1 Public room
h2 Open
if open_games.length > 0
diff --git a/views/head.pug b/views/head.pug
index 4262408..66e3f58 100644
--- a/views/head.pug
+++ b/views/head.pug
@@ -102,14 +102,18 @@ mixin gamelist(list,hide_title=0)
div.game_main
div.game_info
- if item.notice
+ if item.is_match
+ i
+ a(href="/tm/pool/"+item.notice)= item.notice
+ else if item.notice
i= item.notice
else
i= pace_text
- if item.scenario !== "Standard" && item.scenario !== "Historical" && item.scenario.length > 2
- div Scenario: #{item.scenario}
- unless item.human_options === "None"
- div Options: #{item.human_options}
+ unless item.is_match
+ if item.scenario !== "Standard" && item.scenario !== "Historical" && item.scenario.length > 2
+ div Scenario: #{item.scenario}
+ unless item.human_options === "None"
+ div Options: #{item.human_options}
if item.player_names
div Players: !{item.player_names}
else
@@ -135,3 +139,58 @@ mixin gamelist(list,hide_title=0)
unless hide_title
a(href=`/${item.title_id}`)
img(src=`/${item.title_id}/thumbnail.jpg`)
+
+mixin seedlist(list, title)
+ if list && list.length > 0
+ table.half.seeds
+ if title
+ thead
+ tr
+ th= title
+ td
+ td= TM_ICON_QUEUE
+ tbody
+ each seed in list
+ tr
+ td
+ a(href="/tm/seed/" + seed.seed_name)= seed.seed_name
+ td.n #{seed.queue_size}
+ if user && seed.is_queued
+ td= TM_ICON_TICKET
+ else
+ td
+
+mixin poollist(list, title, icon)
+ if list && list.length > 0
+ table.half.pools
+ if title
+ thead
+ tr
+ th= title
+ td= icon
+ tbody
+ each pool in list
+ tr
+ td.w
+ a(href="/tm/pool/" + pool.pool_name)= pool.pool_name
+ if pool.is_finished
+ if pool.status
+ td!= pool.status.split(",").map(p => `<a class="black" href="/user/${p}">${p}</a>`).join(", ")
+ else
+ td Nobody
+ else
+ td= pool.status
+
+mixin tourlist(seeds, pools, fin)
+ if (seeds && seeds.length > 0) || (pools && pools.length > 0) || (fin && fin.length > 0)
+ h2 Tournaments
+ div.tour_list
+ if seeds && seeds.length > 0
+ div
+ +seedlist(seeds, "Registrations")
+ if pools && pools.length > 0
+ div
+ +poollist(pools, "Active", TM_ICON_ACTIVE)
+ if fin && fin.length > 0
+ div
+ +poollist(fin, "Finished", TM_ICON_FINISHED)
diff --git a/views/header.pug b/views/header.pug
index 9ff1263..6df51e6 100644
--- a/views/header.pug
+++ b/views/header.pug
@@ -9,6 +9,7 @@ header
if user
if ENABLE_FORUM
a(href="/forum") Forum
+ a(href="/tm/list") Tournaments
a(href="/games/public") Public
if user.waiting > 0
a(href="/games/active") Games (#{user.waiting})
diff --git a/views/info.pug b/views/info.pug
index 3e80fb1..2ffd8f0 100644
--- a/views/info.pug
+++ b/views/info.pug
@@ -28,6 +28,8 @@ html
p
a(href="/create/"+title.title_id) Create a new game
+ +tourlist(seeds, active_pools, finished_pools)
+
if active_games.length > 0
h2 Recently active
+gamelist(active_games, true)
diff --git a/views/tm_active.pug b/views/tm_active.pug
new file mode 100644
index 0000000..cc821b2
--- /dev/null
+++ b/views/tm_active.pug
@@ -0,0 +1,24 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ title= SITE_NAME
+ body
+ include header
+ article.wide
+ h1 Your Tournaments
+
+ if seeds && seeds.length > 0
+ +seedlist(seeds, "Registrations")
+ p
+ a(href="/tm/list") Join a tournament
+
+ if active_pools && active_pools.length > 0
+ div
+ +poollist(active_pools, "Active", TM_ICON_ACTIVE)
+ div
+ if finished_pools && finished_pools.length > 0
+ +poollist(finished_pools, "Finished", TM_ICON_FINISHED)
+ p
+ a(href="/tm/finished") All your finished tournaments
diff --git a/views/tm_finished.pug b/views/tm_finished.pug
new file mode 100644
index 0000000..efe193d
--- /dev/null
+++ b/views/tm_finished.pug
@@ -0,0 +1,18 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ title= SITE_NAME
+ body
+ include header
+ article.wide
+ if user && user.user_id === who.user_id
+ h1 Your finished tournaments
+ else
+ h1 #{who.name}&rsquo;s finished tournaments
+
+ if pools.length > 0
+ +poollist(pools, TM_ICON_FINISHED)
+ else
+ p Nothing here.
diff --git a/views/tm_list.pug b/views/tm_list.pug
new file mode 100644
index 0000000..41945fc
--- /dev/null
+++ b/views/tm_list.pug
@@ -0,0 +1,28 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ title Tournaments
+ body
+ include header
+ article
+ h1 Tournaments
+
+ p See <a href="/docs/tournaments.html">tournament information</a>.
+
+ if 0
+ dl
+ each seeds, title_id in seeds_by_title
+ dt= TITLE_NAME[title_id]
+ each seed in seeds
+ dd
+ a(href="/tm/seed/" + seed.seed_name)= seed.seed_name
+ | (#{seed.queue_size}/#{seed.pool_size})
+ if user && seed.is_queued
+ | &#x1f3ab;
+ if 0
+ each seeds, title_id in seeds_by_title
+ +seedlist(seeds, TITLE_NAME[title_id])
+ if 1
+ +seedlist(seeds, "Mini Cup")
diff --git a/views/tm_pool.pug b/views/tm_pool.pug
new file mode 100644
index 0000000..d801375
--- /dev/null
+++ b/views/tm_pool.pug
@@ -0,0 +1,159 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ title= pool.pool_name
+ style.
+ @media (max-width: 500px) {
+ table {
+ font-family: var(--font-widget);
+ font-size: 12px;
+ line-height: 16px;
+ }
+ }
+ td, th { padding: 2px 6px; }
+ table.wide tbody tr:hover { background-color: #0001 }
+ tr.hr { padding: 0; border-bottom: 1px solid black }
+ td.c { text-align: center }
+ td.g { color: gray }
+ a.gray { text-decoration: none; color: gray }
+ div.thumb {
+ float: right;
+ }
+ div.thumb img {
+ max-width: 60px;
+ max-height: 72px;
+ margin: 4px 0 4px 4px;
+ border: var(--thin-border);
+ box-shadow: var(--drop-shadow);
+ }
+ #pool_info td { padding: 2px 10px }
+ #pool_info td:first-child { width: 80px }
+ #pool_info tr:first-child td { padding-top: 5px }
+ #pool_info tr:last-child td { padding-bottom: 5px }
+ body
+ include header
+ article
+ div.thumb
+ a(href="/"+seed.title_id)
+ img(src="/"+seed.title_id+"/thumbnail.jpg")
+
+ h2= pool.pool_name
+
+ table.half#pool_info
+ tr
+ td Tournament
+ td
+ a(href="/tm/seed/" + seed.seed_name)= seed.seed_name
+ tr
+ td Started
+ td= human_date(pool.start_date)
+ tr
+ td Finished
+ if pool.finish_date
+ td= human_date(pool.finish_date)
+
+ if seed.player_count === 2
+ table.wide
+ thead
+ tr
+ td.n
+ td
+ each row, ix in players
+ td.n.c= ix+1
+ td.n Pts
+ td.n Son
+ tbody
+ each row, rx in players
+ - var result = JSON.parse(row.result)
+ tr
+ td= rx+1
+ td
+ if row.name
+ <a class="black" href="/user/#{row.name}">#{row.name}</a>
+ else
+ | null
+ each col in players
+ if row.name === col.name
+ td
+ else
+ td.w.c
+ if result[col.name]
+ each gs, ix in result[col.name]
+ if ix > 0
+ | &nbsp;
+ if gs[1] === null
+ a.black(href="/join/" + gs[0]) &minus;
+ else
+ a.black(href="/join/" + gs[0])= gs[1]
+ td.r= row.points
+ td.r.g= row.son
+
+ else
+ - var n = JSON.parse(players[0].result).length
+ table.wide
+ thead
+ tr
+ td.n
+ td
+ - var i = 0
+ while i < n
+ td.n.c= i+1
+ - ++i
+ td.n.r Pts
+ td.n.r Son
+ tbody
+ each row, rx in players
+ - var result = JSON.parse(row.result)
+ tr
+ td= rx+1
+ td
+ if row.name
+ <a class="black" href="/user/#{row.name}">#{row.name}</a>
+ else
+ | null
+ each gs in result
+ td.c
+ if gs[1] === null
+ a.black(href="/join/" + gs[0]) &minus;
+ else
+ a.black(href="/join/" + gs[0])= gs[1]
+ td.r= row.points
+ td.r.g= row.son
+
+ table.wide
+ thead
+ tr
+ td Game
+ each role in roles
+ td= role
+ td.n.r Result
+ td.n.r Moves
+ tbody
+ each group,ix in games_by_round
+ if ix > 1
+ tr.hr
+ each game in group
+ - var role_names = JSON.parse(game.role_names)
+ - var role_scores = JSON.parse(game.role_scores)
+ tr
+ td.n
+ a.black(href="/join/" + game.game_id)= "#" + game.game_id
+ each role in roles
+ - var p = role_names[role]
+ td
+ a.black(href="/user/"+p)= p
+
+ if game.status > 1
+ td.w.r
+ each role, ix in roles
+ if ix > 0
+ | &nbsp;:&nbsp;
+ | #{role_scores[role]}
+ else
+ td.r
+ if game.status > 0
+ td.r= game.moves
+ else
+ td.r
diff --git a/views/tm_seed.pug b/views/tm_seed.pug
new file mode 100644
index 0000000..683029f
--- /dev/null
+++ b/views/tm_seed.pug
@@ -0,0 +1,100 @@
+//- vim:ts=4:sw=4:
+doctype html
+html
+ head
+ include head
+ title= seed.seed_name
+ style.
+ div.thumb {
+ float: right;
+ }
+ div.thumb img {
+ max-width: 60px;
+ max-height: 72px;
+ margin: 4px 0 4px 4px;
+ border: var(--thin-border);
+ box-shadow: var(--drop-shadow);
+ }
+ #seed_info td { padding: 2px 10px }
+ #seed_info td:first-child { width: 80px }
+ #seed_info tr:first-child td { padding-top: 5px }
+ #seed_info tr:last-child td { padding-bottom: 5px }
+ table { margin: 1em 0 0.5em 0 }
+ body
+ include header
+ article
+ div.thumb
+ a(href="/"+seed.title_id)
+ img(src="/"+seed.title_id+"/thumbnail.jpg")
+
+ h1= seed.seed_name
+
+ if error
+ p.error= error
+
+ table#seed_info.half
+ tr
+ td Format
+ td
+ a(href="/docs/tournaments.html") Mini Cup
+ if seed.scenario !== "Standard"
+ tr
+ td Scenario
+ td #{seed.scenario}
+ if seed.pace
+ tr
+ td Pace
+ td= PACE_ICON[seed.pace]
+ tr
+ td Players
+ td #{seed.pool_size}
+ tr
+ td Rounds
+ if (seed.is_concurrent)
+ td #{seed.round_count} concurrent
+ else
+ td #{seed.round_count} sequential
+
+ if seed.is_open
+ each queue,ix in queues
+ table.half
+ thead
+ tr
+ if seed.level_count > 1
+ th Level #{ix+1}
+ else
+ th Registered
+ td.r #{queue.length} / #{seed.pool_size}
+ tbody
+ tr
+ if queue.length > 0
+ td(colspan=2)!= queue.map(p => `<a class="black" href="/user/${p.name}">${p.name}</a>`).join(", ")
+ else
+ td Nobody
+
+ if user
+ if ix === 0
+ if may_register
+ if !queue.find(p => p.user_id === user.user_id)
+ form(method="post" action="/api/tm/register/" + seed.seed_id)
+ button(type="submit") Register
+ button(disabled) Withdraw
+ else
+ div
+ button(disabled) Register
+ button(disabled) Withdraw
+
+ if queue.find(p => p.user_id === user.user_id)
+ form(method="post" action="/api/tm/withdraw/" + seed.seed_id + "/" + (ix+1))
+ button(disabled) Register
+ button(type="submit") Withdraw
+
+ if user.user_id === 1
+ if queue.length >= seed.pool_size
+ form(method="post" action="/api/tm/start/" + seed.seed_id + "/" + (ix+1))
+ button(type="submit") Start
+ else
+ p <a href="/login">Login</a> or <a href="/signup">sign up</a> to register.
+
+ +poollist(active_pools, "Active", TM_ICON_ACTIVE)
+ +poollist(finished_pools, "Finished", TM_ICON_FINISHED)
diff --git a/views/user.pug b/views/user.pug
index ce5b5f0..06fa91d 100644
--- a/views/user.pug
+++ b/views/user.pug
@@ -40,10 +40,12 @@ html
else
a(href="/contacts/add-friend/"+who.name) Add to friends
br
- a(href="/contacts/add-enemy/"+who.name) Blacklist user
+ a(href="/contacts/add-enemy/"+who.name) Add to blacklist
+
+ +tourlist(null, active_pools, finished_pools)
if open_games.length > 0
- h2 Open
+ h2 Invitations
+gamelist(open_games)
if active_games.length > 0
@@ -63,6 +65,7 @@ html
+gamelist(finished_games)
p <a href="/games/finished/#{who.name}">All #{who.name}'s finished games</a>
+ p <a href="/tm/finished/#{who.name}">All #{who.name}'s finished tournaments</a>
if user && user.user_id === 1
if who.is_banned