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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "farheen_blog_app",
3
3
  "private": false,
4
- "version": "0.0.0",
4
+ "version": "0.0.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
package/src/App.css CHANGED
@@ -1,184 +1,234 @@
1
- .counter {
2
- font-size: 16px;
3
- padding: 5px 10px;
4
- border-radius: 5px;
5
- color: var(--accent);
6
- background: var(--accent-bg);
7
- border: 2px solid transparent;
8
- transition: border-color 0.3s;
9
- margin-bottom: 24px;
10
-
11
- &:hover {
12
- border-color: var(--accent-border);
13
- }
14
- &:focus-visible {
15
- outline: 2px solid var(--accent);
16
- outline-offset: 2px;
17
- }
18
- }
19
-
20
- .hero {
21
- position: relative;
22
-
23
- .base,
24
- .framework,
25
- .vite {
26
- inset-inline: 0;
27
- margin: 0 auto;
28
- }
29
-
30
- .base {
31
- width: 170px;
32
- position: relative;
33
- z-index: 0;
34
- }
35
-
36
- .framework,
37
- .vite {
38
- position: absolute;
39
- }
40
-
41
- .framework {
42
- z-index: 1;
43
- top: 34px;
44
- height: 28px;
45
- transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
46
- scale(1.4);
47
- }
48
-
49
- .vite {
50
- z-index: 0;
51
- top: 107px;
52
- height: 26px;
53
- width: auto;
54
- transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
55
- scale(0.8);
56
- }
57
- }
58
-
59
- #center {
60
- display: flex;
61
- flex-direction: column;
62
- gap: 25px;
63
- place-content: center;
64
- place-items: center;
65
- flex-grow: 1;
66
-
67
- @media (max-width: 1024px) {
68
- padding: 32px 20px 24px;
69
- gap: 18px;
70
- }
71
- }
72
-
73
- #next-steps {
74
- display: flex;
75
- border-top: 1px solid var(--border);
76
- text-align: left;
77
-
78
- & > div {
79
- flex: 1 1 0;
80
- padding: 32px;
81
- @media (max-width: 1024px) {
82
- padding: 24px 20px;
83
- }
84
- }
85
-
86
- .icon {
87
- margin-bottom: 16px;
88
- width: 22px;
89
- height: 22px;
90
- }
91
-
92
- @media (max-width: 1024px) {
93
- flex-direction: column;
94
- text-align: center;
95
- }
96
- }
97
-
98
- #docs {
99
- border-right: 1px solid var(--border);
100
-
101
- @media (max-width: 1024px) {
102
- border-right: none;
103
- border-bottom: 1px solid var(--border);
104
- }
105
- }
106
-
107
- #next-steps ul {
108
- list-style: none;
109
- padding: 0;
110
- display: flex;
111
- gap: 8px;
112
- margin: 32px 0 0;
113
-
114
- .logo {
115
- height: 18px;
116
- }
117
-
118
- a {
119
- color: var(--text-h);
120
- font-size: 16px;
121
- border-radius: 6px;
122
- background: var(--social-bg);
123
- display: flex;
124
- padding: 6px 12px;
125
- align-items: center;
126
- gap: 8px;
127
- text-decoration: none;
128
- transition: box-shadow 0.3s;
129
-
130
- &:hover {
131
- box-shadow: var(--shadow);
132
- }
133
- .button-icon {
134
- height: 18px;
135
- width: 18px;
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
- @media (max-width: 1024px) {
140
- margin-top: 20px;
141
- flex-wrap: wrap;
142
- justify-content: center;
222
+ .sidebar{
223
+ width:100%;
224
+ }
143
225
 
144
- li {
145
- flex: 1 1 calc(50% - 8px);
226
+ .cards{
227
+ grid-template-columns:1fr;
146
228
  }
147
229
 
148
- a {
149
- width: 100%;
150
- justify-content: center;
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
- <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>
25
+ <header className="navbar">
9
26
 
10
- <div className="flex gap-4">
11
- <Link to="/">Home</Link>
27
+ <input
28
+ type="text"
29
+ placeholder="Search..."
30
+ />
12
31
 
13
- <Link to="/create">
14
- Create Post
15
- </Link>
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
- </div>
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,13 @@
1
+ import {
2
+ Navigate
3
+ } from "react-router-dom";
4
+
5
+ export const ProtectedRoutes = ({ children }) => {
6
+ const token = localStorage.getItem("token");
7
+
8
+ if (!token) {
9
+ return <Navigate to="/login" />
10
+ }
11
+
12
+ return children;
13
+ }
@@ -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;
@@ -1,40 +1,65 @@
1
1
  import {
2
- BrowserRouter,
3
- Routes,
4
- Route,
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
- 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
- </Routes>
36
- </BrowserRouter>
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;