/** @jsxImportSource hono/jsx */ import { type PasswordChangeError, type PasswordConfig, type PasswordLoginError, type PasswordRegisterError, } from "../adapters" // import { Layout } from "@openauthjs/openauth/ui/base" import { Layout } from "./base" import "@openauthjs/openauth/ui/form" // import { FormAlert } from "@openauthjs/openauth/ui/form" const DEFAULT_COPY = { error_email_taken: "There is already an account with this email.", error_username_taken: "There is already an account with this username.", error_invalid_code: "Code is incorrect.", error_invalid_email: "Email is not valid.", error_invalid_password: "Password is incorrect.", error_invalid_username: "Username can only contain letters.", error_password_mismatch: "Passwords do not match.", register_title: "Welcome to the app", register_description: "Sign in with your email", login_title: "Welcome to the app", login_description: "Sign in with your email", register: "Register", register_prompt: "Don't have an account?", login_prompt: "Already have an account?", login: "Login", change_prompt: "Forgot your password?", change: "Well that sucks", code_resend: "Resend code", code_return: "Back to", logo: "A", input_email: "john@doe.com", input_password: "●●●●●●●●●●●", input_code: "●●●●●●", input_username: "john", input_repeat: "●●●●●●●●●●●", button_continue: "Continue", } satisfies { [key in `error_${| PasswordLoginError["type"] | PasswordRegisterError["type"] | PasswordChangeError["type"]}`]: string } & Record export type PasswordUICopy = typeof DEFAULT_COPY export interface PasswordUIOptions { sendCode: PasswordConfig["sendCode"] copy?: Partial } export function PasswordUI(input: PasswordUIOptions) { const copy = { ...DEFAULT_COPY, ...input.copy, } return { sendCode: input.sendCode, login: async (_req, form, error): Promise => { const emailError = ["invalid_email", "email_taken"].includes( error?.type || "", ) const passwordError = ["invalid_password", "password_mismatch"].includes( error?.type || "", ) const jsx = (

Login

{copy.register_prompt}{" "} {copy.register}
{/* */}
Email
{error?.type && emailError && copy?.[`error_${error.type}`]}
Password
{error?.type && passwordError && copy?.[`error_${error.type}`]}

{copy.change_prompt}{" "} {copy.change}
) return new Response(jsx.toString(), { status: error ? 401 : 200, headers: { "Content-Type": "text/html", }, }) }, register: async (_req, state, form, error): Promise => { const emailError = ["invalid_email", "email_taken"].includes( error?.type || "", ) const passwordError = ["invalid_password", "password_mismatch"].includes( error?.type || "", ) //Just in case the server does it const codeError = ["invalid_code"].includes( error?.type || "", ) const usernameError = ["invalid_username", "username_taken"].includes( error?.type || "", ); const jsx = (

Register

{copy.login_prompt}{" "} {copy.login}
{/* */} {state.type === "start" && ( <>
Email
{error?.type && emailError && copy?.[`error_${error.type}`]}
Username
{error?.type && usernameError && copy?.[`error_${error.type}`]}
Password
{error?.type && passwordError && copy?.[`error_${error.type}`]}
)} {state.type === "code" && ( <>
Code
{error?.type && codeError && copy?.[`error_${error.type}`]}
)}
) as string return new Response(jsx.toString(), { headers: { "Content-Type": "text/html", }, }) }, change: async (_req, state, form, error): Promise => { const passwordError = ["invalid_password", "password_mismatch"].includes( error?.type || "", ) const emailError = ["invalid_email", "email_taken"].includes( error?.type || "", ) const codeError = ["invalid_code"].includes( error?.type || "", ) const jsx = (

Forgot Password

{state.type != "update" && ( Suddenly had an epiphany?{" "} {copy.login} )}
{/* */} {state.type === "start" && ( <>
Email
{error?.type && emailError && copy?.[`error_${error.type}`]}
)} {state.type === "code" && ( <>
Code
{error?.type && codeError && copy?.[`error_${error.type}`]}
)} {state.type === "update" && ( <>
Password
{error?.type && passwordError && copy?.[`error_${error.type}`]}
Confirm Password
{error?.type && passwordError && copy?.[`error_${error.type}`]}
)} {state.type === "code" && (
)}
) return new Response(jsx.toString(), { status: error ? 400 : 200, headers: { "Content-Type": "text/html", }, }) }, } satisfies PasswordConfig }