1, 4: Fixing 404 after logged out, adding market entry

This commit is contained in:
metacryst
2025-11-10 04:05:21 -06:00
parent 6f9ed49b2e
commit 41c0bb57a3
16 changed files with 494 additions and 136 deletions

178
ui/site/apps/Forum/Forum.js Normal file
View File

@@ -0,0 +1,178 @@
css(`
messages- {
font-family: 'Bona';
}
messages- input::placeholder {
font-family: 'Bona Nova';
font-size: 0.9em;
color: var(--accent);
}
input[type="checkbox"] {
appearance: none; /* remove default style */
-webkit-appearance: none;
width: 1em;
height: 1em;
border: 1px solid var(--accent);
}
input[type="checkbox"]:checked {
background-color: var(--red);
}
`)
class Messages extends Shadow {
friends = []
conversations = []
render() {
ZStack(() => {
HStack(() => {
VStack(() => {
h3("Friends")
.marginTop(0)
.marginBottom(1, em)
.marginLeft(0.4, em)
if (this.friends.length > 1) {
for(let i = 0; i < this.friends.length; i++) {
p(this.friends[i].name)
}
} else {
p("No Friends!")
}
})
.height(100, vh)
.paddingLeft(2, em)
.paddingRight(2, em)
.paddingTop(2, em)
.gap(0, em)
.borderRight("1px solid var(--periwinkle)")
VStack(() => {
h3("Conversations")
.marginTop(0)
.marginBottom(1, em)
.marginLeft(0.4, em)
if (this.conversations.length > 1) {
for(let i = 0; i < this.conversations.length; i++) {
p(this.conversations[i].name)
}
} else {
p("No Conversations!")
}
})
.height(100, vh)
.paddingLeft(2, em)
.paddingRight(2, em)
.paddingTop(2, em)
.gap(0, em)
.borderRight("1px solid var(--periwinkle)")
})
.width(100, "%")
.x(0).y(13, vh)
.borderTop("1px solid var(--periwinkle)")
p("0 Items")
.position("absolute")
.x(50, vw).y(50, vh)
.transform("translate(-50%, -50%)")
HStack(() => {
input("Search messages...", "45vw")
.attr({
"type": "text"
})
.fontSize(1.1, em)
.paddingLeft(1.3, em)
.background("transparent")
.border("1px solid var(--periwinkle)")
.outline("none")
.color("var(--accent)")
.borderRadius(10, px)
button("Search")
.marginLeft(2, em)
.borderRadius(10, px)
.background("transparent")
.border("1px solid var(--periwinkle)")
.color("var(--accent)")
.fontFamily("Bona Nova")
.onHover(function (hovering) {
if(hovering) {
this.style.background = "var(--green)"
} else {
this.style.background = "transparent"
}
})
button("+ New Message")
.width(13, em)
.marginLeft(1, em)
.borderRadius(10, px)
.background("transparent")
.border("1px solid var(--periwinkle)")
.color("var(--accent)")
.fontFamily("Bona Nova")
.onHover(function (hovering) {
if(hovering) {
this.style.background = "var(--green)"
} else {
this.style.background = "transparent"
}
})
.onClick((clicking) => {
console.log(this, "clicked")
})
})
.x(55, vw).y(4, vh)
.position("absolute")
.transform("translateX(-50%)")
})
.width(100, "%")
.height(100, "%")
}
SidebarName(name) {
let firstLetter = name[0]
HStack(() => {
div(firstLetter)
.display("flex")
.justifyContent("center")
.alignItems("center")
.width(1.5, em)
.height(1.5, em)
.border("1px solid var(--periwinkle)")
.borderRadius(100, "%")
p(name)
.marginLeft(1, em)
})
.alignItems("center")
.padding(5, px)
.borderRadius(0.5, em)
.cursor("default")
.onHover(function (hovering) {
if(hovering) {
this.style.background = "var(--green)"
} else {
this.style.background = "transparent"
}
})
}
connectedCallback() {
// Optional additional logic
}
}
register(Messages)

View File

