From 7a08913f1155074248dd4a4817e47a43f6991adb Mon Sep 17 00:00:00 2001 From: ADARSHsri2004 Date: Sat, 8 Nov 2025 23:14:20 +0530 Subject: [PATCH] feat: added dashboard for active sessions --- frontend/package-lock.json | 8 +- frontend/package.json | 2 +- frontend/src/App.tsx | 2 + frontend/src/pages/ActiveSessions.tsx | 176 ++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 frontend/src/pages/ActiveSessions.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 453820e..d339b99 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,7 +16,7 @@ "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.14", "@tanstack/react-query": "^5.90.3", - "axios": "^1.12.2", + "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "framer-motion": "^12.23.24", @@ -3194,9 +3194,9 @@ } }, "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", diff --git a/frontend/package.json b/frontend/package.json index d37ea95..2ec8c5c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,7 +19,7 @@ "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.14", "@tanstack/react-query": "^5.90.3", - "axios": "^1.12.2", + "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "framer-motion": "^12.23.24", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9022d99..87ea27c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -14,6 +14,7 @@ import JoinRoom from "./pages/JoinRoom.js"; import InRoom from "./pages/InRoom.js"; import CreateRoomLobby from "./pages/CreateRoomLobby.js"; import CreateRoom from "./pages/CreateRoom.js"; +import ActiveSessions from "./pages/ActiveSessions.js"; const queryClient = new QueryClient(); const App = () => ( @@ -33,6 +34,7 @@ const App = () => ( } /> {/* ✅ */} } /> } /> + } /> diff --git a/frontend/src/pages/ActiveSessions.tsx b/frontend/src/pages/ActiveSessions.tsx new file mode 100644 index 0000000..40b744b --- /dev/null +++ b/frontend/src/pages/ActiveSessions.tsx @@ -0,0 +1,176 @@ +import React, { useEffect, useState } from "react"; +import { motion } from "framer-motion"; +import { Button } from "../components/ui/button.js"; +import { Card, CardContent } from "../components/ui/card.js"; +import { + Loader2, + Laptop, + Smartphone, + MonitorSmartphone, + XCircle, + CheckCircle2, +} from "lucide-react"; + +interface Session { + _id: string; + userAgent: string; + ipAddress: string; + createdAt: string; +} + +const dummySessions: Session[] = [ + { + _id: "1", + userAgent: "Chrome on Windows 11", + ipAddress: "192.168.1.24", + createdAt: "2025-11-08T12:15:00Z", + }, + { + _id: "2", + userAgent: "Safari on iPhone 15", + ipAddress: "10.0.0.45", + createdAt: "2025-11-07T20:30:00Z", + }, + { + _id: "3", + userAgent: "Edge on MacBook Air", + ipAddress: "172.16.0.88", + createdAt: "2025-11-06T09:00:00Z", + }, +]; + +const ActiveSessions: React.FC = () => { + const [sessions, setSessions] = useState([]); + const [loading, setLoading] = useState(true); + const [revokingId, setRevokingId] = useState(null); + const currentDevice = "Chrome on Windows 11"; // simulate current device + + useEffect(() => { + const timer = setTimeout(() => { + setSessions(dummySessions); + setLoading(false); + }, 1000); + return () => clearTimeout(timer); + }, []); + + const revokeSession = (id: string) => { + setRevokingId(id); + setTimeout(() => { + setSessions((prev) => prev.filter((s) => s._id !== id)); + setRevokingId(null); + }, 800); + }; + + const getIcon = (ua: string) => { + if (/iPhone|Android/i.test(ua)) return ; + if (/Mac|Windows/i.test(ua)) + return ; + return ; + }; + + if (loading) + return ( +
+ + Loading sessions... +
+ ); + + return ( + +
+

+ Active Sessions +

+

+ Manage your logged-in devices securely. +

+
+ + {sessions.length === 0 ? ( + + No active sessions found. + + ) : ( +
+ {sessions.map((session, i) => { + const isCurrent = session.userAgent === currentDevice; + return ( + + + +
+
+ {getIcon(session.userAgent)} +
+ +
+

+ {session.userAgent} + {isCurrent && ( + + This Device + + )} +

+

+ IP: {session.ipAddress} +

+

+ Logged in:{" "} + {new Date(session.createdAt).toLocaleString()} +

+
+
+ + +
+
+
+ ); + })} +
+ )} +
+ ); +}; + +export default ActiveSessions;