diff --git a/package.json b/package.json
index 883bcb0..60af171 100644
--- a/package.json
+++ b/package.json
@@ -13,13 +13,13 @@
"preview": "vite preview"
},
"dependencies": {
- "@capacitor/camera": "latest",
- "@capacitor/core": "latest",
+ "@capacitor/camera": "^7.0.2",
+ "@capacitor/core": "^7.4.4",
"@capacitor/geolocation": "^7.1.5",
"@capacitor/google-maps": "^7.2.0",
"@capacitor/haptics": "^7.0.3",
"@capacitor/ios": "^7.4.4",
- "@capacitor/splash-screen": "latest"
+ "@capacitor/splash-screen": "^7.0.3"
},
"devDependencies": {
"@capacitor/cli": "latest",
diff --git a/src/_/code/shared.css b/src/_/code/shared.css
index 014dde8..7e16cf5 100644
--- a/src/_/code/shared.css
+++ b/src/_/code/shared.css
@@ -14,14 +14,23 @@
--darkgrey: #5c4646;
--home-src: /_/icons/home.svg;
- --home-selected-src: /_/icons/homeselected.svg;
+ --home-selected-src: /_/icons/homelightselected.svg;
--people-src: /_/icons/people.svg;
- --people-selected-src: /_/icons/peopleselected.svg;
+ --people-selected-src: /_/icons/peoplelightselected.svg;
+ --settings-src: /_/icons/settings.svg;
+ --settings-selected-src: /_/icons/settingslightselected.svg;
+ --events-src: /_/icons/events.svg;
+ --events-selected-src: /_/icons/eventslightselected.svg;
+ --jobs-src: /_/icons/jobs.svg;
+ --jobs-selected-src: /_/icons/jobslightselected.svg;
--column-src: /_/icons/column2.svg;
--nodes-src: /_/icons/nodes.svg;
--forum-src: /_/icons/forum.svg;
+ --pin-src: /_/icons/pin.svg;
+ --time-src: /_/icons/time.svg;
+
--top-inset: env(safe-area-inset-top, 0px);
--bottom-inset: env(safe-area-inset-bottom, 0px);
}
@@ -37,10 +46,19 @@
--home-selected-src: /_/icons/homelightselected.svg;
--people-src: /_/icons/peoplelight.svg;
--people-selected-src: /_/icons/peoplelightselected.svg;
+ --settings-src: /_/icons/settingslight.svg;
+ --settings-selected-src: /_/icons/settingslightselected.svg;
+ --events-src: /_/icons/eventslight.svg;
+ --events-selected-src: /_/icons/eventslightselected.svg;
+ --jobs-src: /_/icons/jobslight.svg;
+ --jobs-selected-src: /_/icons/jobslightselected.svg;
--column-src: /_/icons/column2.svg;
--nodes-src: /_/icons/nodes.svg;
--forum-src: /_/icons/forum.svg;
+
+ --pin-src: /_/icons/pinlight.svg;
+ --time-src: /_/icons/timelight.svg;
}
}
diff --git a/src/_/icons/events.svg b/src/_/icons/events.svg
new file mode 100644
index 0000000..bf3ce43
--- /dev/null
+++ b/src/_/icons/events.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/eventslight.svg b/src/_/icons/eventslight.svg
new file mode 100644
index 0000000..61be66a
--- /dev/null
+++ b/src/_/icons/eventslight.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/eventslightselected.svg b/src/_/icons/eventslightselected.svg
new file mode 100644
index 0000000..616ea25
--- /dev/null
+++ b/src/_/icons/eventslightselected.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/home.svg b/src/_/icons/home.svg
new file mode 100644
index 0000000..c7d0035
--- /dev/null
+++ b/src/_/icons/home.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/_/icons/homelightselected.svg b/src/_/icons/homelightselected.svg
index a948cfa..788ae2f 100644
--- a/src/_/icons/homelightselected.svg
+++ b/src/_/icons/homelightselected.svg
@@ -1,5 +1 @@
-
+
\ No newline at end of file
diff --git a/src/_/icons/jobslight.svg b/src/_/icons/jobslight.svg
new file mode 100644
index 0000000..16c87ed
--- /dev/null
+++ b/src/_/icons/jobslight.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/_/icons/jobslightselected.svg b/src/_/icons/jobslightselected.svg
new file mode 100644
index 0000000..14887f7
--- /dev/null
+++ b/src/_/icons/jobslightselected.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/_/icons/logowhite.svg b/src/_/icons/logowhite.svg
new file mode 100644
index 0000000..e6278eb
--- /dev/null
+++ b/src/_/icons/logowhite.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/_/icons/pin.svg b/src/_/icons/pin.svg
new file mode 100644
index 0000000..e662f1d
--- /dev/null
+++ b/src/_/icons/pin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/_/icons/pinlight.svg b/src/_/icons/pinlight.svg
new file mode 100644
index 0000000..a4b91eb
--- /dev/null
+++ b/src/_/icons/pinlight.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/_/icons/settings.svg b/src/_/icons/settings.svg
new file mode 100644
index 0000000..90ed89e
--- /dev/null
+++ b/src/_/icons/settings.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/settingslight.svg b/src/_/icons/settingslight.svg
new file mode 100644
index 0000000..4e082ee
--- /dev/null
+++ b/src/_/icons/settingslight.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/settingslightselected.svg b/src/_/icons/settingslightselected.svg
new file mode 100644
index 0000000..0a845e1
--- /dev/null
+++ b/src/_/icons/settingslightselected.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/time.svg b/src/_/icons/time.svg
new file mode 100644
index 0000000..30a9b5b
--- /dev/null
+++ b/src/_/icons/time.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/_/icons/timelight.svg b/src/_/icons/timelight.svg
new file mode 100644
index 0000000..615be77
--- /dev/null
+++ b/src/_/icons/timelight.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/apps/Events/EventCard.js b/src/apps/Events/EventCard.js
new file mode 100644
index 0000000..f94fc85
--- /dev/null
+++ b/src/apps/Events/EventCard.js
@@ -0,0 +1,72 @@
+import util from "../../util"
+
+class EventCard extends Shadow {
+ constructor(event) {
+ super()
+ this.event = event
+ }
+
+ render() {
+ VStack(() => {
+ h3(this.event.title)
+ .color("var(--brown)")
+ .fontSize(1.2, em)
+ .fontWeight("bold")
+ .marginVertical(0, em)
+
+ HStack(() => {
+ img(util.cssVariable("pin-src"), "1.3em")
+ p(this.event.location)
+ })
+ .gap(0.3, em)
+ .verticalAlign("center")
+
+ HStack(() => {
+ img(util.cssVariable("time-src"), "1.2em")
+ p(this.convertDate(this.event.time))
+ })
+ .gap(0.4, em)
+ .verticalAlign("center")
+
+ p("Description: " + " " + this.event.description)
+ })
+ .maxHeight(12.5, em)
+ .padding(0.75, em)
+ .gap(0, em)
+ .borderBottom("1px solid var(--divider)")
+ .verticalAlign("center")
+ .gap(0.5, em)
+ }
+
+ convertDate(rawDate) {
+ const parsed = new Date(rawDate);
+
+ if (isNaN(parsed.getTime())) return rawDate;
+
+ const month = parsed.toLocaleString("en-US", { month: "long", timeZone: "UTC" });
+ const day = parsed.getUTCDate();
+ const year = parsed.getUTCFullYear();
+
+ const hours24 = parsed.getUTCHours();
+ const minutes = parsed.getUTCMinutes();
+
+ const hours12 = hours24 % 12 || 12;
+ const ampm = hours24 >= 12 ? "PM" : "AM";
+ const paddedMinutes = String(minutes).padStart(2, "0");
+
+ 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 `${month} ${ordinal(day)}, ${year} at ${hours12}:${paddedMinutes} ${ampm}`;
+ }
+}
+
+register(EventCard)
\ No newline at end of file
diff --git a/src/apps/Events/Events.js b/src/apps/Events/Events.js
new file mode 100644
index 0000000..ac1203d
--- /dev/null
+++ b/src/apps/Events/Events.js
@@ -0,0 +1,124 @@
+import "../../components/LoadingCircle.js"
+import "./EventCard.js"
+
+css(`
+ events- {
+ font-family: 'Arial';
+ }
+
+ events- h1 {
+ font-family: 'Bona';
+ }
+
+ events- p {
+ color: var(--accent);
+ }
+
+ events- p b {
+ color: var(--darkbrown);
+ }
+`)
+
+class Events extends Shadow {
+ events = [
+ {
+ title: "Austin Chapter Lead",
+ description: "This is the descriptio lets try a longer one agaiin just to see what it would look like? mayeb even longer bc that was pretty short now that i see it. maybe 2 sentences if possible or more.",
+ location: "1234 location",
+ time: "2026-01-13 13:41:41.0722"
+ }
+ ]
+
+ constructor() {
+ super()
+ // this.events = global.currentNetwork.data.events;
+ }
+
+ render() {
+ VStack(() => {
+ h1("Events")
+ .color("var(--quillred)")
+ .textAlign("center")
+ .marginBottom(0)
+ h3(global.currentNetwork.name)
+ .color("var(--quillred)")
+ .textAlign("center")
+ .margin(0)
+ .fontFamily("Bona")
+
+ input("Search (coming soon!)", "80%")
+ .attr({
+ "type": "text",
+ "disabled": "true"
+ })
+ .paddingVertical(0.75, em)
+ .boxSizing("border-box")
+ .paddingHorizontal(1, em)
+ .color("var(--accent)")
+ .background("#fff1dd")
+ .marginTop(0.25, em)
+ .marginBottom(0.5, em)
+ .border("1px solid black")
+ .borderRadius(100, px)
+ .fontFamily("Arial")
+ .fontSize(1, em)
+ .outline("none")
+ .cursor("not-allowed")
+
+ if (this.events == "") {
+ LoadingCircle()
+ } else if (this.events.length > 0) {
+ for (let i = 0; i < this.events.length; i++) {
+ EventCard(this.events[i])
+ .borderTop(i == 0 ? "1px solid var(--divider)" : "")
+ }
+ } else {
+ h2("No Events")
+ .color("var(--brown)")
+ .fontWeight("bold")
+ .marginTop(7.5, em)
+ .marginBottom(0.5, em)
+ .textAlign("center")
+ }
+ })
+ .position("relative")
+ .boxSizing("border-box")
+ .paddingVertical(1, em)
+ .horizontalAlign("center")
+ .gap(0.5, em)
+ .height(100, pct)
+ .width(100, pct)
+ }
+
+ convertDate(rawDate) {
+ const parsed = new Date(rawDate);
+
+ if (isNaN(parsed.getTime())) return rawDate;
+
+ const month = parsed.toLocaleString("en-US", { month: "long", timeZone: "UTC" });
+ const day = parsed.getUTCDate();
+ const year = parsed.getUTCFullYear();
+
+ const hours24 = parsed.getUTCHours();
+ const minutes = parsed.getUTCMinutes();
+
+ const hours12 = hours24 % 12 || 12;
+ const ampm = hours24 >= 12 ? "PM" : "AM";
+ const paddedMinutes = String(minutes).padStart(2, "0");
+
+ 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 `${month} ${ordinal(day)}, ${year} at ${hours12}:${paddedMinutes} ${ampm}`;
+ }
+}
+
+register(Events)
\ No newline at end of file
diff --git a/src/apps/Jobs/JobCard.js b/src/apps/Jobs/JobCard.js
new file mode 100644
index 0000000..c94e2f1
--- /dev/null
+++ b/src/apps/Jobs/JobCard.js
@@ -0,0 +1,39 @@
+import util from "../../util.js"
+
+class JobCard extends Shadow {
+ constructor(job) {
+ super()
+ this.job = job
+ }
+
+ render() {
+ VStack(() => {
+ h3(this.job.title)
+ .color("var(--brown)")
+ .fontSize(1.2, em)
+ .fontWeight("bold")
+ .marginVertical(0, em)
+
+ HStack(() => {
+ img(util.cssVariable("pin-src"), "1.3em")
+ p(this.job.location)
+ })
+ .gap(0.3, em)
+ .verticalAlign("center")
+
+ p("Company: " + " " + this.job.company)
+ p("Salary: " + " " + this.job.salary)
+ p("Description: " + " " + this.job.description)
+ })
+ .width(100, pct)
+ .maxHeight(12.5, em)
+ .padding(0.75, em)
+ .gap(0, em)
+ .borderBottom("1px solid var(--divider)")
+ .textAlign("left")
+ .gap(0.5, em)
+ .boxSizing("border-box")
+ }
+}
+
+register(JobCard)
\ No newline at end of file
diff --git a/src/apps/Jobs/Jobs.js b/src/apps/Jobs/Jobs.js
index bb72598..ace77b0 100644
--- a/src/apps/Jobs/Jobs.js
+++ b/src/apps/Jobs/Jobs.js
@@ -1,27 +1,22 @@
import "./JobsSidebar.js"
import "./JobsGrid.js"
+import "./JobCard.js"
css(`
jobs- {
+ font-family: 'Arial';
+ }
+
+ jobs- h1 {
font-family: 'Bona';
}
- jobs- input::placeholder {
- font-family: 'Bona Nova';
- font-size: 0.9em;
+ jobs- p {
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);
+ jobs- p b {
+ color: var(--darkbrown);
}
`)
@@ -29,72 +24,66 @@ class Jobs extends Shadow {
jobs = [
{
title: "Austin Chapter Lead",
+ description: "This is the description",
salary: "1% of Local Revenue",
company: "Hyperia",
- city: "Austin",
- state: "TX"
+ location: "1234 location"
}
]
render() {
- ZStack(() => {
- HStack(() => {
- JobsSidebar()
-
- JobsGrid(this.jobs)
- })
- .width(100, "%")
- .x(0).y(13, vh)
+ VStack(() => {
+ h1("Jobs")
+ .color("var(--quillred)")
+ .textAlign("center")
+ .marginBottom(0.25, em)
+ h3(global.currentNetwork.name)
+ .color("var(--quillred)")
+ .textAlign("center")
+ .margin(0)
+ .fontFamily("Bona")
- HStack(() => {
- input("Search jobs... (Coming Soon!)", "45vw")
- .attr({
- "type": "text",
- "disabled": "true"
- })
- .fontSize(1.1, em)
- .paddingLeft(1.3, em)
- .background("transparent")
- .border("0.5px solid var(--divider)")
- .outline("none")
- .color("var(--accent)")
- .opacity(0.5)
- .borderRadius(10, px)
- .background("grey")
- .cursor("not-allowed")
+ input("Search (coming soon!)", "80%")
+ .attr({
+ "type": "text",
+ "disabled": "true"
+ })
+ .paddingVertical(0.75, em)
+ .boxSizing("border-box")
+ .paddingHorizontal(1, em)
+ .color("var(--accent)")
+ .background("#fff1dd")
+ .marginTop(0.75, em)
+ .marginBottom(1, em)
+ .border("1px solid black")
+ .borderRadius(100, px)
+ .fontFamily("Arial")
+ .fontSize(1, em)
+ .outline("none")
+ .cursor("not-allowed")
- button("+ Add Job")
- .width(7, em)
- .marginLeft(1, em)
- .borderRadius(10, px)
- .background("transparent")
- .border("0.3px solid var(--accent2)")
- .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%)")
+ if (this.jobs == "") {
+ LoadingCircle()
+ } else if (this.jobs.length > 0) {
+ for (let i = 0; i < this.jobs.length; i++) {
+ JobCard(this.jobs[i])
+ .borderTop(i == 0 ? "1px solid var(--divider)" : "")
+ }
+ } else {
+ h2("No Jobs")
+ .color("var(--brown)")
+ .fontWeight("bold")
+ .marginTop(7.5, em)
+ .marginBottom(0.5, em)
+ .textAlign("center")
+ }
})
- .width(100, "%")
- .height(100, "%")
- }
-
- connectedCallback() {
- // Optional additional logic
+ .position("relative")
+ .boxSizing("border-box")
+ .paddingVertical(1, em)
+ .horizontalAlign("center")
+ .height(100, pct)
+ .width(100, pct)
}
}
diff --git a/src/apps/People/People.js b/src/apps/People/People.js
index f42f180..d030d80 100644
--- a/src/apps/People/People.js
+++ b/src/apps/People/People.js
@@ -29,6 +29,13 @@ class People extends Shadow {
h1("People")
.color("var(--quillred)")
.textAlign("center")
+ .marginBottom(0.25, em)
+ h3(global.currentNetwork.name)
+ .color("var(--quillred)")
+ .textAlign("center")
+ .margin(0)
+ .marginBottom(0.5, em)
+ .fontFamily("Bona")
if (this.people == "") {
LoadingCircle()
@@ -45,7 +52,7 @@ class People extends Shadow {
.background("var(--bone)")
VStack(() => {
- h3(this.people[i].firstName + " " + this.people[i].lastName)
+ h3(this.people[i].first_name + " " + this.people[i].last_name)
.color("var(--brown)")
.fontSize(1.2, em)
.fontWeight("bold")
@@ -81,13 +88,13 @@ class People extends Shadow {
}
convertDate(rawDate) {
- const date = rawDate.split("-", 1)[0]; // "01.31.2026
- const [mm, dd, yyyy] = date.split(".").map(Number);
+ const parsed = new Date(rawDate);
- const months = [
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
- ];
+ if (isNaN(parsed.getTime())) return rawDate;
+
+ const month = parsed.toLocaleString("en-US", { month: "long", timeZone: "UTC" });
+ const day = parsed.getUTCDate();
+ const year = parsed.getUTCFullYear();
const ordinal = (n) => {
const mod100 = n % 100;
@@ -100,7 +107,7 @@ class People extends Shadow {
}
};
- return `${months[mm - 1]} ${ordinal(dd)}, ${yyyy}`;
+ return `${month} ${ordinal(day)}, ${year}`;
}
}
diff --git a/src/components/AppMenu.js b/src/components/AppMenu.js
index 32e328e..025750b 100644
--- a/src/components/AppMenu.js
+++ b/src/components/AppMenu.js
@@ -5,14 +5,22 @@ class AppMenu extends Shadow {
selected = ""
images = {
- "Dashboard": {src: "home-src"},
- "Messages": {src: "letter-src"},
- "People": {src: "people-src"}
+ "Dashboard": {src: ["home-src", "home-selected-src"]},
+ "People": {src: ["people-src", "people-selected-src"]},
+ "Settings": {src: ["settings-src", "settings-selected-src"]},
+ "Events": {src: ["events-src", "events-selected-src"]},
+ "Jobs": {src: ["jobs-src", "jobs-selected-src"]}
}
onNewSelection() {
this.$$("img").forEach((image) => {
image.style.borderBottom = "1px solid transparent"
+ const app = image.attributes.app.value
+ if (app === global.currentApp()) {
+ image.src = util.cssVariable(this.images[app].src[1])
+ } else {
+ image.src = util.cssVariable(this.images[app].src[0])
+ }
})
}
@@ -22,16 +30,16 @@ class AppMenu extends Shadow {
let currentNetwork = global.currentNetwork
for(let i = 0; i < currentNetwork.apps.length; i++) {
let app = currentNetwork.apps[i]
- console.log(app)
- img(util.cssVariable(this.images[app].src), "1.3em")
+ if (app === "Settings") continue;
+ img(util.cssVariable(global.currentApp() === app ? this.images[app].src[1] : this.images[app].src[0]), "1.3em")
.attr({app: app})
.padding(0.5, em)
.borderBottom(global.currentApp() === app ? "1px solid var(--text)" : "1px solid transparent")
.onTouch(async (done, e) => {
if(done) {
- this.onNewSelection()
e.target.style.borderBottom = "1px solid var(--text)"
global.openApp(app)
+ this.onNewSelection()
await Haptics.impact({ style: ImpactStyle.Light });
}
})
diff --git a/src/components/AppWindow.js b/src/components/AppWindow.js
index cd6850c..6b1e9f8 100644
--- a/src/components/AppWindow.js
+++ b/src/components/AppWindow.js
@@ -2,6 +2,7 @@ import "../apps/Forum/Forum.js"
import "../apps/Messages/Messages.js"
import "../apps/Jobs/Jobs.js"
import "../apps/People/People.js"
+import "../apps/Events/Events.js"
class AppWindow extends Shadow {
render() {
@@ -19,6 +20,14 @@ class AppWindow extends Shadow {
case "People":
People()
break;
+
+ case "Jobs":
+ Jobs()
+ break;
+
+ case "Events":
+ Events()
+ break;
}
})
.height(100, pct)