generated from muhtadeetaron/nextjs-template
fix(auth): fix fetch user info at login
This commit is contained in:
@ -4,6 +4,7 @@ import React, { useState, useEffect } from "react";
|
|||||||
import BackgroundWrapper from "@/components/BackgroundWrapper";
|
import BackgroundWrapper from "@/components/BackgroundWrapper";
|
||||||
import { Bookmark, BookmarkCheck, ListFilter, MoveLeft } from "lucide-react";
|
import { Bookmark, BookmarkCheck, ListFilter, MoveLeft } from "lucide-react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import DestructibleAlert from "@/components/DestructibleAlert";
|
||||||
|
|
||||||
interface Question {
|
interface Question {
|
||||||
id: number;
|
id: number;
|
||||||
@ -74,9 +75,13 @@ const BookmarkPage = () => {
|
|||||||
<ListFilter size={24} color="#113768" />
|
<ListFilter size={24} color="#113768" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{questions.map((question: Question) => (
|
{/* {questions.map((question: Question) => (
|
||||||
<QuestionItem key={question.id} question={question} />
|
<QuestionItem key={question.id} question={question} />
|
||||||
))}
|
))} */}
|
||||||
|
<DestructibleAlert
|
||||||
|
text="Page under construction"
|
||||||
|
variant="warning"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { useModal } from "@/context/ModalContext";
|
|||||||
import { useAuthStore } from "@/stores/authStore";
|
import { useAuthStore } from "@/stores/authStore";
|
||||||
import { useTimerStore } from "@/stores/timerStore";
|
import { useTimerStore } from "@/stores/timerStore";
|
||||||
import { useExamStore } from "@/stores/examStore";
|
import { useExamStore } from "@/stores/examStore";
|
||||||
|
import { BsPatchCheckFill } from "react-icons/bs";
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
displayUser?: boolean;
|
displayUser?: boolean;
|
||||||
@ -59,7 +60,7 @@ const Header = ({
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
<span className="text-md font-bold text-white flex items-center gap-2">
|
<span className="text-md font-bold text-white flex items-center gap-2">
|
||||||
Hello, {user?.username ? user.username.split(" ")[0] : "User"}{" "}
|
Hello, {user?.username ? user.username.split(" ")[0] : "User"}{" "}
|
||||||
<BadgeCheck size={20} color="white" />
|
<BsPatchCheckFill size={20} color="white" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -46,7 +46,6 @@ interface AuthState {
|
|||||||
login: (form: LoginForm) => Promise<void>;
|
login: (form: LoginForm) => Promise<void>;
|
||||||
register: (form: RegisterForm) => Promise<void>;
|
register: (form: RegisterForm) => Promise<void>;
|
||||||
setToken: (token: string | null) => void;
|
setToken: (token: string | null) => void;
|
||||||
fetchUser: () => Promise<void>;
|
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
initializeAuth: () => Promise<void>;
|
initializeAuth: () => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -78,9 +77,23 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
throw new Error(data.message || "Login failed");
|
throw new Error(data.message || "Login failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
setCookie("authToken", data.token);
|
const token = data.token;
|
||||||
set({ token: data.token, isLoading: false });
|
setCookie("authToken", token);
|
||||||
|
set({ token });
|
||||||
|
|
||||||
|
// Automatically fetch user info after login
|
||||||
|
const userRes = await fetch(`${API_URL}/me/profile/`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!userRes.ok) {
|
||||||
|
throw new Error("Failed to fetch user info after login");
|
||||||
|
}
|
||||||
|
|
||||||
|
const userData: UserData = await userRes.json();
|
||||||
|
set({ user: userData, isLoading: false });
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
console.error("Login error:", err);
|
||||||
set({
|
set({
|
||||||
error: err?.message || "Login failed",
|
error: err?.message || "Login failed",
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
@ -88,6 +101,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
register: async (form: RegisterForm) => {
|
register: async (form: RegisterForm) => {
|
||||||
set({ isLoading: true, error: null });
|
set({ isLoading: true, error: null });
|
||||||
try {
|
try {
|
||||||
@ -118,26 +132,6 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchUser: async () => {
|
|
||||||
const token = get().token;
|
|
||||||
if (!token) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch(`${API_URL}/me/profile/`, {
|
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) throw new Error("Failed to fetch user info");
|
|
||||||
|
|
||||||
const data: UserData = await res.json();
|
|
||||||
console.log(data);
|
|
||||||
set({ user: data });
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error fetching user:", err);
|
|
||||||
get().logout();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
logout: () => {
|
logout: () => {
|
||||||
set({ token: null, user: null });
|
set({ token: null, user: null });
|
||||||
setCookie("authToken", null);
|
setCookie("authToken", null);
|
||||||
@ -147,7 +141,6 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
const storedToken = getCookie("authToken");
|
const storedToken = getCookie("authToken");
|
||||||
if (storedToken) {
|
if (storedToken) {
|
||||||
set({ token: storedToken });
|
set({ token: storedToken });
|
||||||
await get().fetchUser();
|
|
||||||
}
|
}
|
||||||
set({ isLoading: false, hydrated: true });
|
set({ isLoading: false, hydrated: true });
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user