class SignupForm extends Shadow { errorMessage = "Error signing up. Please try again later or email info@hyperia.so if the problem persists." successMessage = "Success! You may now log in." inputStyles(el) { return el .border("1px solid var(--accent)") } render() { ZStack(() => { form(() => { VStack(() => { p() .attr({id: "signupMessage"}) .display("none") .padding(1, em) .color("var(--main)") .background("var(--accent)") HStack(() => { VStack(() => { input("First Name") .attr({name: "firstName", type: "name"}) .styles(this.inputStyles) input("Last Name") .attr({name: "lastName", type: "name"}) .styles(this.inputStyles) input("Email") .attr({name: "email", type: "email"}) .styles(this.inputStyles) input("Password") .attr({name: "password", type: "password"}) .styles(this.inputStyles) input("Confirm Password") .attr({name: "password", type: "password"}) .styles(this.inputStyles) }) .width(50, "%") .gap(1, em) VStack(() => { input("Street Address") .attr({ name: "address1", type: "text", autocomplete: "address-line1" }) .styles(this.inputStyles) input("Apt, Suite, Unit (optional)") .attr({ name: "address2", type: "text", autocomplete: "address-line2" }) .styles(this.inputStyles) input("City") .attr({ name: "city", type: "text", autocomplete: "address-level2" }) .styles(this.inputStyles) input("State") .attr({ name: "state", type: "text", autocomplete: "address-level1" }) .styles(this.inputStyles) input("ZIP Code") .attr({ name: "zip", type: "text", autocomplete: "postal-code" }) .styles(this.inputStyles) input("Country") .attr({ name: "country", type: "text", autocomplete: "country-name" }) .styles(this.inputStyles) }) .width(50, "%") .gap(1, em) }) .gap(2, em) button("Submit") }) .gap(2, em) }) .onSubmit(async (e) => { e.preventDefault() console.log("submitting") $("#signupMessage").style.display = "none" const formData = new FormData(this.$("form")); const data = Object.fromEntries(formData.entries()); let newMember = { "email": data.email, "firstName": data.firstName, "lastName": data.lastName, "password": data.password } let address = { "address1": data.address1, "address2": data.address2, "zip": data.zip, "state": data.state, "city": data.city } newMember.address = address try { const response = await fetch(window.location.pathname + window.location.search, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newMember) }); if (!response.ok) { $("#signupMessage").style.display = "block" $("#signupMessage").innerText = this.errorMessage throw new Error(`HTTP error! status: ${response.status}`); } else { $("#signupMessage").style.display = "block" $("#signupMessage").innerText = this.successMessage } } catch (err) { console.error("Fetch error:", err); } }) .x(50, vw).y(53, vh) .width(60, vw) .center() }) } } register(SignupForm)