@@ -29,12 +29,17 @@ class Jobs extends Shadow {
jobs = [
{
title: "Austin Chapter Lead",
salary: "1% of Local Tax Revenue",
location: "Austin"
salary: "1% of Local Revenue",
company: "Hyperia",
city: "Austin",
state: "TX"
},
{
title: "San Marcos Chapter Lead",
salary: "1% of Local Tax Revenue"
salary: "1% of Local Revenue",
company: "Hyperia",
city: "San Marcos",
state: "TX"
}
]

View File

@@ -6,10 +6,19 @@ class JobsGrid extends Shadow {
this.jobs = jobs
}
boldUntilFirstSpace(text) {
const index = text.indexOf(' ');
if (index === -1) {
// No spaces — bold the whole thing
return `<b>${text}</b>`;
}
return `<b>${text.slice(0, index)}</b>${text.slice(index)}`;
}
render() {
VStack(() => {
h3("Results")
.marginTop(0)
.marginTop(0.1, em)
.marginBottom(1, em)
.marginLeft(0.4, em)
.color("var(--periwinkle)")
@@ -17,14 +26,23 @@ class JobsGrid extends Shadow {
if (this.jobs.length > 0) {
ZStack(() => {
for (let i = 0; i < this.jobs.length; i++) {
p(this.jobs[i].title)
.border("1px solid var(--periwinkle)")
.padding(1, em)
.borderRadius(5, "px")
}
VStack(() => {
p(this.jobs[i].title)
.fontSize(1.2, em)
.fontWeight("bold")
.marginBottom(0.5, em)
p(this.jobs[i].company)
p(this.jobs[i].city + ", " + this.jobs[i].state)
.marginBottom(0.5, em)
p(this.boldUntilFirstSpace(this.jobs[i].salary))
})
.padding(1, em)
.border("1px solid var(--periwinkle)")
.borderRadius(5, "px")
}
})
.display("grid")
.gridTemplateColumns("repeat(auto-fill, minmax(200px, 1fr))")
.gridTemplateColumns("repeat(auto-fill, minmax(250px, 1fr))")
.gap(1, em)
} else {
p("No Jobs!")

View File

@@ -2,6 +2,7 @@ class JobsSidebar extends Shadow {
render() {
VStack(() => {
h3("Location")
.color("var(--periwinkle)")
})

View File

@@ -1,3 +1,6 @@
import "./MarketSidebar.js"
import "./MarketGrid.js"
css(`
market- {
font-family: 'Bona';
@@ -24,73 +27,27 @@ css(`
class Market extends Shadow {
listings = [
{
title: "Shield Lapel Pin",
stars: "5",
reviews: 1,
price: "$12",
company: "Hyperia",
type: "new",
image: "/db/images/1"
}
]
render() {
ZStack(() => {
HStack(() => {
VStack(() => {
MarketSidebar()
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "hyperia-check"
})
label("Hyperia-Made")
.attr({
"for": "hyperia-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "america-check"
})
label("America-Made")
.attr({
"for": "america-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "new-check"
})
label("New")
.attr({
"for": "new-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "used-check"
})
label("Used")
.attr({
"for": "used-check"
})
.marginLeft(0.5, em)
})
})
.paddingLeft(3, em)
.gap(1, em)
MarketGrid(this.listings)
})
.width(100, "%")
.x(0).y(25, vh)
p("0 Items")
.position("absolute")
.x(50, vw).y(50, vh)
.transform("translate(-50%, -50%)")
.x(0).y(13, vh)
HStack(() => {
input("Search for products...", "45vw")

View File

@@ -0,0 +1,100 @@
class MarketGrid extends Shadow {
listings;
constructor(listings) {
super()
this.listings = listings
}
boldUntilFirstSpace(text) {
if(!text) return
const index = text.indexOf(' ');
if (index === -1) {
// No spaces — bold the whole thing
return `<b>${text}</b>`;
}
return `<b>${text.slice(0, index)}</b>${text.slice(index)}`;
}
render() {
VStack(() => {
h3("Results")
.marginTop(0.1, em)
.marginBottom(1, em)
.marginLeft(0.4, em)
.color("var(--periwinkle)")
if (this.listings.length > 0) {
ZStack(() => {
for (let i = 0; i < this.listings.length; i++) {
const rating = this.listings[i].stars
const percent = (rating / 5)
VStack(() => {
img(this.listings[i].image)
.marginBottom(0.5, em)
p(this.listings[i].company)
.marginBottom(0.5, em)
p(this.listings[i].title)
.fontSize(1.2, em)
.fontWeight("bold")
.marginBottom(0.5, em)
HStack(() => {
p(this.listings[i].stars)
.marginRight(0.2, em)
ZStack(() => {
div("★★★★★") // Empty stars (background)
.color("#ccc")
div("★★★★★") // Filled stars (foreground, clipped by width)
.color("#ffa500")
.position("absolute")
.top(0)
.left(0)
.whiteSpace("nowrap")
.overflow("hidden")
.width(percent * 5, em)
})
.display("inline-block")
.position("relative")
.fontSize(1.2, em)
.lineHeight(1)
p(this.listings[i].reviews)
.marginLeft(0.2, em)
})
.marginBottom(0.5, em)
p(this.listings[i].price)
.fontSize(1.75, em)
.marginBottom(0.5, em)
button("Buy Now")
})
.padding(1, em)
.border("1px solid var(--periwinkle)")
.borderRadius(5, "px")
}
})
.display("grid")
.gridTemplateColumns("repeat(auto-fill, minmax(250px, 1fr))")
.gap(1, em)
} else {
p("No Listings!")
}
})
.height(100, vh)
.paddingLeft(2, em)
.paddingRight(2, em)
.paddingTop(2, em)
.gap(0, em)
.width(100, "%")
}
}
register(MarketGrid)

View File

@@ -0,0 +1,65 @@
class MarketSidebar extends Shadow {
render() {
VStack(() => {
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "hyperia-check"
})
label("Hyperia-Made")
.attr({
"for": "hyperia-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "america-check"
})
label("America-Made")
.attr({
"for": "america-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "new-check"
})
label("New")
.attr({
"for": "new-check"
})
.marginLeft(0.5, em)
})
HStack(() => {
input()
.attr({
"type": "checkbox",
"id": "used-check"
})
label("Used")
.attr({
"for": "used-check"
})
.marginLeft(0.5, em)
})
})
.paddingTop(12, vh)
.paddingLeft(3, em)
.paddingRight(3, em)
.gap(1, em)
.minWidth(10, vw)
.userSelect('none')
}
}
register(MarketSidebar)

View File

@@ -111,7 +111,7 @@ class Messages extends Shadow {
})
button("+ New Message")
.width(15, em)
.width(13, em)
.marginLeft(1, em)
.borderRadius(10, px)
.background("transparent")