diff options
| author | Pinapelz <yukais@pinapelz.com> | 2026-06-05 11:23:34 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2026-06-05 11:23:34 -0700 |
| commit | 95d56dd94153cf464ada2c9bbbe840a3da14f98a (patch) | |
| tree | 9967f18d5f0a6f0f189078f0fa05929bd234980f /templates | |
init commit
Diffstat (limited to 'templates')
| -rw-r--r-- | templates/add.html | 86 | ||||
| -rw-r--r-- | templates/index.html | 341 |
2 files changed, 427 insertions, 0 deletions
diff --git a/templates/add.html b/templates/add.html new file mode 100644 index 0000000..193cfd6 --- /dev/null +++ b/templates/add.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<html> +<head> + <title>Add Steam Game</title> +</head> + +<body> + <h1>Add Steam Game</h1> + + <form id="addForm"> + <div> + <label>Steam App ID:</label><br> + <input type="number" id="steam_id" required> + </div> + + <br> + + <div> + <label>Password:</label><br> + <input type="password" id="password" required> + </div> + + <br> + + <button type="submit">Add Game</button> + </form> + + <pre id="result"></pre> + + <script> + const form = document.getElementById("addForm"); + + const passwordInput = document.getElementById("password"); + const result = document.getElementById("result"); + + // Load saved password from localStorage + const savedPassword = localStorage.getItem("addFormPassword"); + if (savedPassword) { + passwordInput.value = savedPassword; + } + + // Save password to localStorage as user types + passwordInput.addEventListener("input", () => { + localStorage.setItem("addFormPassword", passwordInput.value); + }); + + form.addEventListener("submit", async (e) => { + e.preventDefault(); + + const steamId = document.getElementById("steam_id").value; + const password = passwordInput.value; // Use the input element's current value + + // Clear previous results + result.textContent = ""; + + try { + const res = await fetch(`/api/steam/${steamId}`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ password }) + }); + + const data = await res.json(); + + if (!res.ok) { // Check if response status is not OK (e.g., 401, 500) + throw new Error(data.error || `HTTP error! status: ${res.status}`); + } + + // Success case + result.textContent = `Success! Game added:\n${JSON.stringify(data, null, 2)}`; + // Optionally clear form fields on success + // document.getElementById("steam_id").value = ""; + // passwordInput.value = ""; // Keep password if user wants to add more + // localStorage.removeItem("addFormPassword"); // Or remove password on success if desired + + } catch (error) { + // Error case + result.textContent = `Error: ${error.message}`; + console.error("Error adding game:", error); + } + }); + </script> +</body> +</html> diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..88b9ca9 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,341 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Games</title> + + <style> + * { + box-sizing: border-box; + border-radius: 0px; + + --cl-black: hsl(140, 1%, 6%); + --cl-gray-0: hsl(140, 2%, 8%); + --cl-gray-1: hsl(140, 2%, 12%); + --cl-gray-2: hsl(140, 4%, 16%); + --cl-gray-3: hsl(140, 4%, 24%); + --cl-gray-4: hsl(140, 4%, 36%); + --cl-gray-5: hsl(140, 4%, 44%); + --cl-gray-6: hsl(80, 8%, 52%); + --cl-gray-7: hsl(70, 8%, 58%); + --cl-gray-8: hsl(60, 16%, 66%); + --cl-gray-9: hsl(40, 32%, 78%); + --cl-gray-10: hsl(30, 32%, 84%); + --cl-white: hsl(26, 64%, 88%); + --cl-red-6: hsl(4, 83%, 67%); + --cl-red-7: hsl(4, 75%, 75%); + --cl-orange-6: hsl(26, 84%, 62%); + --cl-orange-7: hsl(26, 84%, 74%); + --cl-yellow: hsl(37, 80%, 69%); + --cl-green-6: hsl(120, 41%, 64%); + --cl-green-7: hsl(120, 42%, 75%); + --cl-cyan-6: hsl(160, 41%, 64%); + --cl-cyan-7: hsl(160, 32%, 75%); + --cl-blue-6: hsl(200, 55%, 64%); + --cl-blue-8: hsl(201, 55%, 80%); + --cl-magenta-7: hsl(320, 59%, 72%); + --cl-magenta-8: hsl(320, 61%, 80%); + } + + body { + margin: 5vh 10vw; + font-family: "Roboto Mono", monospace; + background-color: var(--cl-gray-0); + color: var(--cl-white); + } + + h1 { + margin-top: 0; + color: var(--cl-blue-6); + } + + .tabs { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 20px; + } + + .tab { + background: var(--cl-gray-2); + color: var(--cl-white); + border: 1px solid var(--cl-gray-4); + padding: 10px 16px; + cursor: pointer; + font-family: inherit; + transition: background 0.15s; + } + + .tab:hover { + background: var(--cl-gray-3); + } + + .tab.active { + background: var(--cl-blue-6); + color: var(--cl-black); + font-weight: bold; + } + + .table-container { + overflow-x: auto; + background: var(--cl-gray-1); + border: 1px solid var(--cl-gray-3); + } + + table { + width: 100%; + border-collapse: collapse; + } + + th, + td { + padding: 12px; + border-bottom: 1px solid var(--cl-gray-3); + text-align: left; + vertical-align: top; + } + + th { + background: var(--cl-gray-2); + color: var(--cl-yellow); + position: sticky; + top: 0; + cursor: pointer; + user-select: none; + font-weight: 600; + } + + th:hover { + background: var(--cl-gray-3); + color: var(--cl-orange-7); + } + + tr:hover { + background: var(--cl-gray-2); + } + + img { + width: 240px; + display: block; + border: 1px solid var(--cl-gray-3); + } + + .description { + white-space: normal; + line-height: 1.5; + min-width: 400px; + } + + a:link { + color: var(--cl-orange-6); + text-decoration: none; + } + + a:visited, + a:active { + color: var(--cl-green-6); + } + + a:hover { + color: var(--cl-magenta-7); + text-decoration: underline; + } + + .played-true { + color: var(--cl-green-6); + font-weight: bold; + } + + .played-false { + color: var(--cl-red-6); + font-weight: bold; + } + + .sort-indicator { + margin-left: 4px; + color: var(--cl-cyan-6); + font-size: 0.8em; + } + </style> +</head> +<body> + +<h1>LIST OF CONSIDERATIONS</h1> + +<div id="tabs" class="tabs"> + <button class="tab active" onclick="filterCategory('all', this)"> + All + </button> + + {% for type in games | map(attribute='type') | unique | sort %} + <button class="tab" onclick="filterCategory('{{ type }}', this)"> + {{ type }} + </button> + {% endfor %} +</div> + +<div class="table-container"> +<table id="gamesTable"> + <thead> + <tr> + <th>Image</th> + + <th onclick="sortTable(1)"> + Name + <span class="sort-indicator" id="sort-1"></span> + </th> + + <th onclick="sortTable(2)"> + Type + <span class="sort-indicator" id="sort-2"></span> + </th> + + <th onclick="sortTable(3)"> + Watch/Played + <span class="sort-indicator" id="sort-3"></span> + </th> + + <th>Description</th> + <th>Notes</th> + <th>Link</th> + </tr> + </thead> + + <tbody> + {% for game in games %} + <tr data-type="{{ game.type }}"> + <td> + {% if game.image %} + <img src="{{ game.image }}" alt="{{ game.name }}"> + {% else %} + <img src="https://files.catbox.moe/7wvr9k.jpg" + alt="Default Game Image"> + {% endif %} + </td> + + <td>{{ game.name }}</td> + + <td>{{ game.type }}</td> + + <td> + <span class="played-{{ game.played|string|lower }}"> + {{ game.played }} + </span> + </td> + + <td class="description"> + {{ game.description }} + </td> + + <td> + {{ game.notes }} + </td> + + <td> + {% if game.url %} + <a href="{{ game.url }}" target="_blank"> + Store Page + </a> + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> +</table> +</div> + +<script> +const sortState = {}; + +function sortTable(columnIndex) { + const table = document.getElementById("gamesTable"); + const tbody = table.querySelector("tbody"); + + const rows = Array.from( + tbody.querySelectorAll("tr") + ); + + sortState[columnIndex] = + !sortState[columnIndex]; + + const ascending = + sortState[columnIndex]; + + document + .querySelectorAll(".sort-indicator") + .forEach(el => el.textContent = ""); + + document.getElementById( + `sort-${columnIndex}` + ).textContent = ascending ? "▲" : "▼"; + + rows.sort((a, b) => { + let aVal = + a.children[columnIndex] + .innerText + .trim(); + + let bVal = + b.children[columnIndex] + .innerText + .trim(); + + if ( + aVal.toLowerCase() === "true" || + aVal.toLowerCase() === "false" + ) { + aVal = + aVal.toLowerCase() === "true" + ? 1 + : 0; + + bVal = + bVal.toLowerCase() === "true" + ? 1 + : 0; + + return ascending + ? aVal - bVal + : bVal - aVal; + } + + return ascending + ? aVal.localeCompare(bVal) + : bVal.localeCompare(aVal); + }); + + rows.forEach(row => + tbody.appendChild(row) + ); +} + +function filterCategory(category, button) { + const rows = + document.querySelectorAll( + "#gamesTable tbody tr" + ); + + rows.forEach(row => { + const rowType = + row.dataset.type; + + row.style.display = + category === "all" || + rowType === category + ? "" + : "none"; + }); + + document + .querySelectorAll(".tab") + .forEach(tab => + tab.classList.remove("active") + ); + + button.classList.add("active"); +} +</script> + +</body> +</html> |
