improving authpage

This commit is contained in:
metacryst
2026-03-24 06:07:29 -05:00
parent c5b71add07
commit a87d521a4f
3 changed files with 137 additions and 70 deletions

View File

@@ -22,8 +22,6 @@ class AuthPage extends Shadow {
}) })
} }
selectedPage = 1 // 1 == login, 2 == signup
render() { render() {
VStack(() => { VStack(() => {
img(window.matchMedia('(prefers-color-scheme: dark)').matches ? "/_/icons/columnwhite.svg" : "/_/icons/logo.svg", window.isMobile() ? "5vmax" : "3vmax") img(window.matchMedia('(prefers-color-scheme: dark)').matches ? "/_/icons/columnwhite.svg" : "/_/icons/logo.svg", window.isMobile() ? "5vmax" : "3vmax")
@@ -35,24 +33,36 @@ class AuthPage extends Shadow {
HStack(() => { HStack(() => {
p("Login") p("Login")
.fontWeight(this.selectedPage === 1 ? "bold" : "normal") .state(this, "selected", function (selected) {
.padding(0.75, em) if(selected === "1") {
.borderRadius(12, px) this.fontWeight("bold")
.background(this.selectedPage === 1 ? "var(--loginButton)" : "transparent") this.background("var(--loginButton)")
.onTap(() => { } else {
this.selectedPage = 1; this.fontWeight("normal")
this.rerender(); this.background("transparent")
}) }
})
.padding(0.75, em)
.borderRadius(12, px)
.onTap(() => {
this.attr("selected", "1")
})
p("Sign Up") p("Sign Up")
.fontWeight(this.selectedPage === 2 ? "bold" : "normal") .state(this, "selected", function (selected) {
.padding(0.75, em) if(selected === "2") {
.borderRadius(12, px) this.fontWeight("bold")
.background(this.selectedPage === 2 ? "var(--loginButton)" : "transparent") this.background("var(--loginButton)")
.onTap(() => { } else {
this.selectedPage = 2; this.fontWeight("normal")
this.rerender(); this.background("transparent")
}) }
})
.padding(0.75, em)
.borderRadius(12, px)
.onTap(() => {
this.attr("selected", "2")
})
}) })
.fontFamily("Arial") .fontFamily("Arial")
.padding(0.25, em) .padding(0.25, em)
@@ -65,16 +75,31 @@ class AuthPage extends Shadow {
.marginBottom(2, em) .marginBottom(2, em)
.gap(0.5, em) .gap(0.5, em)
switch (this.selectedPage) { ZStack(() => {
case 1:
Login() Login()
break; .state(this, "selected", function (selected) {
case 2: if(selected === "1") {
Signup() this.display("")
break; } else {
} this.display("none")
}
})
Signup()
.state(this, "selected", function (selected) {
if(selected === "2") {
this.display("")
} else {
this.display("none")
}
})
})
.attr("id", "content")
}) })
.attr("selected", "1")
.width(100, vw) .width(100, vw)
.height(100, vh) .height(100, vh)
.margin(0) .margin(0)

View File

@@ -20,8 +20,6 @@ class Signup extends Shadow {
}) })
} }
errorMessage = ""
render() { render() {
form(() => { form(() => {
VStack(() => { VStack(() => {
@@ -55,6 +53,24 @@ class Signup extends Shadow {
.marginVertical(1, em) .marginVertical(1, em)
.padding(1, em) .padding(1, em)
.styles(this.inputStyles) .styles(this.inputStyles)
p("")
.state("errormessage", function (msg) {
if(msg) {
this.display("")
this.innerText = msg
} else {
this.display("none")
this.innerText = ""
}
})
.margin("auto")
.marginTop(1, em)
.color("var(--text)")
.fontFamily("Arial")
.opacity(.7)
.padding(0.5, em)
.backgroundColor("var(--darkred)")
.display("none")
HStack(() => { HStack(() => {
button("==>") button("==>")
.padding(1, em) .padding(1, em)
@@ -64,6 +80,13 @@ class Signup extends Shadow {
.color("var(--text)") .color("var(--text)")
.border("1px solid var(--accent)") .border("1px solid var(--accent)")
.boxSizing("border-box") .boxSizing("border-box")
.onTouch(function (start) {
if (start) {
this.style.backgroundColor = "var(--accent)"
} else {
this.style.backgroundColor = "var(--searchbackground)"
}
})
}) })
.width(70, vw) .width(70, vw)
.margin("auto") .margin("auto")
@@ -71,6 +94,7 @@ class Signup extends Shadow {
.paddingLeft(0, em) .paddingLeft(0, em)
.paddingRight(2, em) .paddingRight(2, em)
.marginVertical(1, em) .marginVertical(1, em)
.marginBottom(10, em)
.border("1px solid transparent") .border("1px solid transparent")
}) })
}) })
@@ -105,8 +129,7 @@ class Signup extends Shadow {
global.renderHome(); global.renderHome();
} else { } else {
const { error } = await res.json(); const { error } = await res.json();
this.errorMessage = error; console.error(error)
console.error(this.errorMessage)
} }
} }
@@ -118,60 +141,62 @@ class Signup extends Shadow {
const confirmPassword = data.get("confirmPassword"); const confirmPassword = data.get("confirmPassword");
if (!firstName || firstName.trim() === "") { if (!firstName || firstName.trim() === "") {
this.errorMessage = "First name is required."; this.$("p").attr("errormessage", "First name is required.")
return false return false
} else if (firstName.trim().length < 2) { } else if (firstName.trim().length < 2) {
this.errorMessage = "First name must be at least 2 characters."; this.$("p").attr("errormessage", "First name must be at least 2 characters.")
return false return false
} else if (!/^[a-zA-Z\s'-]+$/.test(firstName.trim())) { } else if (!/^[a-zA-Z\s'-]+$/.test(firstName.trim())) {
this.errorMessage = "First name contains invalid characters."; this.$("p").attr("errormessage", "First name contains invalid characters.")
return false return false
} }
if (!lastName || lastName.trim() === "") { if (!lastName || lastName.trim() === "") {
this.errorMessage = "Last name is required."; this.$("p").attr("errormessage", "Last name is required.")
return false return false
} else if (lastName.trim().length < 2) { } else if (lastName.trim().length < 2) {
this.errorMessage = "Last name must be at least 2 characters."; this.$("p").attr("errormessage", "Last name must be at least 2 characters.")
return false return false
} else if (!/^[a-zA-Z\s'-]+$/.test(lastName.trim())) { } else if (!/^[a-zA-Z\s'-]+$/.test(lastName.trim())) {
this.errorMessage = "Last name contains invalid characters."; this.$("p").attr("errormessage", "Last name contains invalid characters.")
return false return false
} }
if (!email || email.trim() === "") { if (!email || email.trim() === "") {
this.errorMessage = "Email is required."; this.$("p").attr("errormessage", "Email is required.")
return false return false
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) { } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())) {
this.errorMessage = "Please enter a valid email address."; this.$("p").attr("errormessage", "Please enter a valid email address.")
return false return false
} }
let passwordError = `Password must be at least 7 characters and include an uppercase letter, a lowercase letter, a number, and a special character (!@#$%^&*(),.?":{}|<>)`
if (!password) { if (!password) {
this.errorMessage = "Password is required."; this.$("p").attr("errormessage", "Password is required.")
return false return false
} else if (password.length < 8) { } else if (password.length < 7) {
this.errorMessage = "Password must be at least 8 characters."; this.$("p").attr("errormessage", passwordError)
return false return false
} else if (!/[A-Z]/.test(password)) { } else if (!/[A-Z]/.test(password)) {
this.errorMessage = "Password must contain at least one uppercase letter."; this.$("p").attr("errormessage", passwordError)
return false return false
} else if (!/[a-z]/.test(password)) { } else if (!/[a-z]/.test(password)) {
this.errorMessage = "Password must contain at least one lowercase letter."; this.$("p").attr("errormessage", passwordError)
return false return false
} else if (!/[0-9]/.test(password)) { } else if (!/[0-9]/.test(password)) {
this.errorMessage = "Password must contain at least one number."; this.$("p").attr("errormessage", passwordError)
return false return false
} else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) { } else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
this.errorMessage = "Password must contain at least one special character."; this.$("p").attr("errormessage", passwordError)
return false return false
} }
if (!confirmPassword) { if (!confirmPassword) {
this.errorMessage = "Please confirm your password."; this.$("p").attr("errormessage", "Please confirm your password.")
return false return false
} else if (confirmPassword !== password) { } else if (confirmPassword !== password) {
this.errorMessage = "Passwords do not match."; this.$("p").attr("errormessage", "Passwords do not match.")
return false return false
} }

