Iniziata la frontend (con Preact) della pagina di creazione delle partite
parent
d8f1a9b4d2
commit
a6c06dc831
@ -1,12 +1,21 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Login • Lupus Lite</title>
|
<title>Crea Partita • Lupus Lite</title>
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=IM+Fell+English:ital@0;1&family=Lato:ital,wght@0,300;0,400;0,900;1,300;1,400;1,900&display=swap" rel="stylesheet" />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" rel="stylesheet" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/src/main.scss" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Crea Partita | Lupus Lite</h1>
|
<main></main>
|
||||||
|
<script type="module" src="/src/crea-partita/main.jsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Lupus Lite</title>
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=IM+Fell+English:ital@0;1&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/src/main.scss">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<h1><a href="/">Lupus Lite</a></h1>
|
||||||
|
<h2>Login</h2>
|
||||||
|
</header>
|
||||||
|
<form action="/api/register" method="post">
|
||||||
|
<h2 class="fill-row">Registrati</h2>
|
||||||
|
<p class="fill-row">
|
||||||
|
Crea un account per accedere alla pagina utente
|
||||||
|
</p>
|
||||||
|
<label for="register-username">Username</label>
|
||||||
|
<input type="text" name="username" id="register-username">
|
||||||
|
<label for="register-password">Password</label>
|
||||||
|
<input type="password" name="password" id="register-password">
|
||||||
|
<label for="register-password">Ripeti Password</label>
|
||||||
|
<input type="password" name="password2" id="register-password2">
|
||||||
|
<button class="fill-row" type="submit">Registrati</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,100 @@
|
|||||||
|
import { render } from 'preact'
|
||||||
|
import { useState, useEffect } from 'preact/hooks'
|
||||||
|
|
||||||
|
const InputNumero = ({ name, id, value, setValue }) => (
|
||||||
|
<div class="compound-input">
|
||||||
|
<input
|
||||||
|
class="grow"
|
||||||
|
type="number"
|
||||||
|
name={name}
|
||||||
|
id={id}
|
||||||
|
value={value}
|
||||||
|
onInput={e => setValue(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button type="button" class="square" onClick={() => setValue(value => value + 1)}>
|
||||||
|
<span class="material-symbols-outlined">add</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="square" onClick={() => setValue(value => value - 1)}>
|
||||||
|
<span class="material-symbols-outlined">remove</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const [user, setUser] = useState(null)
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('/api/user')
|
||||||
|
.then(res => {
|
||||||
|
if (res.ok) {
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(user => setUser(user))
|
||||||
|
})
|
||||||
|
|
||||||
|
const [numeroGiocatori, setNumeroGiocatori] = useState(10)
|
||||||
|
const [numLupi, setNumLupi] = useState(2)
|
||||||
|
const [numFattucchiere, setNumFattucchiere] = useState(1)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<header>
|
||||||
|
<h1>
|
||||||
|
<a href="/">Lupus Lite</a>
|
||||||
|
</h1>
|
||||||
|
<h2>Crea Partita</h2>
|
||||||
|
{user && (
|
||||||
|
<div>
|
||||||
|
(Accesso eseguito come <b>{user.username}</b>)
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</header>
|
||||||
|
<hr />
|
||||||
|
<form action="/api/crea-partita" method="post">
|
||||||
|
<h2 className="fill-row">Nuova Partita</h2>
|
||||||
|
<p class="fill-row">
|
||||||
|
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Esse ipsam quisquam
|
||||||
|
laborum nemo at dignissimos excepturi sapiente incidunt enim fuga?
|
||||||
|
</p>
|
||||||
|
<label for="numero-giocatori">Numero Giocatori</label>
|
||||||
|
<InputNumero
|
||||||
|
name="numero-giocatori"
|
||||||
|
id="numero-giocatori"
|
||||||
|
value={numeroGiocatori}
|
||||||
|
setValue={setNumeroGiocatori}
|
||||||
|
/>
|
||||||
|
<label for="numero-lupi">Numero Lupi</label>
|
||||||
|
<InputNumero
|
||||||
|
name="numero-lupi"
|
||||||
|
id="numero-lupi"
|
||||||
|
value={numLupi}
|
||||||
|
setValue={setNumLupi}
|
||||||
|
/>
|
||||||
|
<label for="numero-fattucchiere">Numero Fattucchiere</label>
|
||||||
|
<InputNumero
|
||||||
|
name="numero-fattucchiere"
|
||||||
|
id="numero-fattucchiere"
|
||||||
|
value={numFattucchiere}
|
||||||
|
setValue={setNumFattucchiere}
|
||||||
|
/>
|
||||||
|
<label for="numero-lupi">Numero Lupi</label>
|
||||||
|
<InputNumero
|
||||||
|
name="numero-lupi"
|
||||||
|
id="numero-lupi"
|
||||||
|
value={numLupi}
|
||||||
|
setValue={setNumLupi}
|
||||||
|
/>
|
||||||
|
<label for="numero-lupi">Numero Lupi</label>
|
||||||
|
<InputNumero
|
||||||
|
name="numero-lupi"
|
||||||
|
id="numero-lupi"
|
||||||
|
value={numLupi}
|
||||||
|
setValue={setNumLupi}
|
||||||
|
/>
|
||||||
|
<button class="fill-row">Crea Partita</button>
|
||||||
|
</form>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render(<App />, document.querySelector('main'))
|
@ -0,0 +1,45 @@
|
|||||||
|
console.log('Home has just come lines of JS')
|
||||||
|
|
||||||
|
const $showUser = document.getElementById('show-user')
|
||||||
|
const $showUsername = document.getElementById('show-username')
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load user if logged
|
||||||
|
//
|
||||||
|
|
||||||
|
let user = null
|
||||||
|
|
||||||
|
const req = await fetch('/api/user')
|
||||||
|
if (req.ok) {
|
||||||
|
user = await req.json()
|
||||||
|
|
||||||
|
$showUser.classList.toggle('hidden', false)
|
||||||
|
$showUsername.textContent = user.username
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLogged = !!user
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logged / Not Logged Pages
|
||||||
|
//
|
||||||
|
|
||||||
|
document.querySelectorAll('.if-not-logged').forEach($el => {
|
||||||
|
$el.classList.toggle('hidden', isLogged)
|
||||||
|
})
|
||||||
|
|
||||||
|
document.querySelectorAll('.if-logged').forEach($el => {
|
||||||
|
$el.classList.toggle('hidden', !isLogged)
|
||||||
|
})
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logout Button
|
||||||
|
//
|
||||||
|
|
||||||
|
const $btnLogout = document.getElementById('btn-logout')
|
||||||
|
$btnLogout.addEventListener('click', () => {
|
||||||
|
fetch('/api/logout', { method: 'POST' }).then(res => {
|
||||||
|
if (res.ok) {
|
||||||
|
location.href = '/'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func validateUsername(username string) error {
|
||||||
|
if !IsWhitespaceFree(username) {
|
||||||
|
return fmt.Errorf(`username cannot contain spaces`)
|
||||||
|
}
|
||||||
|
if len(username) < 4 {
|
||||||
|
return fmt.Errorf(`username too short`)
|
||||||
|
}
|
||||||
|
if len(username) > 1000 {
|
||||||
|
return fmt.Errorf(`username too long`)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validatePasswords(password, password2 string) error {
|
||||||
|
if password != password2 {
|
||||||
|
return fmt.Errorf(`the two password fields don't match`)
|
||||||
|
}
|
||||||
|
if len(password) == 0 {
|
||||||
|
return fmt.Errorf(`password cannot be empty`)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue