Skip to content

Commit c348fa0

Browse files
committed
dasbord user and admin
1 parent e835614 commit c348fa0

22 files changed

+823
-42
lines changed

package-lock.json

Lines changed: 55 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
"react": "^18.2.0",
1919
"react-dom": "^18.2.0",
2020
"react-hook-form": "^7.51.5",
21+
"react-hot-toast": "^2.4.1",
2122
"react-icons": "^5.2.1",
23+
"react-infinite-scroll-component": "^6.1.0",
2224
"react-router-dom": "^6.23.1",
2325
"react-tabs": "^6.0.2",
2426
"sort-by": "^1.2.0",
27+
"sweetalert2": "^11.11.1",
2528
"swiper": "^11.1.4"
2629
},
2730
"devDependencies": {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Navigate } from "react-router-dom";
2+
import useAdmin from "../../Hooks/useAdmin";
3+
import useAuth from "../../Hooks/useAuth";
4+
import LogingSpiner from "../../Sheare/LogingSpiner";
5+
6+
const Adminrouter = ({ children }) => {
7+
const { user, loding } = useAuth();
8+
const [isAdmin, isLoading] = useAdmin();
9+
const location = useLocation();
10+
if (loding || isLoading) return <LogingSpiner></LogingSpiner>;
11+
if (user && isAdmin) return children;
12+
return (
13+
<Navigate to="/login" state={location.pathname} replace="true"></Navigate>
14+
);
15+
};
16+
17+
export default Adminrouter;

src/Componente/Firbase/AuthProvider.jsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ import {
1010
updateProfile,
1111
} from "firebase/auth";
1212
import app from "./firbase.config";
13+
import axios from "axios";
14+
import useAxiosCommon from "../../Hooks/useAxiosCommon";
1315

