"use client"; import { FormHelperText, IconButton, InputAdornment } from "@mui/material"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; import TextField from "@mui/material/TextField"; import Typography from "@mui/material/Typography"; import { TFunction } from "i18next"; import { Session } from "next-auth"; import { getSession, signIn } from "next-auth/react"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { SubmitHandler, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { SetupAxiosInterceptors } from "@/app/(main)/axios/axiosInstance"; import { persistBackendTokens } from "@/app/utils/authToken"; import { Visibility, VisibilityOff } from "@mui/icons-material"; type LoginFields = { username: string; password: string; }; type SessionWithAbilities = | ({ abilities: string[]; accessToken?: string; refreshToken?: string; } & Session) | null; // Error codes in https://next-auth.js.org/configuration/pages#sign-in-page const getHumanFriendlyErrorMessage = ( t: TFunction, serverError: string, ): string => { switch (serverError) { case "CredentialsSignin": return t("Invalid username or password."); case "Default": default: return t("Something went wrong. Please try again later."); } }; const LoginForm: React.FC = () => { const { t } = useTranslation("login"); const { register, handleSubmit, formState: { errors, isSubmitting }, } = useForm(); const [serverError, setServerError] = useState(); const router = useRouter(); const [showPassword, setShowPassword] = useState(false); const handleClickShowPassword = () => setShowPassword(!showPassword); const handleMouseDownPassword = () => setShowPassword(!showPassword); const onSubmit: SubmitHandler = async (data) => { console.log(data); const res = await signIn("credentials", { redirect: false, ...data, }); if (res?.error) { setServerError(res.error); return; } // Persist access + refresh in localStorage (Login is outside AxiosProvider) const session = (await getSession()) as SessionWithAbilities; const access = session?.accessToken ?? ""; if (access) { persistBackendTokens(access, session?.refreshToken); SetupAxiosInterceptors(access); } window.localStorage.setItem( "abilities", JSON.stringify(session?.abilities), ); const callbackUrl = new URLSearchParams(window.location.search).get("callbackUrl") || "/"; router.push(callbackUrl); }; useEffect(() => { // clean abilities before login window.localStorage.removeItem("abilities"); }, []); return ( {t("Sign In")} {showPassword ? : } ), }} /> {serverError && ( {getHumanFriendlyErrorMessage(t, serverError)} )} ); }; export default LoginForm;