diff --git a/src/Home/Login.js b/src/Home/Login.js new file mode 100644 index 0000000..5c65b80 --- /dev/null +++ b/src/Home/Login.js @@ -0,0 +1,61 @@ +class Login extends Shadow { + inputStyles(el) { + return el + .background("var(--main)") + .color("var(--text)") + .border("1px solid var(--accent)") + .fontSize(0.9, rem) + .backgroundColor("var(--accentdark)") + .borderRadius(12, px) + .outline("none") + .onTouch((start) => { + if(start) { + this.style.backgroundColor = "var(--accent)" + } else { + this.style.backgroundColor = "var(--accentdark)" + } + }) + } + + render() { + ZStack(() => { + img(window.matchMedia('(prefers-color-scheme: dark)') ? "/_/icons/columnwhite.svg" : "/_/icons/logo.svg", window.isMobile() ? "5vmax" : "3vmax") + .position("absolute") + .top(5, em) + .left(2, em) + .onClick((done) => { + window.navigateTo("/") + }) + + form(() => { + input("Email", "70vw") + .attr({name: "email", type: "email"}) + .margin(1, em) + .padding(1, em) + .styles(this.inputStyles) + input("Password", "70vw") + .attr({name: "password", type: "password"}) + .margin(1, em) + .padding(1, em) + .styles(this.inputStyles) + button("==>") + .margin(1, em) + .padding(1, em) + .fontSize(0.9, rem) + .borderRadius(12, px) + .background("var(--accent)") + .color("var(--text)") + .border("1px solid var(--accent)") + }) + .attr({action: "/login", method: "POST"}) + .x(50, vw).y(50, vh) + .center() + }) + .background("var(--main)") + .width(100, vw) + .height(100, pct) + .margin(0) + } +} + +register(Login) \ No newline at end of file diff --git a/src/apps/People/People.js b/src/apps/People/People.js new file mode 100644 index 0000000..abe7dfd --- /dev/null +++ b/src/apps/People/People.js @@ -0,0 +1,105 @@ +css(` + people- { + font-family: 'Arial'; + } + + people- h1 { + font-family: 'Bona'; + } + + people- p { + color: var(--accent); + } + + people- p b { + color: var(--darkbrown); + } +`) + +class People extends Shadow { + people = ""; + + constructor() { + super() + this.people = global.currentNetwork.data.members; + } + + render() { + VStack(() => { + h1("People") + .color("rgb(158 136 105)") + .textAlign("center") + + if (this.people == "") { + LoadingCircle() + } else if (this.people.length > 0) { + for (let i = 0; i < this.people.length; i++) { + HStack(() => { + HStack(() => { }) + .boxSizing("border-box") + .height(3.5, em) + .width(3.5, em) + .padding(0.5, em) + .border("1px solid var(--accent)") + .borderRadius(100, pct) + .background("black") + + VStack(() => { + h3(this.people[i].firstName + " " + this.people[i].lastName) + .color("var(--brown)") + .fontSize(1.2, em) + .fontWeight("bold") + .marginVertical(0, em) + p("Member since: " + " " + this.convertDate(this.people[i].created)) + }) + .verticalAlign("center") + .gap(0.5, em) + }) + .height(3.5, em) + .padding(0.75, em) + .gap(1, em) + } + } else { + h2("No Members") + .color("var(--brown)") + .fontWeight("bold") + .marginTop(7.5, em) + .marginBottom(0.5, em) + .textAlign("center") + p("Invite people to this network!") + .textAlign("center") + .color("var(--darkbrown)") + } + }) + .position("relative") + .boxSizing("border-box") + .paddingVertical(1, em) + .height(100, pct) + .width(100, pct) + } + + convertDate(rawDate) { + const date = rawDate.split("-", 1)[0]; // "01.31.2026 + const [mm, dd, yyyy] = date.split(".").map(Number); + + const months = [ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + ]; + + const ordinal = (n) => { + const mod100 = n % 100; + if (mod100 >= 11 && mod100 <= 13) return `${n}th`; + switch (n % 10) { + case 1: return `${n}st`; + case 2: return `${n}nd`; + case 3: return `${n}rd`; + default: return `${n}th`; + } + }; + + return `${months[mm - 1]} ${ordinal(dd)}, ${yyyy}`; + } +} + +register(People) \ No newline at end of file diff --git a/src/components/AppMenu.js b/src/components/AppMenu.js index 2f944d2..d403a81 100644 --- a/src/components/AppMenu.js +++ b/src/components/AppMenu.js @@ -7,7 +7,7 @@ class AppMenu extends Shadow { darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches getImageURL(appName) { - let imgUrl = `${util.HOST}/db/apps/${appName}/icons/${appName}` + let imgUrl = `${util.HOST}/apps/${appName}/icons/${appName}` if(this.darkMode) { imgUrl += "light" } diff --git a/src/index.js b/src/index.js index e85b3de..baab8b6 100644 --- a/src/index.js +++ b/src/index.js @@ -32,14 +32,6 @@ let Global = class { window.dispatchEvent(event) } - async fetchAppData() { - let personalSpace = this.currentNetwork === this.profile - if (personalSpace) { return {} } - let appData = await fetch(`${util.HOST}/api/${personalSpace ? "my" : "org"}data/` + this.currentNetwork.id, {method: "GET"}) - let json = await appData.json() - return json - } - onNavigate = async () => { if(!global.profile) return let selectedNetwork = this.networkFromPath() @@ -72,10 +64,6 @@ let Global = class { window.dispatchEvent(event) } - if(!this.currentNetwork?.data) { - this.currentNetwork.data = await this.fetchAppData() - } - if(appChanged && !networkChanged) { const event = new CustomEvent('appchange', { detail: { name: this.currentApp() } diff --git a/src/public/_/code/quill.js b/src/public/_/code/quill.js index ba362d0..2d6f3eb 100644 --- a/src/public/_/code/quill.js +++ b/src/public/_/code/quill.js @@ -1,6 +1,7 @@ /* Sam Russell Captured Sun + 3.29.26 - Fix attr() bug with empty or null values 3.28.26 - Stopping state() from duplicating on rerender() 3.27.26 - Adding quill router, removing dynamicText(), removing horizontal and verticalAlign() checks 3.24.26 - Allowing state() to watch other elements @@ -1343,7 +1344,7 @@ HTMLElement.prototype.attr = function(arg1, arg2) { } return this; - } else if(typeof arg1 === "string" && arg2) { + } else if(typeof arg1 === "string" && (arg2 || arg2 === "" || arg2 === null || arg2 === 0)) { this.setAttribute(arg1, arg2) return this } else if(typeof arg1 === "string") {