1416
export const AuthContext = createContext(null);
1517
const auth = getAuth(app);
1618
const googlepro = new GoogleAuthProvider();
1719
const AuthProvider = ({ children }) => {
1820
const [user, setuser] = useState(null);
1921
const [loding, setloding] = useState(true);
22+
const axiosCommon = useAxiosCommon();
2023

2124
//user create
2225
const creatuser = (email, password) => {
@@ -43,16 +46,20 @@ const AuthProvider = ({ children }) => {
4346
// logout
4447
const logout = async () => {
4548
setuser(null);
46-
47-
signOut(auth);
49+
return signOut(auth);
4850
};
4951

50-
// Get token from server
51-
const getToken = async (email) => {
52+
//save user
53+
54+
const saveUser = async (user) => {
55+
const cuser = {
56+
name: user?.displayName,
57+
email: user?.email,
58+
badge: "bronze",
59+
};
5260
const { data } = await axios.post(
53-
`${import.meta.env.VITE_API_URL}/jwt`,
54-
{ email },
55-
{ withCredentials: true }
61+
`${import.meta.env.VITE_API_URL}/user`,
62+
cuser
5663
);
5764
return data;
5865
};
@@ -61,15 +68,26 @@ const AuthProvider = ({ children }) => {
6168
useEffect(() => {
6269
const unsubscribe = onAuthStateChanged(auth, (user) => {
6370
setuser(user);
71+
console.log(user);
72+
6473
if (user) {
65-
getToken(user.email);
74+
const userinfo = { email: user.email };
75+
axiosCommon.post("/jwt", userinfo).then((res) => {
76+
if (res.data.token) {
77+
localStorage.setItem("access-token", res.data.token);
78+
}
79+
});
80+
81+
saveUser(user);
82+
} else {
83+
localStorage.removeItem("access-token");
6684
}
6785
setloding(false);
6886
});
6987
return () => {
7088
return unsubscribe();
7189
};
72-
}, []);
90+
}, [axiosCommon]);
7391

7492
const allvalue = {
7593
user,
@@ -80,6 +98,7 @@ const AuthProvider = ({ children }) => {
8098
logout,
8199
setuser,
82100
loding,
101+
setloding,
83102
};
84103
return (
85104
<AuthContext.Provider value={allvalue}>{children}</AuthContext.Provider>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Navigate, useLocation } from "react-router-dom";
2+
import useAuth from "../../Hooks/useAuth";
3+
import LogingSpiner from "../../Sheare/LogingSpiner";
4+
5+
const PrivateRout = ({ children }) => {
6+
const { user, loding } = useAuth();
7+
const location = useLocation();
8+
if (loding) return <LogingSpiner></LogingSpiner>;
9+
if (user) return children;
10+
return (
11+
<Navigate to="/login" state={location.pathname} replace="true"></Navigate>
12+
);
13+
};
14+
15+
export default PrivateRout;

src/Componente/LoginReg/Login.jsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1-
import { Link } from "react-router-dom";
1+
import { Link, useLocation, useNavigate } from "react-router-dom";
22
import Social from "./Social";
33
import { useForm } from "react-hook-form";
4+
import toast from "react-hot-toast";
5+
import useAuth from "../../Hooks/useAuth";
46

57
const Login = () => {
8+
const { login } = useAuth();
9+
const naviget = useNavigate();
10+
const location = useLocation();
11+
const from = location?.state || "/";
12+
613
const { register, handleSubmit } = useForm();
7-
const onSubmit = (data) => console.log(data);
14+
const onSubmit = async (data) => {
15+
const { email, password } = data;
16+
try {
17+
await login(email, password);
18+
naviget(from);
19+
toast.success(" Login successful !");
20+
} catch (err) {
21+
toast.error(err.message);
22+
}
23+
};
824
return (
925
<div className="w-full md:w-3/4 mx-auto p-4">
1026
<div className="md:flex gap-3 ">

src/Componente/LoginReg/Register.jsx

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
1+
import axios from "axios";
12
import { useForm } from "react-hook-form";
2-
import { Link } from "react-router-dom";
3+
import toast from "react-hot-toast";
4+
import { Link, useNavigate } from "react-router-dom";
5+
import useAuth from "../../Hooks/useAuth";
36
import Social from "./Social";
7+
import { ImSpinner9 } from "react-icons/im";
48

59
const Register = () => {
10+
const naviget = useNavigate();
11+
const { creatuser, updatprofil, loding, setloding } = useAuth();
612
const { register, handleSubmit } = useForm();
7-
const onSubmit = (data) => console.log(data);
13+
const onSubmit = async (data) => {
14+
const { name, image, email, password } = data;
15+
const imgfile = { image: data.image[0] };
16+
try {
17+
const { data } = await axios.post(
18+
`https://api.imgbb.com/1/upload?key=${import.meta.env.VITE_IMGBB_key}`,
19+
imgfile,
20+
{
21+
headers: {
22+
"Content-Type": "multipart/form-data",
23+
},
24+
}
25+
);
26+
const result = await creatuser(email, password);
27+
await updatprofil(name, data.data.display_url);
28+
naviget("/");
29+
toast("Sign up Successful !");
30+
} catch (error) {
31+
setloding(false);
32+
toast(error.message);
33+
}
34+
};
835
return (
936
<div>
1037
<div className=" w-full md:w-3/6 mx-auto">
@@ -25,7 +52,13 @@ const Register = () => {
2552
<div>
2653
<label> Your photo : </label>
2754

28-
<input type="file" {...register("img")} required name="img" id="" />
55+
<input
56+
type="file"
57+
{...register("image")}
58+
required
59+
name="image"
60+
id=""
61+
/>
2962
</div>
3063
<br />
3164
<div>
@@ -55,7 +88,8 @@ const Register = () => {
5588
<input
5689
type="submit"
5790
className=" btn btn-outline btn-primary w-full"
58-
value="Login"
91+
value={loding ? "Please wait" : "Register"}
92+
disabled={loding}
5993
/>
6094
</form>
6195
<p className=" text-center mt-2">

src/Componente/LoginReg/Social.jsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
1+
import toast from "react-hot-toast";
12
import { FaGoogle } from "react-icons/fa";
3+
import { useNavigate } from "react-router-dom";
4+
import useAuth from "../../Hooks/useAuth";
25

36
const Social = () => {
7+
const { googlelogin, loding } = useAuth();
8+
const naviget = useNavigate();
9+
const handelglogin = async () => {
10+
try {
11+
await googlelogin();
12+
naviget("/");
13+
toast.success("google Login successful !");
14+
} catch (err) {
15+
toast.error(err.message);
16+
}
17+
};
418
return (
5-
<div className=" mt-2">
19+
<div className=" mt-2 mb-10">
620
<div className=" divider"> or </div>
721
<div className=" flex justify-center">
8-
<button className=" btn text-2xl btn-outline btn-primary">
22+
<button
23+
disabled={loding}
24+
onClick={handelglogin}
25+
className=" btn text-2xl btn-outline btn-primary"
26+
>
927
<FaGoogle /> Google
1028
</button>
1129
</div>

0 commit comments

Comments
 (0)