heavylifting

breaking the trend to say that i fully let AI do the work here im not touching Shit

lowk idek how this thing works. There was an initial different style for the paste pad,

 but idk man thats what you get for AI works. you dont know everything.
 You dont need to.
This commit is contained in:
lda committed 2025-12-19 00:49:27 +07:00
1 parent 57a73e9c17
commit 107e880cf8
16 files changed
+907 -334

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100dvh;
box-sizing: border-box;
}
a {
color: var(--primary-color);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
+201
View File
@@ -0,0 +1,201 @@
/* Buttons */
button,
input[type="submit"],
.btn {
background-color: var(--surface-color);
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 10px 20px;
border-radius: var(--border-radius);
cursor: pointer;
font-size: 1rem;
transition: background-color 0.2s, color 0.2s;
margin: 5px;
display: inline-block;
text-align: center;
text-decoration: none;
}
button:hover,
input[type="submit"]:hover,
.btn:hover {
background-color: var(--primary-color);
color: var(--bg-color);
text-decoration: none;
}
.btn-sm {
padding: 5px 10px;
font-size: 0.8rem;
}
.btn-danger {
border-color: var(--error-color);
color: var(--error-color);
}
.btn-danger:hover {
background-color: var(--error-color);
color: white;
}
.btn-secondary {
border-color: #666;
color: #aaa;
}
/* Forms */
textarea {
background-color: var(--surface-color);
color: var(--text-color);
border: 1px solid #333;
border-radius: var(--border-radius);
padding: 10px;
width: 100%;
/* max-width: 800px; Removed global max-width */
font-family: monospace;
min-width: 20%;
min-height: 20dvh;
box-sizing: border-box; /* Ensure padding doesn't break width */
}
form {
display: flex;
flex-direction: column;
/* align-items: center; Removed global alignment */
width: 100%;
/* max-width: 800px; Removed global max-width */
gap: 10px;
}
.form-control {
width: 100%;
padding: 10px;
background: #333;
color: white;
border: 1px solid #444;
border-radius: var(--border-radius);
box-sizing: border-box;
}
textarea.form-control {
min-height: 150px;
resize: vertical;
}
.disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Cards */
.card {
background-color: var(--surface-color);
padding: 30px;
border-radius: var(--border-radius);
flex: 1;
min-width: 300px;
display: flex;
flex-direction: column;
/* align-items: center; Removed to allow full width content */
text-align: center;
border: 1px solid #333;
overflow-y: auto;
}
.card h2 {
color: var(--secondary-color);
margin-top: 0;
}
.card p {
margin-bottom: 15px;
color: #aaa;
}
.card .actions {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
/* Navbar */
.navbar {
width: 100%;
background-color: var(--surface-color);
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
box-sizing: border-box;
}
.nav-brand {
font-size: 1.5rem;
font-weight: bold;
color: var(--primary-color);
}
.nav-links a {
margin-left: 1.5rem;
color: var(--text-color);
}
.nav-links a:hover {
color: var(--primary-color);
}
/* Lists */
/* Generic list styles can go here if needed */
/* Details/Summary */
details {
width: 100%;
/* max-width: 600px; Removed global max-width */
margin-top: 20px;
background-color: var(--surface-color);
border-radius: var(--border-radius);
border: 1px solid #333;
}
summary {
padding: 15px;
cursor: pointer;
font-weight: bold;
color: var(--secondary-color);
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
}
summary::after {
content: "+";
font-size: 1.2rem;
}
details[open] summary::after {
content: "-";
}
details[open] summary {
border-bottom: 1px solid #333;
}
summary::marker,
summary::-webkit-details-marker {
list-style-type: none;
display: none;
}
/* Misc */
.qrcode {
margin-top: 10px;
margin-inline: auto;
background-color: white;
padding: 10px;
border-radius: 4px;
width: fit-content;
}
+9
View File
@@ -0,0 +1,9 @@
.hero {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
width: 100%;
max-width: 1000px;
margin-bottom: 20px;
}
+52
View File
@@ -0,0 +1,52 @@
.pastepad-container {
width: 100%;
max-width: 1000px; /* Increased from 800px */
display: flex;
flex-direction: column;
gap: 20px;
}
.editor {
display: flex;
flex-direction: column;
gap: 10px;
}
.editor-actions {
display: flex;
gap: 10px;
}
.paste-list {
display: flex;
flex-direction: column;
gap: 15px;
}
.paste-item {
background: var(--surface-color);
padding: 15px;
border-radius: var(--border-radius);
text-align: left; /* Override card's center alignment */
}
.paste-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
border-bottom: 1px solid #333;
padding-bottom: 10px;
width: 100%; /* Ensure full width */
}
.paste-item pre {
background: #111;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
margin: 0;
white-space: pre-wrap;
width: 100%; /* Ensure full width */
box-sizing: border-box;
}
+67
View File
@@ -0,0 +1,67 @@
.route-list {
display: grid;
gap: 10px;
width: 800px;
padding: 15px;
box-sizing: border-box;
}
.route-item {
background-color: var(--surface-color);
padding: 15px;
border-radius: var(--border-radius);
display: flex;
justify-content: space-between;
align-items: center;
font-family: monospace;
gap: 2em;
}
.queue-title {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 800px;
margin-bottom: 20px;
}
.queue-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
align-items: flex-start;
width: 800px;
padding-inline: 0;
}
.queue-grid li {
flex: 1 1 300px;
max-width: 400px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
/* Visual styles moved from components.css */
background-color: var(--surface-color);
margin-bottom: 10px;
padding: 15px;
border-radius: var(--border-radius);
word-break: break-all;
}
.queue-grid li a {
align-items: center;
word-break: break-word;
}
/* Specific override for the queue input form */
.queue-form {
max-width: 800px;
margin: 0 auto;
}
.queue-form textarea {
resize: vertical;
}
+5
View File
@@ -0,0 +1,5 @@
.reader-btn {
font-size: 1.5rem;
padding: 20px 40px;
margin-top: 20px;
}
+21
View File
@@ -0,0 +1,21 @@
.trail-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80dvh;
width: 100%;
cursor: pointer;
text-align: center;
}
.trail-count {
font-size: 5rem;
font-weight: bold;
color: var(--secondary-color);
}
.trail-hint {
color: #666;
margin-top: 20px;
}
+9
View File
@@ -0,0 +1,9 @@
:root {
--bg-color: #121212;
--text-color: #e0e0e0;
--primary-color: #bb86fc;
--secondary-color: #03dac6;
--error-color: #cf6679;
--surface-color: #1e1e1e;
--border-radius: 8px;
}
+198
View File
@@ -0,0 +1,198 @@
document.addEventListener("DOMContentLoaded", () => {
// --- DOM Elements ---
const elements = {
nameInput: document.getElementById("n"),
contentInput: document.getElementById("pc"),
saveBtn: document.getElementById("s"),
listDiv: document.getElementById("list"),
};
// --- State Management ---
const state = {
isEditMode: false,
};
// --- API Interactions ---
const api = {
async getPastes() {
const res = await fetch("/api/pastepad");
if (!res.ok) throw new Error("Failed to fetch pastes");
return res.json();
},
async getPaste(name) {
const res = await fetch(`/api/pastepad/${name}`);
if (!res.ok) throw new Error("Failed to fetch paste");
return res.json();
},
async createPaste(payload) {
const res = await fetch("/api/pastepad", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.detail || "Failed to create paste");
}
return res.json();
},
async updatePaste(name, payload) {
const res = await fetch(`/api/pastepad/${name}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.detail || "Failed to update paste");
}
return res.json();
},
async deletePaste(name) {
const res = await fetch(`/api/pastepad/${name}`, { method: "DELETE" });
if (!res.ok) throw new Error("Failed to delete paste");
},
};
// --- UI Functions ---
function escapeHtml(text) {
if (!text) return text;
return text
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
function renderPasteItem(p) {
const safeName = escapeHtml(p.name);
const safeContent = escapeHtml(p.content);
return `
<div class="paste-item card">
<div class="paste-header">
<strong>${safeName}</strong>
<div class="actions">
<button onclick="editPaste('${safeName}')" class="btn-sm">Edit</button>
<a href="/api/pastepad/${safeName}/raw" target="_blank" class="btn-sm">Raw</a>
<button onclick="deletePaste('${safeName}')" class="btn-sm btn-danger">Delete</button>
</div>
</div>
<pre>${safeContent}</pre>
</div>
`;
}
async function loadPastes() {
try {
const pastes = await api.getPastes();
elements.listDiv.innerHTML = pastes.map(renderPasteItem).join("");
} catch (e) {
console.error(e);
elements.listDiv.innerHTML = `<p style="color: var(--error-color)">Error loading pastes: ${e.message}</p>`;
}
}
function setEditMode(isEdit) {
state.isEditMode = isEdit;
const { nameInput, contentInput, saveBtn } = elements;
if (isEdit) {
nameInput.readOnly = true;
nameInput.classList.add("disabled");
saveBtn.textContent = "Update Paste";
saveBtn.dataset.mode = "update";
if (!document.getElementById("cancelBtn")) {
const cancelBtn = document.createElement("button");
cancelBtn.id = "cancelBtn";
cancelBtn.textContent = "Cancel";
cancelBtn.className = "btn btn-secondary";
cancelBtn.onclick = resetForm;
saveBtn.after(cancelBtn);
}
} else {
nameInput.value = "";
contentInput.value = "";
nameInput.readOnly = false;
nameInput.classList.remove("disabled");
saveBtn.textContent = "Save Paste";
saveBtn.dataset.mode = "create";
const c = document.getElementById("cancelBtn");
if (c) c.remove();
}
}
function resetForm() {
setEditMode(false);
const url = new URL(window.location);
url.searchParams.delete("name");
window.history.pushState({}, "", url);
}
async function handleSave() {
const content = elements.contentInput.value;
if (!content) return;
const name = elements.nameInput.value;
const payload = { content };
if (name) payload.name = name;
try {
if (state.isEditMode) {
await api.updatePaste(name, payload);
} else {
await api.createPaste(payload);
}
resetForm();
loadPastes();
} catch (e) {
alert("Error: " + e.message);
}
}
// --- Initialization & Event Listeners ---
elements.saveBtn.addEventListener("click", handleSave);
// Global handlers for inline onclicks
window.editPaste = async (name) => {
const url = new URL(window.location);
url.searchParams.set("name", name);
window.history.pushState({}, "", url);
try {
const data = await api.getPaste(name);
elements.nameInput.value = data.name;
elements.contentInput.value = data.content;
setEditMode(true);
window.scrollTo({ top: 0, behavior: "smooth" });
} catch (e) {
console.error(e);
alert("Could not load paste for editing");
}
};
window.deletePaste = async (name) => {
if (!confirm("Delete " + name + "?")) return;
try {
await api.deletePaste(name);
loadPastes();
if (elements.nameInput.value === name) resetForm();
} catch (e) {
alert("Error deleting paste: " + e.message);
}
};
// Check URL for edit mode on load
const params = new URLSearchParams(window.location.search);
const nameToEdit = params.get("name");
if (nameToEdit) {
window.editPaste(nameToEdit);
}
loadPastes();
});
+8 -262
View File
@@ -1,262 +1,8 @@
:root {
--bg-color: #121212;
--text-color: #e0e0e0;
--primary-color: #bb86fc;
--secondary-color: #03dac6;
--error-color: #cf6679;
--surface-color: #1e1e1e;
--border-radius: 8px;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100dvh;
box-sizing: border-box; /* Ensure padding is included in width/height */
}
a {
color: var(--primary-color);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
button,
input[type="submit"],
.btn {
background-color: var(--surface-color);
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 10px 20px;
border-radius: var(--border-radius);
cursor: pointer;
font-size: 1rem;
transition: background-color 0.2s, color 0.2s;
margin: 5px;
display: inline-block;
text-align: center;
text-decoration: none;
}
button:hover,
input[type="submit"]:hover,
.btn:hover {
background-color: var(--primary-color);
color: var(--bg-color);
text-decoration: none;
}
textarea {
background-color: var(--surface-color);
color: var(--text-color);
border: 1px solid #333;
border-radius: var(--border-radius);
padding: 10px;
width: 100%;
max-width: 800px;
font-family: monospace;
min-width: 20%;
min-height: 20dvh;
}
form {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
max-width: 800px;
gap: 10px;
}
ol {
list-style: none;
padding: 0;
width: 100%;
max-width: 800px;
}
li {
background-color: var(--surface-color);
margin-bottom: 10px;
padding: 15px;
border-radius: var(--border-radius);
word-break: break-all;
width: min-content;
}
li a {
display: flex;
flex-direction: column;
gap: 10px;
}
.qrcode {
margin-top: 10px;
background-color: white;
padding: 10px;
border-radius: 4px;
width: fit-content;
}
/* Specifics for reader */
.reader-btn {
font-size: 1.5rem;
padding: 20px 40px;
margin-top: 20px;
}
/* Specifics for index */
.hero {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
width: 100%;
max-width: 1000px;
margin-bottom: 20px;
}
.card {
background-color: var(--surface-color);
padding: 30px;
border-radius: var(--border-radius);
flex: 1;
min-width: 300px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
border: 1px solid #333;
/* max-height: 90dvh; Prevent card from exceeding viewport height */
overflow-y: auto; /* Scroll if content is too tall */
}
.card h2 {
color: var(--secondary-color);
margin-top: 0;
/* margin-bottom: 10px; Reduced margin */
/* font-size: 1.2rem; Slightly smaller title */
}
.card p {
margin-bottom: 15px; /* Reduced margin */
color: #aaa;
}
.card .actions {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
details {
width: 100%;
max-width: 600px;
margin-top: 20px;
background-color: var(--surface-color);
border-radius: var(--border-radius);
border: 1px solid #333;
}
summary {
padding: 15px;
cursor: pointer;
font-weight: bold;
color: var(--secondary-color);
list-style: none; /* Hide default triangle */
display: flex;
justify-content: space-between;
align-items: center;
}
summary::after {
content: "+";
font-size: 1.2rem;
}
details[open] summary::after {
content: "-";
}
details[open] summary {
border-bottom: 1px solid #333;
}
summary::marker,
summary::-webkit-details-marker {
list-style-type: none;
display: none;
}
.route-list {
display: grid;
gap: 10px;
width: 100%;
padding: 15px;
box-sizing: border-box;
}
.route-item {
background-color: var(--surface-color);
padding: 15px;
border-radius: var(--border-radius);
display: flex;
justify-content: space-between;
align-items: center;
font-family: monospace;
}
/* Queue Grid */
.queue-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
width: 100%;
}
.queue-grid li {
flex: 1 1 300px; /* Grow, shrink, basis */
max-width: 400px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.queue-grid li a {
align-items: center;
word-break: break-word;
}
/* Trail Page */
.trail-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80dvh;
width: 100%;
cursor: pointer;
text-align: center;
}
.trail-count {
font-size: 5rem;
font-weight: bold;
color: var(--secondary-color);
}
.trail-hint {
color: #666;
margin-top: 20px;
}
@import "css/variables.css";
@import "css/base.css";
@import "css/components.css";
@import "css/pages/index.css";
@import "css/pages/queue.css";
@import "css/pages/trail.css";
@import "css/pages/pastepad.css";
@import "css/pages/reader.css";