{authMode === "login" ? (
-
+
) : (
-
+
)}
@@ -80,10 +111,18 @@ export function AuthModal({ isOpen, onOpenChange }: IAuthModalProps) {
size={"lg"}
className="w-full gap-4"
onClick={handleGoogleSignIn}
+ disabled={isGoogleSigningIn}
+ loading={isGoogleSigningIn}
icon={GoogleIcon}
iconPlacement="left"
>
Nastavi sa Google računom
+ {lastLoginMethod === "google" && !isGoogleSigningIn && (
+
+
+ Zadnja prijava
+
+ )}
diff --git a/frontend/src/components/custom/header/forms/login-form.tsx b/frontend/src/components/custom/header/forms/login-form.tsx
index b814d46..c8177bd 100644
--- a/frontend/src/components/custom/header/forms/login-form.tsx
+++ b/frontend/src/components/custom/header/forms/login-form.tsx
@@ -2,17 +2,17 @@
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
-import { Loader2 } from "lucide-react";
+import { CircleCheck, Loader2 } from "lucide-react";
import { toast } from "sonner";
-import { isAxiosError } from "axios";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { loginRequestSchema, LoginRequest } from "@/lib/api/schemas/auth-user";
import { cn } from "@/lib/utils";
-import { authService } from "@/lib/api";
+import { signIn } from "@/lib/auth-client";
import { useUser } from "@/context/user-context";
+import { setLastLoginMethod } from "@/utils/browser/local-storage";
import {
Form,
FormControl,
@@ -25,131 +25,115 @@ import { PasswordInput } from "@/components/ui/password-input";
interface ILoginFormProps {
onSuccess?: () => void;
+ isLastUsed?: boolean;
+ externalDisabled?: boolean;
}
-export function LoginForm({ onSuccess }: ILoginFormProps) {
- const loginMutation = authService.useLogin();
+export function LoginForm({ onSuccess, isLastUsed, externalDisabled }: ILoginFormProps) {
const { handleUserLogin } = useUser();
const form = useForm
({
resolver: zodResolver(loginRequestSchema),
defaultValues: {
- usernameOrEmail: "",
+ email: "",
password: "",
},
});
- const onSubmit = (data: LoginRequest) => {
- // clear previous root error and start login
+ async function onSubmit(data: LoginRequest) {
form.clearErrors("root");
- loginMutation.mutate(
- {
- usernameOrEmail: data.usernameOrEmail,
- password: data.password,
- },
- {
- onSuccess: async (response) => {
- toast.success("Prijava uspješna!");
- form.reset();
- // Use handleUserLogin to set user and fetch shopping lists/digital cards
- await handleUserLogin(response.user);
- onSuccess?.();
- },
- onError: (error: unknown) => {
- let status = 0;
- let serverMessage: string | undefined;
- if (isAxiosError(error)) {
- status = error.response?.status ?? 0;
- serverMessage =
- (error.response?.data as { message?: string })?.message ||
- error.message;
- } else {
- serverMessage = (error as Error)?.message || "Unknown error";
- }
+ try {
+ const result = await signIn.email({
+ email: data.email,
+ password: data.password,
+ });
- if (status >= 400 && status < 500) {
- // 4xx -> show root form error
- const message =
- status === 401
- ? "Neispravno korisničko ime ili email i lozinka"
- : serverMessage || "Provjeri unesene podatke.";
- form.setError("root", { type: "server", message });
- } else {
- toast.error(serverMessage || "Greška pri prijavi");
- }
- },
+ if (result.error) {
+ const status = result.error.status ?? 0;
+ const message =
+ status === 401 || status === 400
+ ? "Neispravni email ili lozinka"
+ : result.error.message || "Provjeri unesene podatke.";
+ form.setError("root", { type: "server", message });
+ return;
}
- );
- };
+
+ await handleUserLogin();
+ toast.success("Prijava uspješna!");
+ form.reset();
+ setLastLoginMethod("email");
+ onSuccess?.();
+ } catch {
+ toast.error("Greška pri prijavi. Pokušaj ponovo.");
+ }
+ }
return (
- <>
-