use tailwind for frontpage

This commit is contained in:
evanpelle
2025-01-27 10:01:09 -08:00
committed by Evan
parent 348a4a611a
commit 633e93f21b
5 changed files with 85 additions and 379 deletions
+25 -44
View File
@@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit';
import { LitElement, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { Lobby } from "../core/Schemas";
import { Difficulty, GameMapType, GameType } from '../core/game/Game';
@@ -11,37 +11,9 @@ export class PublicLobby extends LitElement {
private lobbiesInterval: number | null = null;
private currLobby: Lobby = null;
static styles = css`
.lobby-button {
width: 100%;
max-width: 25rem;
margin: 0 auto;
padding: 0.75rem;
background: linear-gradient(to right, #2563eb, #3b82f6);
color: white;
font-weight: 500;
border-radius: 0.5rem;
transition: opacity 0.2s;
}
.lobby-button:hover {
opacity: 0.9;
}
.lobby-button.highlighted {
background: linear-gradient(to right, #16a34a, #22c55e);
}
.lobby-name {
font-size: 1rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.lobby-info {
display: flex;
justify-content: center;
gap: 1rem;
color: rgb(219 234 254);
font-size: 0.875rem;
}
`;
createRenderRoot() {
return this;
}
connectedCallback() {
super.connectedCallback();
@@ -83,19 +55,28 @@ export class PublicLobby extends LitElement {
const lobby = this.lobbies[0];
const timeRemaining = Math.max(0, Math.floor(lobby.msUntilStart / 1000));
// return html`
// <div class="bg-blue-500 p-4 rounded-lg text-white hover:bg-blue-600">
// Test Tailwind
// </div>
// `;
return html`
<button
@click=${() => this.lobbyClicked(lobby)}
class="lobby-button ${this.isLobbyHighlighted ? 'highlighted' : ''}"
>
<div class="lobby-name">Next Public Game</div>
<div class="lobby-info">
<div>Starts in: ${timeRemaining}s</div>
<div>Players: ${lobby.numClients}</div>
<div>ID: ${lobby.id}</div>
</div>
</button>
`;
<button
@click=${() => this.lobbyClicked(lobby)}
class="w-full max-w-3xl mx-auto py-3 px-4 md:py-6 md:px-8 ${this.isLobbyHighlighted
? 'bg-gradient-to-r from-green-600 to-green-500'
: 'bg-gradient-to-r from-blue-600 to-blue-500'
} text-white font-medium rounded-xl transition-opacity duration-200 hover:opacity-90"
>
<div class="text-xl md:text-2xl font-semibold mb-4">Next Game</div>
<div class="flex justify-center gap-8 text-blue-100 text-m md:text-lg">
<div>Starts in: ${timeRemaining}s</div>
<div>Players: ${lobby.numClients}</div>
<div>ID: ${lobby.id}</div>
</div>
</button>
`;
}
private lobbyClicked(lobby: Lobby) {
+10 -35
View File
@@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit';
import { LitElement, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { v4 as uuidv4 } from 'uuid';
import { MAX_USERNAME_LENGTH, validateUsername } from '../core/validations/username';
@@ -9,37 +9,14 @@ const usernameKey: string = 'username';
export class UsernameInput extends LitElement {
@state() private username: string = '';
@property({ type: String }) validationError: string = '';
private _isValid: boolean = true;
private _isValid: boolean = true
// Remove static styles since we're using Tailwind
static styles = css`
input {
width: 15rem;
padding: .5rem;
background-color: white;
border: 1px solid #d1d5db;
border-radius: 0.375rem;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
font-size: 1rem;
line-height: 1.5;
color: #111827;
text-align: center;
}
input:focus {
outline: none;
ring: 2px;
ring-color: #3b82f6;
border-color: #3b82f6;
}
.error {
color: #dc2626;
background-color: #fff;
padding: 4px;
font-size: 0.875rem;
border: 1px solid #dc2626;
margin-top: 0.5rem;
}
`;
createRenderRoot() {
// Disable shadow DOM to allow Tailwind classes to work
return this;
}
public getCurrentUsername(): string {
return this.username;
@@ -60,9 +37,10 @@ export class UsernameInput extends LitElement {
@change=${this.handleChange}
placeholder="Enter your username"
maxlength="${MAX_USERNAME_LENGTH}"
class="w-72 px-4 py-2 bg-white border border-gray-300 rounded-xl shadow-sm text-2xl text-gray-900 text-center focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
${this.validationError
? html`<div class="error">${this.validationError}</div>`
? html`<div class="mt-2 px-3 py-1 text-lg text-red-600 bg-white border border-red-600 rounded">${this.validationError}</div>`
: null}
`;
}
@@ -70,8 +48,6 @@ export class UsernameInput extends LitElement {
private handleChange(e: Event) {
const input = e.target as HTMLInputElement;
this.username = input.value.trim();
const result = validateUsername(this.username)
this._isValid = result.isValid
if (result.isValid) {
@@ -119,7 +95,6 @@ export class UsernameInput extends LitElement {
}
public isValid(): boolean {
return true
return this._isValid
return this._isValid;
}
}
@@ -172,6 +172,11 @@ export class Leaderboard extends LitElement implements Layer {
private _hidden = true;
render() {
// return html`
// <div class="bg-blue-500 p-4 rounded-lg text-white hover:bg-blue-600">
// Test Tailwind
// </div>
// `;
return html`
<div class="leaderboard ${this._hidden ? 'hidden' : ''}">
<table>
+45 -47
View File
@@ -1,21 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenFront (ALPHA)</title>
<script src="https://cdn.tailwindcss.com"></script>
<!-- Google tag (gtag.js) -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=AW-16702609763"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
<html lang="en" class="h-full">
<head>
<meta charset="UTF-8">
@@ -28,49 +12,64 @@
gtag('js', new Date());
gtag('config', 'AW-16702609763');
</script>
<style>
body {
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease;
}
</style>
</head>
<body>
<div class="content">
<h1><img src="../../resources/images/OpenFrontLogo.svg" alt="OpenFront.io"></h1>
<h3 class="version">(v0.14.0)</h3>
<body
class="h-full overflow-hidden select-none font-sans min-h-screen bg-opacity-0 bg-cover bg-center bg-fixed transition-opacity duration-300 ease-in-out invisible opacity-0">
<!-- Main container with responsive padding -->
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-4 sm:py-6 lg:py-8">
<!-- Logo section with responsive scaling -->
<img src="../../resources/images/OpenFrontLogo.svg" alt="OpenFront.io"
class="h-auto w-1/2 lg:w-1/4 mx-auto transform sm:scale-125 md:scale-150 lg:scale-175">
<username-input></username-input>
<!-- Version text scales with screen size -->
<h3 class="font-sans text-center text-black pb-4 text-sm sm:text-base lg:text-lg">(v0.14.0)</h3>
<div class="lobby-section">
<div class="p-2 flex items-center justify-center min-h-full w-full">
<username-input></username-input>
</div>
<!-- Public lobby section with responsive spacing -->
<div class="w-full pb-4 p-2 flex items-center justify-center min-h-full">
<public-lobby></public-lobby>
</div>
<div class="button-container">
<button id="single-player" class="primary-button">Single Player</button>
<div style="display: flex; flex-direction: column; gap: 1rem; flex: 1;">
<button id="host-lobby-button" class="secondary-button">Create Lobby</button>
<button id="join-private-lobby-button" class="secondary-button">Join Lobby</button>
<!-- Button container with responsive width and spacing -->
<div
class="flex flex-col sm:flex-row gap-4 sm:gap-6 lg:gap-8 max-w-sm sm:max-w-md lg:max-w-lg xl:max-w-xl mx-auto">
<!-- Single Player button -->
<button id="single-player" class="bg-blue-600 hover:bg-blue-700 text-white p-3 sm:p-4 lg:p-5
font-bold text-lg sm:text-xl lg:text-2xl rounded-lg
flex-1 border-none cursor-pointer transition-colors duration-300">
Single Player
</button>
<!-- Secondary buttons container -->
<div class="flex flex-col gap-3 sm:gap-4 lg:gap-5 flex-1">
<button id="host-lobby-button" class="bg-blue-100 hover:bg-blue-200 text-blue-900
p-3 sm:p-4 lg:p-5 font-medium
text-sm sm:text-base lg:text-lg rounded-md w-full
border-none cursor-pointer transition-colors duration-300">
Create Lobby
</button>
<button id="join-private-lobby-button" class="bg-blue-100 hover:bg-blue-200 text-blue-900
p-3 sm:p-4 lg:p-5 font-medium
text-sm sm:text-base lg:text-lg rounded-md w-full
border-none cursor-pointer transition-colors duration-300">
Join Lobby
</button>
</div>
</div>
<!-- <a href="https://youtu.be/jvHEvbko3uw?si=znspkP84P76B1w5I" class="link-button green" target="_blank" rel="noopener noreferrer">
How to Play
</a>
<a href="https://discord.gg/k22YrnAzGp" class="link-button purple" target="_blank" rel="noopener noreferrer">
Join the Discord!
</a> -->
</div>
<div id="customMenu">
<!-- Game components with appropriate spacing -->
<div id="customMenu" class="mt-4 sm:mt-6 lg:mt-8">
<ul></ul>
</div>
<div id="app"></div>
<div id="radialMenu" class="radial-menu"></div>
<!-- Game modals and overlays -->
<single-player-modal></single-player-modal>
<host-lobby-modal></host-lobby-modal>
<join-private-lobby-modal></join-private-lobby-modal>
@@ -83,13 +82,12 @@
<player-info-overlay></player-info-overlay>
<win-modal></win-modal>
<!-- Scripts -->
<script>
window.addEventListener('DOMContentLoaded', (event) => {
document.body.style.visibility = 'visible';
document.body.style.opacity = 1;
document.body.classList.remove('invisible', 'opacity-0');
});
</script>
<script defer src='https://static.cloudflareinsights.com/beacon.min.js'
data-cf-beacon='{"token": "03d93e6fefb349c28ee69b408fa25a13"}'></script>
</body>
-253
View File
@@ -1,256 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
html,
body {
touch-action: manipulation;
-ms-touch-action: manipulation;
height: 100%;
overflow: hidden;
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@font-face {
font-family: 'Overpass';
src: url('/resources/fonts/overpass.woff') format('woff');
font-weight: normal;
font-style: normal;
}
body {
font-family: 'Overpass', sans-serif;
margin: 0;
padding: 0;
min-height: 100vh;
background-color: #15151500;
background-size: cover;
background-position: center;
background-attachment: fixed;
background-blend-mode: overlay;
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease;
}
.content {
text-align: center;
padding: 20px;
max-width: 100%;
margin: 0 auto;
position: relative;
}
body {
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease;
background: rgba(45, 45, 51, 0.173);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(8px);
min-height: 100vh;
margin: 0;
}
/* Typography */
h1 {
font-family: Arial, serif;
text-align: center;
color: #2e2e2e;
font-size: 3em;
margin: 1em 0 10px;
}
h1 img {
height: auto;
width: auto;
max-width: 100%;
transform: scale(2);
}
h2 {
font-family: Arial, serif;
text-align: center;
color: #2e2e2e;
font-size: 1.5em;
margin-bottom: 50px;
}
h3 {
font-family: Arial, serif;
text-align: center;
color: #000000;
}
.version {
font-family: Arial, serif;
text-align: center;
color: #000000;
font-size: 1em;
}
/* Username input */
#username-container {
margin-bottom: 50px;
display: flex;
justify-content: center;
}
#username {
width: 90%;
max-width: 500px;
padding: 10px;
font-size: 16px;
text-align: center;
border: 2px solid #007bff;
border-radius: 5px;
background-color: rgba(255, 255, 255, 0.8);
margin: 1em auto;
display: block;
}
/* Buttons */
.button-container {
display: flex;
gap: 1rem;
max-width: 20rem;
max-height: 10rem;
margin: 0 auto;
}
.primary-button {
background-color: #2563eb;
color: white;
padding: 1rem 1rem;
font-weight: bold;
font-size: 1.25rem;
border-radius: 0.5rem;
flex: 1;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
.secondary-button {
background-color: #dbeafe;
color: #1e40af;
padding: 1rem;
font-weight: 500;
font-size: 0.875rem;
border-radius: 0.375rem;
width: 100%;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
.link-button {
display: block;
max-width: 400px;
margin: 1rem auto;
padding: 0.5rem 1rem;
text-align: center;
text-decoration: none;
font-weight: bold;
border-radius: 0.375rem;
transition: background-color 0.3s;
}
.link-button.green {
background-color: #059669;
color: white;
}
.link-button.purple {
background-color: #4f46e5;
color: white;
}
/* Discord */
.discord-link {
position: fixed;
top: 20px;
right: 20px;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
background-color: #5865F2;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.discord-link:hover {
background-color: #4752C4;
}
.discord-logo {
width: 30px;
height: 30px;
}
/* Media Queries */
@media (min-width: 768px) {
h1 {
font-size: 2em;
}
h3 {
font-size: 1em;
}
.lobby-section {
padding: 1rem;
}
#username {
font-size: 24px;
}
.lobby-container {
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
width: 100%;
padding: 1rem;
}
.lobby-button {
width: 50rem;
display: block;
margin: 0 auto;
}
.lobby-name {
font-size: 36px;
}
.lobby-timer,
.player-count {
font-size: 24px;
}
.discord-link {
top: 50px;
right: 50px;
width: 70px;
height: 70px;
}
.discord-logo {
width: 40px;
height: 40px;
}
}