farheen_blog_app 0.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "farheen_blog_app",
3
3
  "private": false,
4
- "version": "0.0.3",
4
+ "version": "1.0.4",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -0,0 +1,85 @@
1
+ import {
2
+ createContext,
3
+ useContext,
4
+ useEffect,
5
+ useState
6
+ } from "react";
7
+
8
+ const UserContext = createContext();
9
+
10
+ export const UserProvider = ({ children }) => {
11
+ const [user, setUser] = useState(null);
12
+ const [token, setToken] = useState(null);
13
+
14
+ useEffect(() => {
15
+
16
+ const storedUser =
17
+ localStorage.getItem(
18
+ "user"
19
+ );
20
+
21
+ const storedToken =
22
+ localStorage.getItem(
23
+ "token"
24
+ );
25
+
26
+ if (
27
+ storedUser &&
28
+ storedToken
29
+ ) {
30
+
31
+ setUser(JSON.parse(storedUser));
32
+ setToken(storedToken);
33
+ }
34
+
35
+ }, []);
36
+
37
+ const login = (userData, jwtToken) => {
38
+ setUser(userData);
39
+ setToken(jwtToken);
40
+
41
+ localStorage.setItem(
42
+ "user",
43
+ JSON.stringify(
44
+ userData
45
+ )
46
+ );
47
+
48
+ localStorage.setItem(
49
+ "token",
50
+ jwtToken
51
+ );
52
+ };
53
+
54
+ const logout = () => {
55
+
56
+ setUser(null);
57
+
58
+ setToken(null);
59
+
60
+ localStorage.removeItem(
61
+ "user"
62
+ );
63
+
64
+ localStorage.removeItem(
65
+ "token"
66
+ );
67
+ };
68
+
69
+ return (
70
+ <UserContext.Provider
71
+ value={{
72
+ user,
73
+ token,
74
+ login,
75
+ logout
76
+ }}
77
+ >
78
+ {children}
79
+ </UserContext.Provider>
80
+ );
81
+ };
82
+
83
+ export const useUser = () => {
84
+ return useContext(UserContext);
85
+ };
@@ -0,0 +1,35 @@
1
+ import {
2
+ useState,
3
+ useEffect
4
+ } from "react";
5
+
6
+ const useDebounce = (
7
+ value,
8
+ delay
9
+ ) => {
10
+
11
+ const [
12
+ debouncedValue,
13
+ setDebouncedValue
14
+ ] = useState(value);
15
+
16
+ useEffect(() => {
17
+
18
+ const timer =
19
+ setTimeout(() => {
20
+
21
+ setDebouncedValue(
22
+ value
23
+ );
24
+
25
+ }, delay);
26
+
27
+ return () =>
28
+ clearTimeout(timer);
29
+
30
+ }, [value, delay]);
31
+
32
+ return debouncedValue;
33
+ };
34
+
35
+ export default useDebounce;
@@ -1,13 +1,17 @@
1
1
  import {
2
- Navigate
3
- } from "react-router-dom";
2
+ Navigate,
3
+ Outlet
4
+ }
5
+ from "react-router-dom";
4
6
 
