import server from "../_/code/bridge/serverFunctions"; css(` profile- textarea::-webkit-scrollbar { display: none; width: 0px; height: 0px; } profile- textarea::-webkit-scrollbar-thumb { background: transparent; } profile- textarea::-webkit-scrollbar-track { background: transparent; } `) class Profile extends Shadow { constructor() { super() this.profile = global.profile this.bioText = global.profile.bio ?? "" } render() { ZStack(() => { p("< Back") .color("var(--darkred)") .fontSize(1.5, em) .position("absolute") .fontFamily("Arial") .top(2, rem) .left(2, rem) .zIndex(1001) .onClick(() => { $("appwindowcontainer-").closeProfile() }) form(() => { VStack(() => { HStack(() => { }) // Profile Image placeholder .boxSizing("border-box") .height(10, em) .width(10, em) .paddingHorizontal(0.5, em) .border("1px solid var(--accent)") .borderRadius(100, pct) .background("var(--darkaccent)") h1(this.profile.first_name + " " + this.profile.last_name) .color("var(--headertext") .width(70, pct) .textAlign("center") .marginBottom(0.25, em) p("Joined " + this.convertDate(this.profile.created)) .color("var(--headertext)") .marginBottom(0.5, em) h2("Bio") .color("var(--headertext") .margin(0) .paddingVertical(0.9, em) .borderTop("2px solid var(--divider)") .width(70, pct) .textAlign("center") textarea(this.bioText ? this.bioText : "Tap to start typing...") .attr({ name: "bioinput" }) .padding(1, em) .width(90, pct) .height(15, em) .boxSizing("border-box") .background("var(--searchbackground)") .color("var(--darktext)") .border("1px solid color-mix(in srgb, var(--accent) 60%, transparent)") .borderRadius(12, px) .fontFamily("Arial") .fontSize(1.1, em) .outline("none") .onAppear((e) => { if (this.bioText) { $("profile- textarea").innerText = this.bioText } }) .lineHeight(1.2, em) button("Save Bio") .padding(1, em) .fontSize(1.1, em) .borderRadius(12, px) .background("var(--searchbackground)") .color("var(--text)") .border("1px solid var(--accent)") .boxSizing("border-box") .marginVertical(0.75, em) }) .horizontalAlign("center") .marginTop(5, em) }) .onSubmit(async (e) => { e.preventDefault(); const newBio = new FormData(e.target).get("bioinput"); if (newBio.trim() !== this.profile.bio.trim()) { const result = await server.editBio(newBio, this.profile.id) const { bio, updated_at } = result.data global.profile.bio = bio global.profile.updated_at = updated_at this.profile = global.profile } }) }) .backgroundColor("var(--main)") .overflowX("hidden") .height(window.visualViewport.height - 20, px) .boxSizing("border-box") .width(100, pct) .position("fixed") .top(100, vh) .zIndex(5) .transition("top .3s") .pointerEvents("none") } 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 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}`; } } register(Profile)