farheen_blog_app 0.0.0 → 0.0.1
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 +1 -1
- package/src/App.css +228 -178
- package/src/components/Navbar.jsx +37 -13
- package/src/components/admin/AdminSidebar.jsx +37 -0
- package/src/components/admin/UserTable.jsx +29 -0
- package/src/layout/AdminLayout.jsx +21 -0
- package/src/middleware/ProtectedRoute.jsx +13 -0
- package/src/pages/admin/AdminDashboard.jsx +72 -0
- package/src/pages/admin/EditBlog.jsx +0 -0
- package/src/pages/admin/EditUser.jsx +0 -0
- package/src/pages/admin/ManageBlogs.jsx +47 -0
- package/src/pages/admin/ManageUsers.jsx +44 -0
- package/src/routes/AppRoutes.jsx +53 -28
package/package.json
CHANGED
package/src/App.css
CHANGED
|
@@ -1,184 +1,234 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
padding:
|
|
4
|
-
border-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
*{
|
|
2
|
+
margin:0;
|
|
3
|
+
padding:0;
|
|
4
|
+
box-sizing:border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body{
|
|
8
|
+
font-family:Inter,sans-serif;
|
|
9
|
+
background:#f5f7fb;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.layout{
|
|
13
|
+
display:flex;
|
|
14
|
+
min-height:100vh;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Sidebar */
|
|
18
|
+
|
|
19
|
+
.sidebar{
|
|
20
|
+
width:260px;
|
|
21
|
+
background:#111827;
|
|
22
|
+
color:white;
|
|
23
|
+
padding:20px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.logo{
|
|
27
|
+
margin-bottom:40px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sidebar nav{
|
|
31
|
+
display:flex;
|
|
32
|
+
flex-direction:column;
|
|
33
|
+
gap:10px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sidebar a{
|
|
37
|
+
text-decoration:none;
|
|
38
|
+
color:white;
|
|
39
|
+
padding:12px;
|
|
40
|
+
border-radius:8px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sidebar a:hover{
|
|
44
|
+
background:#1f2937;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Main Content */
|
|
48
|
+
|
|
49
|
+
.main-content{
|
|
50
|
+
flex:1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Navbar */
|
|
54
|
+
|
|
55
|
+
.navbar{
|
|
56
|
+
background:white;
|
|
57
|
+
padding:15px 30px;
|
|
58
|
+
display:flex;
|
|
59
|
+
justify-content:space-between;
|
|
60
|
+
align-items:center;
|
|
61
|
+
box-shadow:0 2px 5px rgba(0,0,0,.05);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.navbar input{
|
|
65
|
+
width:350px;
|
|
66
|
+
padding:10px;
|
|
67
|
+
border:1px solid #ddd;
|
|
68
|
+
border-radius:8px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.navbar-right{
|
|
72
|
+
display:flex;
|
|
73
|
+
align-items:center;
|
|
74
|
+
gap:15px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.navbar-right img{
|
|
78
|
+
width:40px;
|
|
79
|
+
height:40px;
|
|
80
|
+
border-radius:50%;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Dashboard */
|
|
84
|
+
|
|
85
|
+
.dashboard{
|
|
86
|
+
padding:30px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.cards{
|
|
90
|
+
display:grid;
|
|
91
|
+
grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
|
|
92
|
+
gap:20px;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.card{
|
|
96
|
+
background:white;
|
|
97
|
+
padding:25px;
|
|
98
|
+
border-radius:12px;
|
|
99
|
+
box-shadow:0 2px 8px rgba(0,0,0,.05);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.card h4{
|
|
103
|
+
color:#6b7280;
|
|
104
|
+
margin-bottom:10px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.card h2{
|
|
108
|
+
color:#111827;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.dashboard-container{
|
|
112
|
+
display:flex;
|
|
113
|
+
min-height:100vh;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Sidebar */
|
|
117
|
+
|
|
118
|
+
.sidebar{
|
|
119
|
+
width:250px;
|
|
120
|
+
background:#1f2937;
|
|
121
|
+
color:white;
|
|
122
|
+
padding:20px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.sidebar h2{
|
|
126
|
+
margin-bottom:30px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.sidebar ul{
|
|
130
|
+
list-style:none;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.sidebar ul li{
|
|
134
|
+
padding:12px;
|
|
135
|
+
cursor:pointer;
|
|
136
|
+
border-radius:6px;
|
|
137
|
+
margin-bottom:10px;
|
|
138
|
+
transition:0.3s;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.sidebar ul li:hover{
|
|
142
|
+
background:#374151;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Main Content */
|
|
146
|
+
|
|
147
|
+
.dashboard-content{
|
|
148
|
+
flex:1;
|
|
149
|
+
padding:30px;
|
|
150
|
+
background:#f5f7fa;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.dashboard-content h1{
|
|
154
|
+
margin-bottom:25px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Cards */
|
|
158
|
+
|
|
159
|
+
.cards{
|
|
160
|
+
display:grid;
|
|
161
|
+
grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
|
|
162
|
+
gap:20px;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.card{
|
|
166
|
+
background:white;
|
|
167
|
+
padding:25px;
|
|
168
|
+
border-radius:10px;
|
|
169
|
+
box-shadow:0 2px 10px rgba(0,0,0,0.1);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.card h3{
|
|
173
|
+
color:#555;
|
|
174
|
+
margin-bottom:10px;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.card p{
|
|
178
|
+
font-size:28px;
|
|
179
|
+
font-weight:bold;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.user-table{
|
|
183
|
+
width:100%;
|
|
184
|
+
border-collapse:collapse;
|
|
185
|
+
margin-top:20px;
|
|
186
|
+
background:white;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* user table */
|
|
190
|
+
.user-table th,
|
|
191
|
+
.user-table td{
|
|
192
|
+
border:1px solid #ddd;
|
|
193
|
+
padding:12px;
|
|
194
|
+
text-align:left;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.user-table th{
|
|
198
|
+
background:#1f2937;
|
|
199
|
+
color:white;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.delete-btn{
|
|
203
|
+
background:red;
|
|
204
|
+
color:white;
|
|
205
|
+
border:none;
|
|
206
|
+
padding:8px 15px;
|
|
207
|
+
border-radius:5px;
|
|
208
|
+
cursor:pointer;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.delete-btn:hover{
|
|
212
|
+
opacity:0.8;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* mobile responsive */
|
|
216
|
+
@media(max-width:768px){
|
|
217
|
+
|
|
218
|
+
.dashboard-container{
|
|
219
|
+
flex-direction:column;
|
|
136
220
|
}
|
|
137
|
-
}
|
|
138
221
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
justify-content: center;
|
|
222
|
+
.sidebar{
|
|
223
|
+
width:100%;
|
|
224
|
+
}
|
|
143
225
|
|
|
144
|
-
|
|
145
|
-
|
|
226
|
+
.cards{
|
|
227
|
+
grid-template-columns:1fr;
|
|
146
228
|
}
|
|
147
229
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
box-sizing: border-box;
|
|
230
|
+
.user-table{
|
|
231
|
+
display:block;
|
|
232
|
+
overflow-x:auto;
|
|
152
233
|
}
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
#spacer {
|
|
157
|
-
height: 88px;
|
|
158
|
-
border-top: 1px solid var(--border);
|
|
159
|
-
@media (max-width: 1024px) {
|
|
160
|
-
height: 48px;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.ticks {
|
|
165
|
-
position: relative;
|
|
166
|
-
width: 100%;
|
|
167
|
-
|
|
168
|
-
&::before,
|
|
169
|
-
&::after {
|
|
170
|
-
content: '';
|
|
171
|
-
position: absolute;
|
|
172
|
-
top: -4.5px;
|
|
173
|
-
border: 5px solid transparent;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
&::before {
|
|
177
|
-
left: 0;
|
|
178
|
-
border-left-color: var(--border);
|
|
179
|
-
}
|
|
180
|
-
&::after {
|
|
181
|
-
right: 0;
|
|
182
|
-
border-right-color: var(--border);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
234
|
+
}
|
|
@@ -1,24 +1,48 @@
|
|
|
1
1
|
import { Link } from "react-router-dom";
|
|
2
2
|
|
|
3
3
|
const Navbar = () => {
|
|
4
|
+
// return (
|
|
5
|
+
// <div className="bg-black text-white px-6 py-4 flex justify-between">
|
|
6
|
+
// <h1 className="text-2xl font-bold">
|
|
7
|
+
// Blog App
|
|
8
|
+
// </h1>
|
|
9
|
+
|
|
10
|
+
// <div className="flex gap-4">
|
|
11
|
+
// <Link to="/">Home</Link>
|
|
12
|
+
|
|
13
|
+
// <Link to="/create">
|
|
14
|
+
// Create Post
|
|
15
|
+
// </Link>
|
|
16
|
+
|
|
17
|
+
// <Link to="/login">
|
|
18
|
+
// Login
|
|
19
|
+
// </Link>
|
|
20
|
+
// </div>
|
|
21
|
+
// </div>
|
|
22
|
+
// );
|
|
23
|
+
|
|
4
24
|
return (
|
|
5
|
-
<
|
|
6
|
-
<h1 className="text-2xl font-bold">
|
|
7
|
-
Blog App
|
|
8
|
-
</h1>
|
|
25
|
+
<header className="navbar">
|
|
9
26
|
|
|
10
|
-
<
|
|
11
|
-
|
|
27
|
+
<input
|
|
28
|
+
type="text"
|
|
29
|
+
placeholder="Search..."
|
|
30
|
+
/>
|
|
12
31
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
<div className="navbar-right">
|
|
33
|
+
|
|
34
|
+
<button>
|
|
35
|
+
🔔
|
|
36
|
+
</button>
|
|
37
|
+
|
|
38
|
+
<img
|
|
39
|
+
src="https://i.pravatar.cc/40"
|
|
40
|
+
alt="profile"
|
|
41
|
+
/>
|
|
16
42
|
|
|
17
|
-
<Link to="/login">
|
|
18
|
-
Login
|
|
19
|
-
</Link>
|
|
20
43
|
</div>
|
|
21
|
-
|
|
44
|
+
|
|
45
|
+
</header>
|
|
22
46
|
);
|
|
23
47
|
};
|
|
24
48
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Link } from "react-router-dom";
|
|
2
|
+
|
|
3
|
+
const AdminSidebar = () => {
|
|
4
|
+
return (
|
|
5
|
+
<aside className="sidebar">
|
|
6
|
+
|
|
7
|
+
<h2 className="logo">Blogify</h2>
|
|
8
|
+
|
|
9
|
+
<nav>
|
|
10
|
+
|
|
11
|
+
<Link to="/admin/dashboard">
|
|
12
|
+
Dashboard
|
|
13
|
+
</Link>
|
|
14
|
+
|
|
15
|
+
<Link to="/admin/blogs">
|
|
16
|
+
Blogs
|
|
17
|
+
</Link>
|
|
18
|
+
|
|
19
|
+
<Link to="/admin/users">
|
|
20
|
+
Users
|
|
21
|
+
</Link>
|
|
22
|
+
|
|
23
|
+
<Link to="/admin/categories">
|
|
24
|
+
Categories
|
|
25
|
+
</Link>
|
|
26
|
+
|
|
27
|
+
<Link to="/admin/settings">
|
|
28
|
+
Settings
|
|
29
|
+
</Link>
|
|
30
|
+
|
|
31
|
+
</nav>
|
|
32
|
+
|
|
33
|
+
</aside>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default Sidebar;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const UserTable = () => {
|
|
2
|
+
return (
|
|
3
|
+
<table className="user-table">
|
|
4
|
+
<thead>
|
|
5
|
+
<tr>
|
|
6
|
+
<th>Name</th>
|
|
7
|
+
<th>Email</th>
|
|
8
|
+
<th>Role</th>
|
|
9
|
+
<th>Action</th>
|
|
10
|
+
</tr>
|
|
11
|
+
</thead>
|
|
12
|
+
|
|
13
|
+
<tbody>
|
|
14
|
+
<tr>
|
|
15
|
+
<td>Farheen</td>
|
|
16
|
+
<td>farheen@gmail.com</td>
|
|
17
|
+
<td>User</td>
|
|
18
|
+
<td>
|
|
19
|
+
<button className="delete-btn">
|
|
20
|
+
Delete
|
|
21
|
+
</button>
|
|
22
|
+
</td>
|
|
23
|
+
</tr>
|
|
24
|
+
</tbody>
|
|
25
|
+
</table>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default UserTable;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
import { Outlet } from "react-router-dom";
|
|
3
|
+
import AdminSidebar from "../components/admin/AdminSidebar";
|
|
4
|
+
import Navbar from "../components/Navbar";
|
|
5
|
+
|
|
6
|
+
const AdminLayout = () => {
|
|
7
|
+
return (
|
|
8
|
+
<div className="layout">
|
|
9
|
+
|
|
10
|
+
<AdminSidebar />
|
|
11
|
+
|
|
12
|
+
<div className="main-content">
|
|
13
|
+
<Navbar />
|
|
14
|
+
<Outlet />
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default AdminLayout;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import api from "../../services/api";
|
|
3
|
+
|
|
4
|
+
const AdminDashboard = () => {
|
|
5
|
+
|
|
6
|
+
const [data, setData] = useState({});
|
|
7
|
+
|
|
8
|
+
const getDashboard = async () => {
|
|
9
|
+
try {
|
|
10
|
+
|
|
11
|
+
const res = await api.get("/admin/dashboard");
|
|
12
|
+
|
|
13
|
+
setData(res.data);
|
|
14
|
+
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.log(error);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
getDashboard();
|
|
22
|
+
}, []);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className="dashboard-container">
|
|
26
|
+
|
|
27
|
+
<aside className="sidebar">
|
|
28
|
+
<h2>Admin Panel</h2>
|
|
29
|
+
|
|
30
|
+
<ul>
|
|
31
|
+
<li>Dashboard</li>
|
|
32
|
+
<li>Users</li>
|
|
33
|
+
<li>Blogs</li>
|
|
34
|
+
<li>Settings</li>
|
|
35
|
+
</ul>
|
|
36
|
+
</aside>
|
|
37
|
+
|
|
38
|
+
<main className="dashboard-content">
|
|
39
|
+
|
|
40
|
+
<h1>Dashboard</h1>
|
|
41
|
+
|
|
42
|
+
<div className="cards">
|
|
43
|
+
|
|
44
|
+
<div className="card">
|
|
45
|
+
<h3>Total Users</h3>
|
|
46
|
+
<p>150</p>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div className="card">
|
|
50
|
+
<h3>Total Blogs</h3>
|
|
51
|
+
<p>450</p>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div className="card">
|
|
55
|
+
<h3>Published Blogs</h3>
|
|
56
|
+
<p>400</p>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="card">
|
|
60
|
+
<h3>Draft Blogs</h3>
|
|
61
|
+
<p>50</p>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
</main>
|
|
67
|
+
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default AdminDashboard;
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import api from "../../services/api";
|
|
3
|
+
|
|
4
|
+
const ManageBlogs = () => {
|
|
5
|
+
|
|
6
|
+
const [blogs,setBlogs] = useState([]);
|
|
7
|
+
|
|
8
|
+
const getBlogs = async () => {
|
|
9
|
+
try{
|
|
10
|
+
|
|
11
|
+
const res = await api.get("/admin/blogs");
|
|
12
|
+
|
|
13
|
+
setBlogs(res.data);
|
|
14
|
+
|
|
15
|
+
}catch(error){
|
|
16
|
+
console.log(error);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
useEffect(()=>{
|
|
21
|
+
getBlogs();
|
|
22
|
+
},[]);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div>
|
|
26
|
+
|
|
27
|
+
<h1>Manage Blogs</h1>
|
|
28
|
+
|
|
29
|
+
{
|
|
30
|
+
blogs.map((blog)=>(
|
|
31
|
+
<div key={blog._id}>
|
|
32
|
+
|
|
33
|
+
<h3>{blog.title}</h3>
|
|
34
|
+
|
|
35
|
+
<p>
|
|
36
|
+
{blog.createdBy?.name}
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
</div>
|
|
40
|
+
))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default ManageBlogs;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import api from "../../services/api";
|
|
3
|
+
|
|
4
|
+
const ManageUsers = () => {
|
|
5
|
+
|
|
6
|
+
const [users,setUsers] = useState([]);
|
|
7
|
+
|
|
8
|
+
const getUsers = async () => {
|
|
9
|
+
try{
|
|
10
|
+
|
|
11
|
+
const res = await api.get("/admin/users");
|
|
12
|
+
|
|
13
|
+
setUsers(res.data);
|
|
14
|
+
|
|
15
|
+
}catch(error){
|
|
16
|
+
console.log(error);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
useEffect(()=>{
|
|
21
|
+
getUsers();
|
|
22
|
+
},[]);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div>
|
|
26
|
+
|
|
27
|
+
<h1>Manage Users</h1>
|
|
28
|
+
|
|
29
|
+
{
|
|
30
|
+
users.map((user)=>(
|
|
31
|
+
<div key={user._id}>
|
|
32
|
+
|
|
33
|
+
<h3>{user.name}</h3>
|
|
34
|
+
<p>{user.email}</p>
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default ManageUsers;
|
package/src/routes/AppRoutes.jsx
CHANGED
|
@@ -1,40 +1,65 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
BrowserRouter,
|
|
3
|
+
Routes,
|
|
4
|
+
Route,
|
|
5
5
|
} from "react-router-dom";
|
|
6
6
|
|
|
7
7
|
import Navbar from "../components/Navbar";
|
|
8
|
-
|
|
9
8
|
import Home from "../pages/Home";
|
|
10
|
-
|
|
11
9
|
import Login from "../pages/Login";
|
|
12
|
-
|
|
13
10
|
import CreatePost from "../pages/CreatePost";
|
|
11
|
+
import ManageUsers from "../pages/admin/ManageUsers";
|
|
12
|
+
import ManageBlogs from "../pages/admin/ManageBlogs";
|
|
13
|
+
import AdminDashboard from "../pages/admin/AdminDashboard";
|
|
14
14
|
|
|
15
15
|
const AppRoutes = () => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
16
|
+
return (
|
|
17
|
+
<BrowserRouter>
|
|
18
|
+
<Navbar />
|
|
19
|
+
|
|
20
|
+
<Routes>
|
|
21
|
+
<Route
|
|
22
|
+
path="/"
|
|
23
|
+
element={<Home />}
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
<Route
|
|
27
|
+
path="/login"
|
|
28
|
+
element={<Login />}
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<Route
|
|
32
|
+
path="/create"
|
|
33
|
+
element={<CreatePost />}
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
<Route
|
|
37
|
+
path="/admin"
|
|
38
|
+
element={
|
|
39
|
+
|
|
40
|
+
<AdminDashboard />
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<Route
|
|
46
|
+
path="/admin/users"
|
|
47
|
+
element={
|
|
48
|
+
<ManageUsers />
|
|
49
|
+
}
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<Route
|
|
53
|
+
path="/admin/blogs"
|
|
54
|
+
element={
|
|
55
|
+
<ManageBlogs />
|
|
56
|
+
}
|
|
57
|
+
/>
|
|
58
|
+
</Routes>
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
</BrowserRouter>
|
|
62
|
+
);
|
|
38
63
|
};
|
|
39
64
|
|
|
40
65
|
export default AppRoutes;
|