View File

@@ -1,6 +1,7 @@
/* /*
Sam Russell Sam Russell
Captured Sun Captured Sun
2.24.26 - Allowing state() to watch other elements
2.21.26 - Making state() be called on initial definition, fixing fontSize so it works with clamp(), other strings 2.21.26 - Making state() be called on initial definition, fixing fontSize so it works with clamp(), other strings
2.20.26 - Adding state() 2.20.26 - Adding state()
2.19.26 - Adding dynamicText() 2.19.26 - Adding dynamicText()
@@ -700,19 +701,34 @@ HTMLElement.prototype.horizontalAlign = function (value) {
/* Elements */ /* Elements */
HTMLElement.prototype.state = function(attr, cb) { HTMLElement.prototype.state = function(arg1, arg2, arg3) {
let el;
let attr;
let cb;
if(arg3) {
el = arg1
attr = arg2
cb = arg3
} else {
el = this
attr = arg1
cb = arg2
}
if (attr !== attr.toLowerCase()) { if (attr !== attr.toLowerCase()) {
throw new Error(`quill: dynamicText() attr "${attr}" must be lowercase`); throw new Error(`quill: dynamicText() attr "${attr}" must be lowercase`);
} }
new MutationObserver(() => { let handler = () => {
const value = this.getAttribute(attr); const value = el.getAttribute(attr);
cb.call(this, value) cb.call(this, value)
}) }
.observe(this, { attributes: true, attributeFilter: [attr] });
const value = this.getAttribute(attr); new MutationObserver(handler)
cb.call(this, value) .observe(el, { attributes: true, attributeFilter: [attr] });
handler()
return this return this
} }
@@ -1230,22 +1246,23 @@ HTMLElement.prototype.removeAllListeners = function() {
/* ATTRIBUTES */ /* ATTRIBUTES */
HTMLElement.prototype.attr = function(attributes) { HTMLElement.prototype.attr = function(arg1, arg2) {
if ( if(typeof arg1 === "object") {
typeof attributes !== "object" || for (const [key, value] of Object.entries(arg1)) {
attributes === null || if(value === null) {
Array.isArray(attributes) this.removeAttribute(key)
) { } else {
throw new TypeError("attr() expects an object with key-value pairs"); this.setAttribute(key, value);
} }
for (const [key, value] of Object.entries(attributes)) {
if(value === null) {
this.removeAttribute(key)
} else {
this.setAttribute(key, value);
} }
}
return this; return this;
} else if(typeof arg1 === "string" && arg2) {
this.setAttribute(arg1, arg2)
return this
} else if(typeof arg1 === "string") {
return this.getAttribute("")
} else {
throw new TypeError("wrong parameter for attr(): ", arg1);
}
}; };