5
- export const ProtectedRoutes = ({ children }) => {
6
- const token = localStorage.getItem("token");
7
+ export function ProtectedRoute(){
7
8
 
8
- if (!token) {
9
- return <Navigate to="/login" />
10
- }
9
+ const token =
10
+ localStorage.getItem(
11
+ "token"
12
+ );
11
13
 
12
- return children;
14
+ return token
15
+ ? <Outlet />
16
+ : <Navigate to="/login"/>
13
17
  }
@@ -1,33 +1,43 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import api from "../../services/api";
3
+ import useDebounce from "../../hooks/useDebounce";
3
4
 
4
5
  const ManageBlogs = () => {
5
6
 
6
- const [blogs,setBlogs] = useState([]);
7
+ // for pagination and debounce search
8
+ const [page, setPage] = useState(1);
9
+ const [totalPage, setTotalPage] = useState(1);
10
+ const [search, setSearch] = useState("");
11
+
12
+ const debouncedSearch = useDebounce(search, 500);
13
+
14
+ const [blogs, setBlogs] = useState([]);
7
15
 
8
16
  const getBlogs = async () => {
9
- try{
17
+ try {
10
18
 
11
- const res = await api.get("/admin/blogs");
19
+ const res = await api.get(`/admin/blogs/posts?page=${page}&search=${debouncedSearch}`);
12
20
 
13
21
  setBlogs(res.data);
22
+ setTotalPage(res.data.totalPges);
14
23
 
15
- }catch(error){
24
+ } catch (error) {
16
25
  console.log(error);
17
26
  }
18
27
  };
19
28
 
20
- useEffect(()=>{
29
+ useEffect(() => {
21
30
  getBlogs();
22
- },[]);
31
+ }, [page, debouncedSearch]);
23
32
 
24
33
  return (
25
34
  <div>
35
+ <input type="text" value={search} placeholder="search" onChange={(e) => setSearch(e.target.value)} />
26
36
 
27
37
  <h1>Manage Blogs</h1>
28
38
 
29
39
  {
30
- blogs.map((blog)=>(
40
+ blogs.map((blog) => (
31
41
  <div key={blog._id}>
32
42
 
33
43
  <h3>{blog.title}</h3>
@@ -40,6 +50,43 @@ const ManageBlogs = () => {
40
50
  ))
41
51
  }
42
52
 
53
+ {/* pagination */}
54
+ <div>
55
+ <button
56
+ disabled={
57
+ page === 1
58
+ }
59
+ onClick={() =>
60
+ setPage(
61
+ page - 1
62
+ )
63
+ }
64
+ >
65
+ Prev
66
+ </button>
67
+
68
+ <span>
69
+ {" "}
70
+ {page} / {
71
+ totalPages
72
+ }{" "}
73
+ </span>
74
+
75
+ <button
76
+ disabled={
77
+ page ===
78
+ totalPages
79
+ }
80
+ onClick={() =>
81
+ setPage(
82
+ page + 1
83
+ )
84
+ }
85
+ >
86
+ Next
87
+ </button>
88
+ </div>
89
+
43
90
  </div>
44
91
  );
45
92
  };
@@ -13,8 +13,9 @@ import ManageBlogs from "../pages/admin/ManageBlogs";
13
13
  import AdminDashboard from "../pages/admin/AdminDashboard";
14
14
  import AdminLayout from "../layout/AdminLayout";
15
15
  import Register from "../pages/Register";
16
+ import { ProtectedRoute } from "../middleware/ProtectedRoute";
16
17
 
17
- const AppRoutes = () => {
18
+ function AppRoutes() {
18
19
  return (
19
20
  <BrowserRouter>
20
21
  {/* <Navbar /> */}
@@ -25,7 +26,7 @@ const AppRoutes = () => {
25
26
  element={<Home />}
26
27
  />
27
28
 
28
- <Route
29
+ <Route
29
30
  path="/register"
30
31
  element={<Register />}
31
32
  />
@@ -40,22 +41,28 @@ const AppRoutes = () => {
40
41
  element={<CreatePost />}
41
42
  />
42
43
 
43
- <Route path="/admin" element={<AdminLayout />}>
44
- <Route index element={<AdminDashboard />} />
45
- <Route
46
- path="users"
47
- element={<ManageUsers />}
48
- />
49
- <Route
50
- path="blogs"
51
- element={<ManageBlogs />}
52
- />
53
- {/* <Route
44
+ <Route
45
+ element={<ProtectedRoute />}
46
+ >
47
+
48
+ <Route path="/admin" element={<AdminLayout />}>
49
+ <Route index element={<AdminDashboard />} />
50
+ <Route
51
+ path="users"
52
+ element={<ManageUsers />}
53
+ />
54
+ <Route
55
+ path="blogs"
56
+ element={<ManageBlogs />}
57
+ />
58
+ {/* <Route
54
59
  path="settings"
55
60
  element={<Settings />}
56
61
  /> */}
62
+ </Route>
63
+
57
64
  </Route>
58
-
65
+
59
66
  </Routes>
60
67
  </BrowserRouter>
61
68
  );