import { useState, useEffect, useRef, SyntheticEvent, MouseEventHandler, } from "react"; import { useLocation, Link } from "react-router-dom"; import { useAuth } from "../useAuth"; import { useUnauthenticatedRequest } from "../util"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faGithub, faGitlab, faGoogle, IconDefinition, } from "@fortawesome/free-brands-svg-icons"; import { faSignInAlt } from "@fortawesome/free-solid-svg-icons"; import { PersonPlus } from "react-bootstrap-icons"; interface OAuthProviders { providers: string[]; } interface Prompt { message: string; kind: string; } export default function Login() { const location = useLocation(); const auth = useAuth(); const [ackLocation, setAckLocation] = useState(false); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [prompt, setPrompt] = useState(null); const [loading, setLoading] = useState(null); const isMountedRef = useRef(null); const { response: oauthProviders } = useUnauthenticatedRequest({ endpoint: "auth/login/oauth/providers", }); useEffect(() => { if (location.state?.prompt && !ackLocation) { setPrompt(location.state.prompt); setAckLocation(true); } isMountedRef.current = true; return () => { isMountedRef.current = false; }; }); const handleSubmit = async (evt: SyntheticEvent) => { evt.preventDefault(); setPrompt(null); setLoading("password"); try { await auth?.login(username, password); } catch (e: any) { setPrompt({ message: e.message, kind: "danger" }); } finally { if (isMountedRef.current) { setLoading(null); } } }; const handleOAuthLogin = async (provider: string) => { setPrompt(null); setLoading(provider); try { await auth?.oauthLogin(provider); } catch (e: any) { setPrompt({ message: e.message, kind: "danger" }); } }; return (

chartered ✈️

a private, authenticated cargo registry
{prompt?.message}
setUsername(e.target.value)} />
setPassword(e.target.value)} />
Register {oauthProviders?.providers.length > 0 ? ( <>
or
{oauthProviders.providers.map((v, i) => ( { evt.preventDefault(); handleOAuthLogin(v); }} /> ))} ) : ( <> )}
); } const BRANDS = { default: [faSignInAlt, ""], github: [faGithub, "#4078c0"], gitlab: [faGitlab, "#6E49cb"], google: [faGoogle, "#4285f4"], }; function getIconForProvider(provider: string): [IconDefinition, string] { return BRANDS[provider] || BRANDS.default; } function ButtonOrSpinner({ type, variant, disabled, showSpinner, text, icon, background, onClick, }: { type: "button" | "submit"; variant: string; disabled: boolean; showSpinner: boolean; text: string; icon?: IconDefinition; background?: string; onClick: MouseEventHandler; }) { if (showSpinner) { return (
Logging in...
); } if (type) { return ( ); } return <>; }