aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components')
-rw-r--r--frontend/src/components/Navigation.tsx26
-rw-r--r--frontend/src/components/ProtectedRoute.tsx32
-rw-r--r--frontend/src/components/index.ts1
3 files changed, 57 insertions, 2 deletions
diff --git a/frontend/src/components/Navigation.tsx b/frontend/src/components/Navigation.tsx
index 08a523f..d6e20c9 100644
--- a/frontend/src/components/Navigation.tsx
+++ b/frontend/src/components/Navigation.tsx
@@ -2,11 +2,22 @@ import {
faBookOpen,
faCircleCheck,
faGear,
+ faRightFromBracket,
} from "@fortawesome/free-solid-svg-icons";
-import { Link } from "wouter";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link, useLocation } from "wouter";
+import { useAuth } from "../contexts/AuthContext";
import { MenuItem } from "./MenuItem";
export function Navigation() {
+ const { logout, user } = useAuth();
+ const [, setLocation] = useLocation();
+
+ const handleLogout = async () => {
+ await logout();
+ setLocation("/login");
+ };
+
return (
<nav className="bg-white shadow-sm border-b border-gray-200">
<div className="container mx-auto px-4">
@@ -14,10 +25,21 @@ export function Navigation() {
<Link href="/" className="text-xl font-bold text-gray-900">
feedaka
</Link>
- <div className="flex space-x-6">
+ <div className="flex items-center space-x-6">
<MenuItem path="/unread" label="Unread" icon={faBookOpen} />
<MenuItem path="/read" label="Read" icon={faCircleCheck} />
<MenuItem path="/settings" label="Settings" icon={faGear} />
+ {user && (
+ <button
+ type="button"
+ onClick={handleLogout}
+ className="flex items-center space-x-2 text-gray-600 hover:text-gray-900"
+ title={`Logout (${user.username})`}
+ >
+ <FontAwesomeIcon icon={faRightFromBracket} />
+ <span>Logout</span>
+ </button>
+ )}
</div>
</div>
</div>
diff --git a/frontend/src/components/ProtectedRoute.tsx b/frontend/src/components/ProtectedRoute.tsx
new file mode 100644
index 0000000..0cfef42
--- /dev/null
+++ b/frontend/src/components/ProtectedRoute.tsx
@@ -0,0 +1,32 @@
+import type { ReactNode } from "react";
+import { Redirect } from "wouter";
+import { useAuth } from "../contexts/AuthContext";
+
+interface Props {
+ children: ReactNode;
+}
+
+export function ProtectedRoute({ children }: Props) {
+ const { user, isLoading } = useAuth();
+
+ if (isLoading) {
+ return (
+ <div
+ style={{
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ minHeight: "100vh",
+ }}
+ >
+ Loading...
+ </div>
+ );
+ }
+
+ if (!user) {
+ return <Redirect to="/login" />;
+ }
+
+ return <>{children}</>;
+}
diff --git a/frontend/src/components/index.ts b/frontend/src/components/index.ts
index 8253800..06f4c29 100644
--- a/frontend/src/components/index.ts
+++ b/frontend/src/components/index.ts
@@ -4,3 +4,4 @@ export { FeedList } from "./FeedList";
export { Layout } from "./Layout";
export { MenuItem } from "./MenuItem";
export { Navigation } from "./Navigation";
+export { ProtectedRoute } from "./ProtectedRoute";