mirror of
https://github.com/KeyZox71/knl_meowscendence.git
synced 2025-10-14 02:54:44 +02:00
「🚧」 test(src/front): wip of the front
This commit is contained in:
@ -1,5 +1,8 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@theme {
|
@source inline("space-y-{18,46,102,214,438,886,1782,3574,7158,14326,28662,57334,114678,229366,458742,917494}");
|
||||||
|
@source inline("mt-{28,56,84,112}");
|
||||||
|
|
||||||
|
/*@theme {
|
||||||
--color-accent-500: #f55151;
|
--color-accent-500: #f55151;
|
||||||
}
|
}*/
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
/*import MainMenu from "./views/MainMenu.ts";
|
|
||||||
import PongMenu from "./views/PongMenu.ts";
|
|
||||||
|
|
||||||
import LoginPage from "./views/LoginPage.ts";
|
|
||||||
import RegisterPage from "./views/RegisterPage.ts";
|
|
||||||
|
|
||||||
import Game from "./views/Game.ts";*/
|
|
||||||
|
|
||||||
const navigationManager = url => {
|
const navigationManager = url => {
|
||||||
history.pushState(null, null, url);
|
history.pushState(null, null, url);
|
||||||
router();
|
router();
|
||||||
@ -14,17 +6,11 @@ const navigationManager = url => {
|
|||||||
let view;
|
let view;
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
/*{ path: "/", view: MainMenu },
|
|
||||||
|
|
||||||
{ path: "/pong", view: PongMenu },
|
|
||||||
{ path: "/pong/solo", view: Game },
|
|
||||||
|
|
||||||
{ path: "/login", view: LoginPage },
|
|
||||||
{ path: "/register", view: RegisterPage },*/
|
|
||||||
{ path: "/", view: () => import("./views/MainMenu.ts") },
|
{ path: "/", view: () => import("./views/MainMenu.ts") },
|
||||||
|
|
||||||
{ path: "/pong", view: () => import("./views/PongMenu.ts") },
|
{ path: "/pong", view: () => import("./views/PongMenu.ts") },
|
||||||
{ path: "/pong/solo", view: () => import("./views/Game.ts") },
|
{ path: "/pong/local", view: () => import("./views/Game.ts") },
|
||||||
|
{ path: "/pong/tournament", view: () => import("./views/TournamentMenu.ts") },
|
||||||
|
|
||||||
{ path: "/login", view: () => import("./views/LoginPage.ts") },
|
{ path: "/login", view: () => import("./views/LoginPage.ts") },
|
||||||
{ path: "/register", view: () => import("./views/RegisterPage.ts") },
|
{ path: "/register", view: () => import("./views/RegisterPage.ts") },
|
||||||
|
@ -7,7 +7,7 @@ export default class extends Aview {
|
|||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.setTitle("pog or pong ? :3");
|
this.setTitle("pong (local match)");
|
||||||
this.running = true;
|
this.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ export default class extends Aview {
|
|||||||
rightPaddleY -= paddleSpeed * elapsed;
|
rightPaddleY -= paddleSpeed * elapsed;
|
||||||
if (keys["ArrowDown"] && rightPaddleY < canvas.height - paddleHeight)
|
if (keys["ArrowDown"] && rightPaddleY < canvas.height - paddleHeight)
|
||||||
rightPaddleY += paddleSpeed * elapsed;
|
rightPaddleY += paddleSpeed * elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBounceVelocity(paddleY) {
|
function getBounceVelocity(paddleY) {
|
||||||
const speed = ballSpeed;
|
const speed = ballSpeed;
|
||||||
@ -209,6 +209,7 @@ export default class extends Aview {
|
|||||||
countdown = 3;
|
countdown = 3;
|
||||||
countdownTimer = performance.now();
|
countdownTimer = performance.now();
|
||||||
});
|
});
|
||||||
|
|
||||||
requestAnimationFrame(gameLoop);
|
requestAnimationFrame(gameLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ export default class extends Aview {
|
|||||||
<div class="text-center p-10 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4 flex flex-col">
|
<div class="text-center p-10 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4 flex flex-col">
|
||||||
<h1 class="text-4xl font-bold text-blue-600">login</h1>
|
<h1 class="text-4xl font-bold text-blue-600">login</h1>
|
||||||
|
|
||||||
<input type="text" id="username" class="bg-white text-neutral-900 border rounded-md w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
<input type="text" placeholder="username" id="username" class="bg-white text-neutral-900 border rounded-md w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
||||||
<input type="password" id="password" class="bg-white text-neutral-900 border w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 border w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
||||||
<p id="login-error-message" class="hidden text-red-700 dark:text-red-500"></p>
|
<p id="login-error-message" class="hidden text-red-700 dark:text-red-500"></p>
|
||||||
<button id="login-button" type="submit" class="bg-blue-600 text-white hover:bg-blue-500 w-full py-2 rounded-md transition-colors">login</button>
|
<button id="login-button" type="submit" class="bg-blue-600 text-white hover:bg-blue-500 w-full py-2 rounded-md transition-colors">login</button>
|
||||||
|
|
||||||
@ -31,16 +31,16 @@ export default class extends Aview {
|
|||||||
const password = (document.getElementById("password") as HTMLInputElement).value;
|
const password = (document.getElementById("password") as HTMLInputElement).value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*const response = await fetch("https://localhost/login", {
|
const response = await fetch("http://localhost:3001/login", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json", },
|
headers: { "Content-Type": "application/json", },
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify({ user: username, password: password }),
|
body: JSON.stringify({ user: username, password: password }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json();*/
|
const data = await response.json();
|
||||||
const data = { "error": "invalid password or smth" };
|
/*const data = { "error": "invalid password or smth" };
|
||||||
const response = { status: 400};
|
const response = { status: 400};*/
|
||||||
|
|
||||||
|
|
||||||
if (response.status === 200)
|
if (response.status === 200)
|
||||||
@ -56,6 +56,7 @@ export default class extends Aview {
|
|||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
console.log(error);
|
||||||
document.getElementById("login-error-message").innerHTML = "error: server error, try again later...";
|
document.getElementById("login-error-message").innerHTML = "error: server error, try again later...";
|
||||||
document.getElementById("login-error-message").classList.remove("hidden");
|
document.getElementById("login-error-message").classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,21 @@ export default class extends Aview {
|
|||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.setTitle("ponging ur mom");
|
this.setTitle("knl is trans(cendence)");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHTML() {
|
async getHTML() {
|
||||||
return `
|
return `
|
||||||
<div class="text-center p-10 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4">
|
<div class="text-center p-12 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4">
|
||||||
<p class="text-gray-700 dark:text-white text-3xl font-bold pb-4">pong is funny yay</p>
|
<p class="text-gray-700 dark:text-white text-3xl font-bold pb-4">pong is funny yay</p>
|
||||||
<a class="bg-red-500 hover:bg-red-400 text-white px-4 py-2 rounded" href="/pong/solo" data-link>
|
<div class="flex flex-col space-y-4">
|
||||||
solo
|
<a class="bg-red-500 hover:bg-red-400 text-white px-4 py-2 rounded" href="/pong/local" data-link>
|
||||||
</a>
|
local match
|
||||||
|
</a>
|
||||||
|
<a class="bg-red-500 hover:bg-red-400 text-white px-4 py-2 rounded" href="/pong/tournament" data-link>
|
||||||
|
local tournament
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ export default class extends Aview {
|
|||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.setTitle("ft_trans 🏳️⚧️");
|
this.setTitle("register");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHTML() {
|
async getHTML() {
|
||||||
@ -13,8 +13,8 @@ export default class extends Aview {
|
|||||||
<div class="text-center p-10 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4 flex flex-col">
|
<div class="text-center p-10 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4 flex flex-col">
|
||||||
<h1 class="text-4xl font-bold text-blue-600">register</h1>
|
<h1 class="text-4xl font-bold text-blue-600">register</h1>
|
||||||
|
|
||||||
<input type="text" id="username" class="bg-white text-neutral-900 border rounded-md w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
<input type="text" id="username" placeholder="username" class="bg-white text-neutral-900 border rounded-md w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
||||||
<input type="password" id="password" class="bg-white text-neutral-900 border w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
<input type="password" id="password" placeholder="password" class="bg-white text-neutral-900 border w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
||||||
|
|
||||||
<button type="submit" class="bg-blue-600 text-white hover:bg-blue-500 w-full py-2 rounded-md transition-colors">register</button>
|
<button type="submit" class="bg-blue-600 text-white hover:bg-blue-500 w-full py-2 rounded-md transition-colors">register</button>
|
||||||
|
|
||||||
|
141
src/front/static/ts/views/TournamentMenu.ts
Normal file
141
src/front/static/ts/views/TournamentMenu.ts
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
import Aview from "./Aview.ts"
|
||||||
|
|
||||||
|
export default class extends Aview {
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.setTitle("Tournament");
|
||||||
|
}
|
||||||
|
|
||||||
|
async getHTML() {
|
||||||
|
return `
|
||||||
|
<div class="text-center p-12 bg-white dark:bg-neutral-800 rounded-xl shadow space-y-4">
|
||||||
|
<p class="text-gray-700 dark:text-white text-lg font-bold pb-4">how many players ?</p>
|
||||||
|
<div class="flex flex-col space-y-4">
|
||||||
|
<input type="number" id="playerNumber" value="6" placeholder="number of players" class="bg-white text-neutral-900 border rounded-md w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"></input>
|
||||||
|
<button type="submit" id="bracket-generate" class="bg-blue-600 text-white hover:bg-blue-500 w-full py-2 rounded-md transition-colors">create the bracket</button>
|
||||||
|
<div id="bracket"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run() {
|
||||||
|
const generateBracket = async (playerCount: number) => {
|
||||||
|
document.getElementById("bracket").innerHTML = "";
|
||||||
|
|
||||||
|
const rounds = Math.ceil(Math.log2(playerCount));
|
||||||
|
const totalSlots = 2 ** rounds;
|
||||||
|
const byes = totalSlots - playerCount;
|
||||||
|
|
||||||
|
let odd = 0;
|
||||||
|
if (playerCount % 2)
|
||||||
|
{
|
||||||
|
console.error("odd numbers are temporarily invalids");
|
||||||
|
return ;
|
||||||
|
/*++odd;
|
||||||
|
--playerCount;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
let notPowPlayersCount = 0;
|
||||||
|
|
||||||
|
if ((playerCount & (playerCount - 1)) != 0)
|
||||||
|
notPowPlayersCount = playerCount - (2 ** Math.floor(Math.log2(playerCount)));
|
||||||
|
|
||||||
|
|
||||||
|
let initialPlayers = Array.from({ length: 2 ** Math.floor(Math.log2(playerCount))}, (_, i) => `Player ${i + 1}`);
|
||||||
|
playerCount = 2 ** Math.floor(Math.log2(playerCount));
|
||||||
|
//let initialPlayers = Array.from({ length: playerCount }, (_, i) => `Player ${i + 1}`);
|
||||||
|
|
||||||
|
const bracketWrapper = document.createElement("div");
|
||||||
|
bracketWrapper.className = "flex space-x-8 overflow-x-auto";
|
||||||
|
|
||||||
|
// Round 0: Player input column
|
||||||
|
const playerInputColumn = document.createElement("div");
|
||||||
|
playerInputColumn.className = `flex flex-col mt-${(notPowPlayersCount + odd) * 28} space-y-4`;
|
||||||
|
|
||||||
|
initialPlayers.forEach((name, i) => {
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "text";
|
||||||
|
input.id = `playerName${i}`;
|
||||||
|
input.value = "";
|
||||||
|
input.placeholder = name;
|
||||||
|
input.className =
|
||||||
|
"w-32 h-10 p-2 text-sm border rounded bg-white shadow disabled:bg-gray-200";
|
||||||
|
playerInputColumn.appendChild(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
bracketWrapper.appendChild(playerInputColumn);
|
||||||
|
|
||||||
|
let currentRound = initialPlayers;
|
||||||
|
let previousPadding = 4;
|
||||||
|
for (let round = 1; round <= rounds; round++)
|
||||||
|
{
|
||||||
|
const roundColumn = document.createElement("div");
|
||||||
|
previousPadding = previousPadding * 2 + 10
|
||||||
|
roundColumn.className = `flex flex-col justify-center space-y-${previousPadding}`;
|
||||||
|
|
||||||
|
const nextRound: string[] = [];
|
||||||
|
|
||||||
|
if (!notPowPlayersCount)
|
||||||
|
{
|
||||||
|
if (odd)
|
||||||
|
{
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "text";
|
||||||
|
input.id = `playerName${playerCount}`;
|
||||||
|
input.value = "";
|
||||||
|
input.placeholder = `Player ${++playerCount}`;
|
||||||
|
input.className =
|
||||||
|
"w-32 h-10 p-2 text-sm border rounded bg-white shadow disabled:bg-gray-200";
|
||||||
|
roundColumn.appendChild(input);
|
||||||
|
odd--;
|
||||||
|
nextRound.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (notPowPlayersCount)
|
||||||
|
{
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "text";
|
||||||
|
input.id = `playerName${playerCount}`;
|
||||||
|
input.value = "";
|
||||||
|
input.placeholder = `Player ${++playerCount}`;
|
||||||
|
input.className =
|
||||||
|
"w-32 h-10 p-2 text-sm border rounded bg-white shadow disabled:bg-gray-200";
|
||||||
|
roundColumn.appendChild(input);
|
||||||
|
--notPowPlayersCount;
|
||||||
|
nextRound.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < currentRound.length; i += 2)
|
||||||
|
{
|
||||||
|
const p1 = currentRound[i];
|
||||||
|
const p2 = currentRound[i + 1];
|
||||||
|
|
||||||
|
const matchDiv = document.createElement("div");
|
||||||
|
matchDiv.className =
|
||||||
|
"w-32 h-10 flex items-center justify-center bg-white border rounded shadow text-center text-sm";
|
||||||
|
|
||||||
|
matchDiv.textContent = "";
|
||||||
|
nextRound.push("");
|
||||||
|
|
||||||
|
roundColumn.appendChild(matchDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
bracketWrapper.appendChild(roundColumn);
|
||||||
|
currentRound = nextRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("bracket").appendChild(bracketWrapper);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("bracket-generate")?.addEventListener("click", () => {
|
||||||
|
const input: HTMLInputElement = document.getElementById("playerNumber") as HTMLInputElement;
|
||||||
|
generateBracket(+input.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
content: ['./src/front/**/*.{html,js}'],
|
content: ['./src/front/**/*.{html,js,ts,css}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user