Skip to content

Commit da62d48

Browse files
Merge pull request #1 from Your-Ehsan/development
Development
2 parents e285e35 + 2647156 commit da62d48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+5067
-1963
lines changed

client/components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": false,
6+
"tailwind": {
7+
"config": "tailwind.config.js",
8+
"css": "src/index.css",
9+
"baseColor": "zinc",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

client/jsconfig.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"paths": {
5+
"@/*": ["./src/*"]
6+
}
7+
}
8+
}

client/package.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,23 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"@radix-ui/react-avatar": "^1.1.2",
14+
"@radix-ui/react-collapsible": "^1.1.2",
15+
"@radix-ui/react-dialog": "^1.1.3",
16+
"@radix-ui/react-dropdown-menu": "^2.1.3",
17+
"@radix-ui/react-separator": "^1.1.1",
18+
"@radix-ui/react-slot": "^1.1.1",
19+
"@radix-ui/react-tooltip": "^1.1.6",
20+
"@tanstack/react-query": "^5.62.7",
21+
"class-variance-authority": "^0.7.1",
22+
"clsx": "^2.1.1",
23+
"lucide-react": "^0.468.0",
1324
"react": "^18.2.0",
1425
"react-dom": "^18.2.0",
15-
"react-router-dom": "^6.14.2"
26+
"react-router-dom": "^6.14.2",
27+
"tailwind-merge": "^2.5.5",
28+
"tailwindcss-animate": "^1.0.7",
29+
"zustand": "^5.0.2"
1630
},
1731
"devDependencies": {
1832
"@types/react": "^18.2.15",

client/src/App.jsx

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,78 @@
11
import PropTypes from "prop-types";
22
import {
3-
Navigate,
4-
Route,
5-
RouterProvider,
6-
createBrowserRouter,
7-
createRoutesFromElements,
3+
Navigate,
4+
Route,
5+
RouterProvider,
6+
createBrowserRouter,
7+
createRoutesFromElements,
88
} from "react-router-dom";
99
import MainLayout from "./layouts/MainLayout";
1010
import Home from "./pages/Home";
1111
import Login, { LoginAction } from "./pages/Login";
1212
import Signup, { SignupAction } from "./pages/Signup";
13-
import { HomeLoader } from "./utilities/HomeLoader";
1413
import { NotesContextProvider } from "./contexts/NotesContext";
14+
import { getAuthToken } from "./lib/utils";
15+
import { useAuth } from "./hooks/useAuth";
16+
import { CreateNotePage } from "./pages/CreateNotePage";
17+
import { EditNotePage } from "./pages/EditNotePage";
18+
import { NotePage } from "./pages/NotePage";
1519

1620
function App() {
17-
const ProtectedRoute = ({ children }) => {
18-
if (localStorage.getItem("token") === null) {
19-
return <Navigate to={"login"} replace />;
20-
}
21-
return children;
22-
};
21+
const ProtectedRoute = ({ children }) => {
22+
const { authToken } = useAuth();
23+
const token = getAuthToken();
24+
if (authToken === null || token === null) {
25+
return <Navigate to={"login"} replace />;
26+
}
27+
return children;
28+
};
2329

24-
ProtectedRoute.propTypes = {
25-
children: PropTypes.element,
26-
};
30+
ProtectedRoute.propTypes = {
31+
children: PropTypes.element,
32+
};
2733

28-
return (
29-
<RouterProvider
30-
router={createBrowserRouter(
31-
createRoutesFromElements(
32-
<Route element={<MainLayout />}>
33-
{/* TODO: convert this ⬆ to versions */}
34-
<Route
35-
index
36-
errorElement={<h1>error occured</h1>}
37-
loader={HomeLoader}
38-
element={
39-
<ProtectedRoute>
40-
<NotesContextProvider>
41-
<Home />
42-
</NotesContextProvider>
43-
</ProtectedRoute>
44-
}
45-
/>
46-
<Route action={LoginAction} path="login" element={<Login />} />
47-
<Route path="signup" action={SignupAction} element={<Signup />} />
48-
</Route>,
49-
),
50-
)}
51-
/>
52-
);
34+
return (
35+
<RouterProvider
36+
router={createBrowserRouter(
37+
createRoutesFromElements(
38+
<>
39+
<Route
40+
element={
41+
<ProtectedRoute>
42+
<NotesContextProvider>
43+
<MainLayout />
44+
</NotesContextProvider>
45+
</ProtectedRoute>
46+
}
47+
>
48+
<Route
49+
index
50+
errorElement={<h1>error occurred</h1>}
51+
element={<Home />}
52+
/>
53+
<Route
54+
path="create"
55+
errorElement={<h1>error occurred</h1>}
56+
element={<CreateNotePage />}
57+
/>
58+
<Route
59+
path="edit"
60+
errorElement={<h1>error occurred</h1>}
61+
element={<EditNotePage />}
62+
/>
63+
<Route
64+
path=":id"
65+
errorElement={<h1>error occurred</h1>}
66+
element={<NotePage />}
67+
/>
68+
</Route>
69+
<Route action={LoginAction} path="login" element={<Login />} />
70+
<Route path="signup" action={SignupAction} element={<Signup />} />
71+
</>
72+
)
73+
)}
74+
/>
75+
);
5376
}
5477

5578
export default App;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { NotebookPen, NotebookTabsIcon, Settings2 } from "lucide-react";
2+
3+
import {
4+
Sidebar,
5+
SidebarContent,
6+
SidebarFooter,
7+
SidebarHeader,
8+
SidebarRail,
9+
} from "@/components/ui/sidebar";
10+
import { NavMain } from "./nav-menu";
11+
import { NavUser } from "./nav-user";
12+
import { TeamSwitcher } from "./teams";
13+
14+
// This is sample data.
15+
const data = {
16+
teams: [
17+
{
18+
name: "Your Notes",
19+
logo: NotebookPen,
20+
plan: "free",
21+
link: "/",
22+
},
23+
],
24+
navMain: [
25+
{
26+
title: "Notes",
27+
url: "#",
28+
icon: NotebookTabsIcon,
29+
isActive: true,
30+
items: [
31+
{
32+
title: "Create",
33+
url: "/create",
34+
},
35+
],
36+
},
37+
{
38+
title: "Settings",
39+
url: "#",
40+
icon: Settings2,
41+
items: [
42+
{
43+
title: "General",
44+
url: "#",
45+
},
46+
{
47+
title: "Team",
48+
url: "#",
49+
},
50+
{
51+
title: "Billing",
52+
url: "#",
53+
},
54+
{
55+
title: "Limits",
56+
url: "#",
57+
},
58+
],
59+
},
60+
],
61+
};
62+
63+
export function AppSidebar({ ...props }) {
64+
return (
65+
<Sidebar collapsible="icon" {...props}>
66+
<SidebarHeader>
67+
<TeamSwitcher teams={data.teams} />{" "}
68+
</SidebarHeader>
69+
<SidebarContent>
70+
<NavMain items={data.navMain} />
71+
</SidebarContent>
72+
<SidebarFooter>
73+
<NavUser />
74+
</SidebarFooter>
75+
<SidebarRail />
76+
</Sidebar>
77+
);
78+
}

client/src/components/Header.jsx

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,46 @@
11
import { Link, NavLink } from "react-router-dom";
2+
import { useAuth } from "../hooks/useAuth";
23

34
const Header = () => {
4-
const sameClasses = {
5-
headerLink:
6-
"p-4 duration-200 border-b-2 border-green-500 border-opacity-0 cursor-pointer hover:border-opacity-100 hover:text-green-500",
7-
};
8-
return (
9-
<header className="sticky top-0 flex items-center justify-between px-8 bg-white shadow-md header py-02">
10-
<Link to={"/"}>
11-
<h1 className="text-4xl">note App</h1>
12-
</Link>
13-
<div className="flex justify-end w-3/12">
14-
<div className="flex items-center">
15-
{localStorage.getItem("token") === null ? (
16-
<div className="flex">
17-
<NavLink
18-
className={({ isActive }) => (isActive ? "font-bold" : "")}
19-
to={"login"}
20-
>
21-
<div className={sameClasses.headerLink}>Login</div>
22-
</NavLink>
23-
<NavLink
24-
className={({ isActive }) => (isActive ? "font-bold" : "")}
25-
to={"signup"}
26-
>
27-
<div className={sameClasses.headerLink}>Sign Up</div>
28-
</NavLink>
29-
</div>
30-
) : (
31-
<Link to={"login"} onClick={() => localStorage.removeItem("token")}>
32-
<div className={sameClasses.headerLink}>Log Out</div>
33-
</Link>
34-
)}
35-
</div>
36-
</div>
37-
</header>
38-
);
5+
const { authToken, setAuthToken } = useAuth();
6+
const sameClasses = {
7+
headerLink:
8+
"p-4 duration-200 border-b-2 border-green-500 border-opacity-0 cursor-pointer hover:border-opacity-100 hover:text-green-500",
9+
};
10+
return (
11+
<header className="sticky top-0 flex items-center justify-between px-8 bg-white shadow-md header py-02">
12+
<Link to={"/"}>
13+
<h1 className="text-4xl">note App</h1>
14+
</Link>
15+
<div className="flex justify-end w-3/12">
16+
<div className="flex items-center">
17+
{authToken === null ? (
18+
<div className="flex">
19+
<NavLink
20+
className={({ isActive }) => (isActive ? "font-bold" : "")}
21+
to={"login"}
22+
>
23+
<div className={sameClasses.headerLink}>Login</div>
24+
</NavLink>
25+
<NavLink
26+
className={({ isActive }) => (isActive ? "font-bold" : "")}
27+
to={"signup"}
28+
>
29+
<div className={sameClasses.headerLink}>Sign Up</div>
30+
</NavLink>
31+
</div>
32+
) : (
33+
<Link
34+
to={"login"}
35+
onClick={() => setAuthToken({ authToken: null })}
36+
>
37+
<div className={sameClasses.headerLink}>Log Out</div>
38+
</Link>
39+
)}
40+
</div>
41+
</div>
42+
</header>
43+
);
3944
};
4045

4146
export default Header;

0 commit comments

Comments
 (0)