/** * Login screen component for PodTUI * Email/password login with links to code validation and OAuth */ import { createSignal } from "solid-js"; import { useAuthStore } from "@/stores/auth"; import { useTheme } from "@/context/ThemeContext"; import { AUTH_CONFIG } from "@/config/auth"; interface LoginScreenProps { focused?: boolean; onNavigateToCode?: () => void; onNavigateToOAuth?: () => void; } type FocusField = "email" | "password" | "submit" | "code" | "oauth"; export function LoginScreen(props: LoginScreenProps) { const auth = useAuthStore(); const { theme } = useTheme(); const [email, setEmail] = createSignal(""); const [password, setPassword] = createSignal(""); const [focusField, setFocusField] = createSignal("email"); const [emailError, setEmailError] = createSignal(null); const [passwordError, setPasswordError] = createSignal(null); const fields: FocusField[] = ["email", "password", "submit", "code", "oauth"]; const validateEmail = (value: string): boolean => { if (!value) { setEmailError("Email is required"); return false; } if (!AUTH_CONFIG.email.pattern.test(value)) { setEmailError("Invalid email format"); return false; } setEmailError(null); return true; }; const validatePassword = (value: string): boolean => { if (!value) { setPasswordError("Password is required"); return false; } if (value.length < AUTH_CONFIG.password.minLength) { setPasswordError(`Minimum ${AUTH_CONFIG.password.minLength} characters`); return false; } setPasswordError(null); return true; }; const handleSubmit = async () => { const isEmailValid = validateEmail(email()); const isPasswordValid = validatePassword(password()); if (!isEmailValid || !isPasswordValid) { return; } await auth.login({ email: email(), password: password() }); }; const handleKeyPress = (key: { name: string; shift?: boolean }) => { if (key.name === "tab") { const currentIndex = fields.indexOf(focusField()); const nextIndex = key.shift ? (currentIndex - 1 + fields.length) % fields.length : (currentIndex + 1) % fields.length; setFocusField(fields[nextIndex]); } else if (key.name === "return" || key.name === "enter") { if (focusField() === "submit") { handleSubmit(); } else if (focusField() === "code" && props.onNavigateToCode) { props.onNavigateToCode(); } else if (focusField() === "oauth" && props.onNavigateToOAuth) { props.onNavigateToOAuth(); } } }; return ( Sign In {/* Email field */} Email: {emailError() && {emailError()}} {/* Password field */} Password: {passwordError() && {passwordError()}} {/* Submit button */} {auth.isLoading ? "Signing in..." : "[Enter] Sign In"} {/* Auth error message */} {auth.error && {auth.error.message}} {/* Alternative auth options */} Or authenticate with: [C] Sync Code [O] OAuth Info Tab to navigate, Enter to select ); }