update redux
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
"use client"
|
||||
|
||||
import UserAddressCard from "@/components/user-profile/UserAddressCard";
|
||||
import UserInfoCard from "@/components/user-profile/UserInfoCard";
|
||||
import UserMetaCard from "@/components/user-profile/UserMetaCard";
|
||||
import { Metadata } from "next";
|
||||
import React from "react";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Next.js Profile | TailAdmin - Next.js Dashboard Template",
|
||||
description:
|
||||
"This is Next.js Profile page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template",
|
||||
};
|
||||
import { RootState } from "@/store/store";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export default function Profile() {
|
||||
const user = useSelector((state: RootState) => state.user.data);
|
||||
console.log("Current User:", user);
|
||||
return (
|
||||
<div>
|
||||
<div className="rounded-2xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] lg:p-6">
|
||||
|
||||
@@ -4,6 +4,7 @@ import "flatpickr/dist/flatpickr.css";
|
||||
import { SidebarProvider } from '@/context/SidebarContext';
|
||||
import { ThemeProvider } from '@/context/ThemeContext';
|
||||
import { Toaster } from 'sonner';
|
||||
import StoreProvider from '@/store/StoreProvider';
|
||||
|
||||
const outfit = Outfit({
|
||||
subsets: ["latin"],
|
||||
@@ -17,9 +18,11 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={`${outfit.className} dark:bg-gray-900`}>
|
||||
<ThemeProvider>
|
||||
<SidebarProvider>{children} <Toaster closeButton richColors position="top-right" /> </SidebarProvider>
|
||||
</ThemeProvider>
|
||||
<StoreProvider>
|
||||
<ThemeProvider>
|
||||
<SidebarProvider>{children} <Toaster closeButton richColors position="top-right" /> </SidebarProvider>
|
||||
</ThemeProvider>
|
||||
</StoreProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -3,17 +3,20 @@
|
||||
import Checkbox from "@/components/form/input/Checkbox";
|
||||
import Input from "@/components/form/input/InputField";
|
||||
import Label from "@/components/form/Label";
|
||||
import Button from "@/components/ui/button/Button";
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon } from "@/icons";
|
||||
import { apiGetCurrentUser, apiSignIn } from "@/service/auth";
|
||||
import Link from "next/link";
|
||||
import React, { useState } from "react";
|
||||
import { toast } from 'sonner';
|
||||
import { API } from "../../../api";
|
||||
import api from "@/config/config";
|
||||
import { setUserData } from "@/store/features/userSlice";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function SignInForm() {
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const router = useRouter();
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
const [errorMsg, setErrorMsg] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -60,11 +63,15 @@ const [showPassword, setShowPassword] = useState(false);
|
||||
setLoading(true);
|
||||
const res = await apiSignIn(formData);
|
||||
console.log("API Sign In Response:", res);
|
||||
|
||||
if (res.status === true) {
|
||||
toast.success('Đăng nhập thành công!');
|
||||
|
||||
const data = await apiGetCurrentUser();
|
||||
console.log("Current User:", data);
|
||||
console.log("Current User Data:", data);
|
||||
if (data?.data) {
|
||||
dispatch(setUserData(data.data));
|
||||
// router.push("/profile");
|
||||
}
|
||||
}else{
|
||||
toast.error('Email hoặc mật khẩu không đúng.');
|
||||
}
|
||||
|
||||
27
src/interface/user.ts
Normal file
27
src/interface/user.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export interface UserProfile {
|
||||
display_name: string;
|
||||
full_name: string;
|
||||
avatar_url: string;
|
||||
bio: string;
|
||||
location: string;
|
||||
website: string;
|
||||
country_code: string;
|
||||
phone: string;
|
||||
}
|
||||
|
||||
export interface UserRole {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface UserData {
|
||||
id: string;
|
||||
email: string;
|
||||
profile: UserProfile;
|
||||
token_version: number;
|
||||
is_deleted: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
roles: UserRole[];
|
||||
}
|
||||
|
||||
14
src/store/StoreProvider.tsx
Normal file
14
src/store/StoreProvider.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import { useRef } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { store } from './store';
|
||||
|
||||
export default function StoreProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const storeRef = useRef(store);
|
||||
return <Provider store={storeRef.current}>{children}</Provider>;
|
||||
}
|
||||
29
src/store/features/userSlice.ts
Normal file
29
src/store/features/userSlice.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { UserData } from '@/interface/user';
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
interface UserState {
|
||||
data: UserData | null;
|
||||
isAuthenticated: boolean;
|
||||
}
|
||||
const initialState: UserState = {
|
||||
data: null,
|
||||
isAuthenticated: false,
|
||||
};
|
||||
|
||||
const userSlice = createSlice({
|
||||
name: 'user',
|
||||
initialState,
|
||||
reducers: {
|
||||
setUserData: (state, action: PayloadAction<UserData>) => {
|
||||
state.data = action.payload;
|
||||
state.isAuthenticated = true;
|
||||
},
|
||||
clearUserData: (state) => {
|
||||
state.data = null;
|
||||
state.isAuthenticated = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setUserData, clearUserData } = userSlice.actions;
|
||||
export default userSlice.reducer;
|
||||
11
src/store/store.ts
Normal file
11
src/store/store.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import userReducer from './features/userSlice';
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
user: userReducer,
|
||||
},
|
||||
});
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
Reference in New Issue
Block a user