diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json deleted file mode 100644 index 0e81f9b..0000000 --- a/ui/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} \ No newline at end of file diff --git a/ui/.gitignore b/ui/.gitignore deleted file mode 100644 index fd3dbb5..0000000 --- a/ui/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/ui/README.md b/ui/README.md deleted file mode 100644 index c403366..0000000 --- a/ui/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/ui/app/api/overview/get-all/route.ts b/ui/app/api/overview/get-all/route.ts deleted file mode 100644 index 857ab7c..0000000 --- a/ui/app/api/overview/get-all/route.ts +++ /dev/null @@ -1,19 +0,0 @@ -export async function GET(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/overview/get-all` - - if (endPoint) { - try { - const res = await fetch(endPoint, { - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/password/forget-request/route.ts b/ui/app/api/password/forget-request/route.ts deleted file mode 100644 index a6a637c..0000000 --- a/ui/app/api/password/forget-request/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/password/forget-request`; - - const { email } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - email - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/password/reset/route.ts b/ui/app/api/password/reset/route.ts deleted file mode 100644 index c46bc1e..0000000 --- a/ui/app/api/password/reset/route.ts +++ /dev/null @@ -1,27 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/password/reset`; - - const { email, old_password, new_password } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - email, - old_password, - new_password - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/delete-all/route.ts b/ui/app/api/session/delete-all/route.ts deleted file mode 100644 index a9aaf64..0000000 --- a/ui/app/api/session/delete-all/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/delete-all`; - - const { uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/delete/route.ts b/ui/app/api/session/delete/route.ts deleted file mode 100644 index 4719363..0000000 --- a/ui/app/api/session/delete/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/delete`; - - const { session_id, uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - session_id, - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/get-all-from-uid/route.ts b/ui/app/api/session/get-all-from-uid/route.ts deleted file mode 100644 index 14ab980..0000000 --- a/ui/app/api/session/get-all-from-uid/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/get-all-from-uid`; - - const { uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/get-all/route.ts b/ui/app/api/session/get-all/route.ts deleted file mode 100644 index 0ab2143..0000000 --- a/ui/app/api/session/get-all/route.ts +++ /dev/null @@ -1,20 +0,0 @@ -export async function GET(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/get-all`; - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/revoke-all/route.ts b/ui/app/api/session/revoke-all/route.ts deleted file mode 100644 index abcf0a3..0000000 --- a/ui/app/api/session/revoke-all/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/revoke-all`; - - const { uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/session/revoke/route.ts b/ui/app/api/session/revoke/route.ts deleted file mode 100644 index ef7d565..0000000 --- a/ui/app/api/session/revoke/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/session/revoke`; - - const { session_id, uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - session_id, - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/delete/route.ts b/ui/app/api/user/delete/route.ts deleted file mode 100644 index 7e6a948..0000000 --- a/ui/app/api/user/delete/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/delete`; - - const { email } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - cache: 'no-cache', - body: JSON.stringify({ - email - }), - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/get-all/route.ts b/ui/app/api/user/get-all/route.ts deleted file mode 100644 index f4015f1..0000000 --- a/ui/app/api/user/get-all/route.ts +++ /dev/null @@ -1,19 +0,0 @@ -export async function GET(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/get-all` - - if (endPoint) { - try { - const res = await fetch(endPoint, { - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/get-from-uid/route.ts b/ui/app/api/user/get-from-uid/route.ts deleted file mode 100644 index aa89af8..0000000 --- a/ui/app/api/user/get-from-uid/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/get-from-id`; - - const { uid } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - uid - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/get-recent/route.ts b/ui/app/api/user/get-recent/route.ts deleted file mode 100644 index 18b0387..0000000 --- a/ui/app/api/user/get-recent/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/get-recent`; - - const { limit } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - cache: 'no-cache', - body: JSON.stringify({ - limit - }), - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/toggle-active-status/route.ts b/ui/app/api/user/toggle-active-status/route.ts deleted file mode 100644 index b74f9f1..0000000 --- a/ui/app/api/user/toggle-active-status/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/toggle-account-active-status`; - - const { email, is_active } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - email, - is_active - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/update-role/route.ts b/ui/app/api/user/update-role/route.ts deleted file mode 100644 index 34376e7..0000000 --- a/ui/app/api/user/update-role/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/update-role`; - - const { email, role } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - email, - role - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/api/user/update/route.ts b/ui/app/api/user/update/route.ts deleted file mode 100644 index bab208a..0000000 --- a/ui/app/api/user/update/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -export async function POST(req: Request) { - const endPoint: (string | undefined) = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/user/update`; - - const { name, email } = await req.json(); - - if (endPoint) { - try { - const res = await fetch(endPoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', // Set the appropriate content type for your request - 'x-api-key': process.env.X_API_KEY!, - }, - body: JSON.stringify({ - name, - email - }), - cache: 'no-cache', - }); - const data = await res.json(); - return Response.json({ data }) - } catch (error) { - console.error('Error during request:', error); - } - } -} \ No newline at end of file diff --git a/ui/app/favicon.ico b/ui/app/favicon.ico deleted file mode 100644 index 1e4d4cc..0000000 Binary files a/ui/app/favicon.ico and /dev/null differ diff --git a/ui/app/globals.css b/ui/app/globals.css deleted file mode 100644 index 523b3dd..0000000 --- a/ui/app/globals.css +++ /dev/null @@ -1,57 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - :root { - --background: 222.2 50% 4.9%; - --foreground: 210 40% 98%; - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - --primary: 217.2 91.2% 59.8%; - --primary-foreground: 222.2 47.4% 11.2%; - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - --accent: 217.2 32.6% 17.5%; - --accent-foreground: 210 40% 98%; - --destructive: 0 94% 30.6%; - --destructive-foreground: 210 40% 98%; - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 224.3 76.3% 48%; - --radius: 0.5rem; - - --chart-1-1: 221.2 83.2% 53.3%; - --chart-2-1: 212 95% 68%; - --chart-3-1: 216 92% 60%; - --chart-4-1: 210 98% 78%; - --chart-5-1: 212 97% 87%; - - --chart-1-2: 359 2% 90%; - --chart-2-2: 240 1% 74%; - --chart-3-2: 240 1% 58%; - --chart-4-2: 240 1% 42%; - --chart-5-2: 240 2% 26%; - - --chart-1-3: 139 65% 20%; - --chart-2-3: 140 74% 44%; - --chart-3-3: 142 88% 28%; - --chart-4-3: 137 55% 15%; - --chart-5-3: 141 40% 9%; - } -} - - -@layer base { - * { - @apply border-border overflow-x-clip; - } - - body { - @apply bg-background text-foreground; - } -} \ No newline at end of file diff --git a/ui/app/layout.tsx b/ui/app/layout.tsx deleted file mode 100644 index 96536cb..0000000 --- a/ui/app/layout.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import type { Metadata } from "next"; -import { Poppins } from "next/font/google"; -import "./globals.css"; -import { TooltipProvider } from "@/components/ui/tooltip"; -import Navbar from "@/components/shared/Navbar"; -import { Toaster } from "@/components/ui/toaster"; -import Sidebar from "@/components/shared/Sidebar/Sidebar"; -import { AppPages } from "@/constants/appconstants"; - -const poppins = Poppins({ - weight: '400', - subsets: ['latin'], - display: 'swap', -}) - -export const metadata: Metadata = { - title: "FlexAuth Dashboard", - description: "Your own flexible, blazingly fast 🦀, and secure in-house authentication system.", -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - -
- -
- -
- -
- {children} -
-
-
- - -
- - - ); -} diff --git a/ui/app/page.tsx b/ui/app/page.tsx deleted file mode 100644 index fc8ddaa..0000000 --- a/ui/app/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -"use client"; -import React from 'react' -import Overview from '@/components/Overview/Overview'; - -const OverviewPage = () => { - return ( -
- -
- ) -} - -export default OverviewPage \ No newline at end of file diff --git a/ui/app/sessions/page.tsx b/ui/app/sessions/page.tsx deleted file mode 100644 index c59020e..0000000 --- a/ui/app/sessions/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -"use client" - -import SessionTableAll from '@/components/session/SessionTableAll' -import React from 'react' - -const Sessions = () => { - return ( -
- -
- ) -} - -export default Sessions \ No newline at end of file diff --git a/ui/app/users/[userID]/page.tsx b/ui/app/users/[userID]/page.tsx deleted file mode 100644 index a24c4a2..0000000 --- a/ui/app/users/[userID]/page.tsx +++ /dev/null @@ -1,540 +0,0 @@ -"use client"; -import React, { useCallback, useEffect } from "react"; -import { Loader } from "@/components/custom/Loader"; -import { Button } from "@/components/ui/button"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { IUser } from "@/interfaces/IUser"; -import { - AlertDialog, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, -} from "@/components/ui/alert-dialog"; -import { Input } from "@/components/ui/input"; -import { useRouter } from "next/navigation"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { IoMdMore } from "react-icons/io"; -import { toast } from "@/components/ui/use-toast"; -import { Badge } from "@/components/ui/badge"; -import { GoClockFill } from "react-icons/go"; -import { TiTick } from "react-icons/ti"; -import { IoIosWarning } from "react-icons/io"; -import { format } from "date-fns"; -import SessionTableUser from "@/components/session/SessionTableUser"; -import PasswordInput from "@/components/ui/passwordInput"; -import { FaRegCopy } from "react-icons/fa"; -import useCopy from "@/hooks/useCopy"; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; - -const UserDetails = ({ params }: any) => { - const { userID } = params; - const [loading, setLoading] = React.useState(true); - const [user, setUser] = React.useState(null); - const [role, setRole] = React.useState(""); - const [name, setName] = React.useState(""); - const [oldPassword, setOldPassword] = React.useState(""); - const [newPassword, setNewPassword] = React.useState(""); - const [confirmNewPassword, setConfirmNewPassword] = React.useState(""); - const router = useRouter(); - const { copyHandler } = useCopy(); - - // function to update is_active - const updateUserActive = async (is_active: boolean) => { - try { - setLoading(true); - await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/toggle-active-status`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: user?.email, - is_active: is_active, - }), - } - ); - await getUser(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - const getUser = useCallback(async () => { - try { - setLoading(true); - const res = await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/get-from-uid`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - uid: userID, - }), - } - ); - const { data } = await res.json(); - setUser(data); - setRole(data?.role || ""); - setName(data?.name || ""); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }, [userID]); - - // delete user function - const deleteUser = async (email: string) => { - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/delete`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - }), - }); - router.push("/"); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // reset password function - const resetPassword = async ( - email: string, - old_password: string, - new_password: string - ) => { - if ( - old_password === "" || - new_password === "" || - confirmNewPassword === "" - ) { - toast({ - title: "Error", - description: "Fill all the fields correctly.", - variant: "destructive", - }); - return; - } else { - if (new_password !== confirmNewPassword) { - toast({ - title: "Error", - description: "New and Confirm New Passwords do not match.", - variant: "destructive", - }); - return; - } - } - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/password/reset`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - old_password, - new_password, - }), - }); - } catch (error) { - console.error("Error during POST request:", error); - } finally { - setOldPassword(""); - setNewPassword(""); - setConfirmNewPassword(""); - } - setLoading(false); - }; - - // forget password request function - const forgetPassword = async (email: string) => { - try { - setLoading(true); - await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/password/forget-request`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - }), - } - ); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // edit user function - const editUser = async (email: string, name: string, role: string) => { - if (name === "" || role === "") { - toast({ - title: "Error", - description: "Fill all the fields correctly.", - variant: "destructive", - }); - return; - } - try { - setLoading(true); - if (role !== user?.role) { - await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update-role`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: user?.email, - role, - }), - } - ); - } - if (name !== user?.name) { - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email, - name, - }), - }); - } - await getUser(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - useEffect(() => { - getUser(); - }, [getUser]); - - return ( -
-
- {loading ? ( -
- -
- ) : ( -
- - - -
-

{user?.name}

-
-

- {user?.uid} -

- - - - - - -

Copy UID

-
-
-
-
-
- -
-
- - - - - - - - Update User Name - - -

Name

- setName(e.target.value)} - /> -

Role

- setRole(e.target.value)} - /> -
-
- - Cancel - - -
-
- - - - - - - - Want to delete this User? - - - This action cannot be undone. - - - - Cancel - - - - - - - - - - - - - Reset Password - - - - - Reset Password - - -
-

Old Password

- - setOldPassword(e.target.value) - } - /> -
- - -
-
- - { - setOldPassword(""); - setNewPassword(""); - setConfirmNewPassword(""); - }}>Cancel - - -
-
-
- - - - Forget Password - - - - - Forget Password - - - This action cannot be undone. - - - - Cancel - - - - - - - - - {user?.is_active ? "Suspend Account" : "Activate Account"} - - - - - {user?.is_active ? "Suspend Account" : "Activate Account"} {"for " + user?.email} - - - are you sure you want to do this? - - - - Cancel - - - - - -
-
-
-
-
-
- -
-
-

Email

-

{user?.email}

-
-
-

Role

-

{user?.role}

-
-
-

- Email Verification -

- - {user?.email_verified ? : } - - {user?.email_verified ? "Verified" : "Pending"} - -
-
-

Account Status

- - {user?.is_active ? : } - - {user?.is_active ? "Active" : "Suspended"} - -
-
-

Created At

-

- {format( - new Date(parseInt(user?.created_at.$date.$numberLong!)), - "PP - p" - )} -

-
-
-

Updated At

-

- {format( - new Date(parseInt(user?.updated_at.$date.$numberLong!)), - "PP - p" - )} -

-
-
-
-
- -
- )} -
-
- ); -}; - -export default UserDetails; diff --git a/ui/app/users/page.tsx b/ui/app/users/page.tsx deleted file mode 100644 index 9de8c91..0000000 --- a/ui/app/users/page.tsx +++ /dev/null @@ -1,11 +0,0 @@ -"use client" -import React from 'react' -import Users from '@/components/Users/Users' - -const UsersPage = () => { - return ( - - ) -} - -export default UsersPage \ No newline at end of file diff --git a/ui/components.json b/ui/components.json deleted file mode 100644 index 15f2b02..0000000 --- a/ui/components.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": true, - "tsx": true, - "tailwind": { - "config": "tailwind.config.ts", - "css": "app/globals.css", - "baseColor": "slate", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils" - } -} \ No newline at end of file diff --git a/ui/components/Overview/Overview.tsx b/ui/components/Overview/Overview.tsx deleted file mode 100644 index ce83078..0000000 --- a/ui/components/Overview/Overview.tsx +++ /dev/null @@ -1,469 +0,0 @@ -/* eslint-disable react-hooks/rules-of-hooks */ -"use client"; -import React, { useEffect, useState } from 'react' -import { Loader } from '../custom/Loader'; -import { IOverview } from '@/interfaces/IOverview'; -import { DonutChartStats } from '../custom/DonutChartForStats'; -import { ChartConfig } from '../ui/chart'; -import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; -import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; -import { FaUsersSlash } from 'react-icons/fa'; -import { ChartPie } from '../custom/PieChart'; -import { IUser } from '@/interfaces/IUser'; -import { ColumnDef } from '@tanstack/react-table'; -import { LuArrowUpRight } from 'react-icons/lu'; -import { useRouter } from 'next/navigation'; -import { Badge } from '../ui/badge'; -import { TiTick } from 'react-icons/ti'; -import { GoClockFill } from 'react-icons/go'; -import { IoIosWarning, IoMdMore } from 'react-icons/io'; -import { format } from 'date-fns'; -import { toast } from '../ui/use-toast'; -import { Input } from '../ui/input'; -import { Button } from '../ui/button'; -import { DataTable } from '../ui/data-table'; - -const Overview = () => { - const [overview, setOverview] = useState(null) - const [recentUsers, setRecentUsers] = useState([]) - const [loading, setLoading] = useState(true) - - const userChartData = [ - { name: "active", count: overview?.active_user_count, fill: "var(--color-active)" }, - { name: "inactive", count: overview?.inactive_user_count, fill: "var(--color-inactive)" }, - ] - - const userChartConfig = { - user: { - label: "Users", - }, - active: { - label: "Active", - color: "hsl(var(--chart-1-1))", - }, - inactive: { - label: "Inactive", - color: "hsl(var(--chart-2-1))", - }, - } satisfies ChartConfig - - const sessionChartData = [ - { name: "active", count: overview?.active_session_count, fill: "var(--color-active)" }, - { name: "revoked", count: overview?.revoked_session_count, fill: "var(--color-revoked)" }, - ] - - const sessionChartConfig = { - session: { - label: "Sessions", - }, - active: { - label: "Active", - color: "hsl(var(--chart-1-1))", - }, - revoked: { - label: "Revoked", - color: "hsl(var(--chart-2-2))", - }, - } satisfies ChartConfig - - - // Define an interface for the device counts - interface CountObject { - [key: string]: number; - } - - // Initialize the device counts object with the correct type - const deviceCounts: CountObject = (overview ?? { - device_types: [], - }).device_types.reduce((acc, device) => { - const sanitizedKey = device.replace(/\s+/g, ''); // Remove whitespace from the key - acc[sanitizedKey] = (acc[sanitizedKey] || 0) + 1; - return acc; - }, {} as CountObject); - - // Count occurrences in the browsers array - const browserCounts: CountObject = (overview ?? { - browser_types: [], - }).browser_types.reduce((acc, browser) => { - const sanitizedKey = browser.replace(/\s+/g, ''); // Remove whitespace from the key - acc[sanitizedKey] = (acc[sanitizedKey] || 0) + 1; - return acc; - }, {} as CountObject); - - // Count occurrences in the OS types array - const osTypeCounts: CountObject = (overview ?? { - os_types: [], - }).os_types.reduce((acc, os) => { - const sanitizedKey = os.replace(/\s+/g, ''); // Remove whitespace from the key - acc[sanitizedKey] = (acc[sanitizedKey] || 0) + 1; - return acc; - }, {} as CountObject); - - - // Define a function to generate colors dynamically - const generateColor = (index: number, themeNo: number) => { - return `hsl(var(--chart-${index + 1}-${themeNo}))`; - }; - - // Generic function to generate chart configuration - const generateChartConfig = (counts: CountObject, themeNo: number) => { - const config: { [key: string]: { label: string; color: string } } = {}; - const types = Object.keys(counts); - - - types.forEach((type, index) => { - config[type] = { - label: type, - color: generateColor(index, themeNo), - }; - }); - - return config; - }; - - const sessionDeviceChartData = Object.keys(deviceCounts).map(device => ({ - name: device, - count: deviceCounts[device] || 0, - fill: `var(--color-${device})` - })); - - const sessionBrowserChartData = Object.keys(browserCounts).map(browser => ({ - name: browser, - count: browserCounts[browser] || 0, - fill: `var(--color-${browser})` - })); - - const sessionOsTypeChartData = Object.keys(osTypeCounts).map(os => ({ - name: os, - count: osTypeCounts[os] || 0, - fill: `var(--color-${os})` - })); - - const sessionDeviceChartConfig = generateChartConfig(deviceCounts, 2); - - const sessionBrowserChartConfig = generateChartConfig(browserCounts, 1); - - const sessionOSChartConfig = generateChartConfig(osTypeCounts, 2); - - // delete user function - const deleteUser = async (email: string) => { - try { - setLoading(true) - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/delete`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email - }), - }); - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - const router = useRouter(); - - const columns: ColumnDef[] = [ - { - accessorKey: "name", - header: "Name", - cell: ({ row }) => { - const user = row.original; - return ( -
router.push(`/users/${user.uid}`)}> -
{user.name}
-
- -
-
- ); - } - }, - { - accessorKey: "email", - header: "Email", - }, - { - accessorKey: "role", - header: "Role", - }, - { - accessorKey: "email_verified", - header: "Email Verification", - cell: ({ row }) => { - return ( - - {row.original?.email_verified ? : } - - {row.original?.email_verified ? "Verified" : "Pending"} - - ) - }, - }, - { - accessorKey: "is_active", - header: "Account Status", - cell: ({ row }) => { - return ( - - {row.original?.is_active ? : } - - {row.original?.is_active ? "Active" : "Suspended"} - - ) - }, - }, - { - accessorKey: "created_at", - header: "Created At", - cell: ({ row }) => { - return ( -
- {format( - new Date(parseInt(row.original?.created_at.$date.$numberLong!)), - "PP - p" - )} -
- ) - }, - }, - { - accessorKey: "updated_at", - header: "Action", - cell: ({ row }) => { - const user = row.original; - const [name, setName] = useState(user.name); - const [role, setRole] = useState(user.role) - // edit user function - const editUser = async (email: string, name: string, role: string) => { - if (name === "" || role === "") { - toast({ - title: "Error", - description: "Fill all the fields correctly.", - variant: "destructive" - }); - return; - }; - try { - setLoading(true) - if (role !== user?.role) { - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update-role`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email: user?.email, - role - }), - }); - } - if (name !== user?.name) { - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email, - name - }), - }); - } - await getRecentUsers() - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - return ( -
- - - - - - - - - Update - - - - Update User Name - -

Name

- setName(e.target.value)} /> -

Role

- setRole(e.target.value)} /> -
-
- - Cancel - - -
-
-
- - - - Delete - - - - Are you absolutely sure? - - This action cannot be undone. - - - - Cancel - - - - - -
-
-
- ) - }, - }, - ]; - - - const getOverview = async () => { - try { - setLoading(true) - const res = await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/overview/get-all`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - cache: 'no-cache', - }); - const { data } = await res.json(); - setOverview(data); - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - const getRecentUsers = async () => { - try { - setLoading(true) - const res = await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/get-recent`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ limit: 5 }), - cache: 'no-cache', - }); - const { data } = await res.json(); - setRecentUsers(data); - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - const fetchAllData = async () => { - await Promise.all([getOverview(), getRecentUsers()]) - } - - useEffect(() => { - fetchAllData() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) - - return ( -
- { - loading ? -
- -
- : -
-
- - - - Blocked Users - - - -

- {overview?.blocked_user_count} -

-
-
- - - - -
-
-

Recent Users

- -
-
- } -
- ) -} - -export default Overview \ No newline at end of file diff --git a/ui/components/Users/Users.tsx b/ui/components/Users/Users.tsx deleted file mode 100644 index f128549..0000000 --- a/ui/components/Users/Users.tsx +++ /dev/null @@ -1,274 +0,0 @@ -/* eslint-disable react-hooks/rules-of-hooks */ -"use client"; - -import { IUser } from '@/interfaces/IUser'; -import { ColumnDef } from '@tanstack/react-table'; -import { useRouter } from 'next/navigation'; -import React, { useEffect, useState } from 'react' -import { LuArrowUpRight } from 'react-icons/lu'; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; -import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; -import { Button } from '@/components/ui/button'; -import { IoIosWarning, IoMdMore } from 'react-icons/io'; -import { Input } from '@/components/ui/input'; -import { Loader } from '@/components/custom/Loader'; -import { DataTable } from '@/components/ui/data-table'; -import { toast } from '@/components/ui/use-toast'; -import { Badge } from '../ui/badge'; -import { TiTick } from 'react-icons/ti'; -import { GoClockFill } from 'react-icons/go'; -import { format } from 'date-fns'; - - -const Users = () => { - const [users, setUsers] = useState([] as IUser[]) - const [loading, setLoading] = useState(true) - const router = useRouter(); - - const getAllUsers = async () => { - try { - setLoading(true) - const res = await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/get-all`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - cache: 'no-cache', - }); - const { data } = await res.json(); - setUsers(data); - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - // delete user function - const deleteUser = async (email: string) => { - try { - setLoading(true) - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/delete`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email - }), - }); - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - - const columns: ColumnDef[] = [ - { - accessorKey: "name", - header: "Name", - cell: ({ row }) => { - const user = row.original; - return ( -
router.push(`/users/${user.uid}`)}> -
{user.name}
-
- -
-
- ); - } - }, - { - accessorKey: "email", - header: "Email", - }, - { - accessorKey: "role", - header: "Role", - }, - { - accessorKey: "email_verified", - header: "Email Verification", - cell: ({ row }) => { - return ( - - {row.original?.email_verified ? : } - - {row.original?.email_verified ? "Verified" : "Pending"} - - ) - }, - }, - { - accessorKey: "is_active", - header: "Account Status", - cell: ({ row }) => { - return ( - - {row.original?.is_active ? : } - - {row.original?.is_active ? "Active" : "Suspended"} - - ) - }, - }, - { - accessorKey: "created_at", - header: "Created At", - cell: ({ row }) => { - return ( -
- {format( - new Date(parseInt(row.original?.created_at.$date.$numberLong!)), - "PP - p" - )} -
- ) - }, - }, - { - accessorKey: "updated_at", - header: "Action", - cell: ({ row }) => { - const user = row.original; - const [name, setName] = useState(user.name); - const [role, setRole] = useState(user.role) - // edit user function - const editUser = async (email: string, name: string, role: string) => { - if (name === "" || role === "") { - toast({ - title: "Error", - description: "Fill all the fields correctly.", - variant: "destructive" - }); - return; - }; - try { - setLoading(true) - if (role !== user?.role) { - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update-role`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email: user?.email, - role - }), - }); - } - if (name !== user?.name) { - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/user/update`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email, - name - }), - }); - } - await getAllUsers() - } catch (error) { - console.error('Error during POST request:', error); - } - setLoading(false) - } - - return ( -
- - - - - - - - - Update - - - - Update User Name - -

Name

- setName(e.target.value)} /> -

Role

- setRole(e.target.value)} /> -
-
- - Cancel - - -
-
-
- - - - Delete - - - - Are you absolutely sure? - - This action cannot be undone. - - - - Cancel - - - - - -
-
-
- ) - }, - }, - ]; - - useEffect(() => { - getAllUsers() - }, []) - return ( -
- { - loading ? -
- -
- :
- -
- } -
- ) -} - -export default Users \ No newline at end of file diff --git a/ui/components/custom/BarChart.tsx b/ui/components/custom/BarChart.tsx deleted file mode 100644 index 0183e02..0000000 --- a/ui/components/custom/BarChart.tsx +++ /dev/null @@ -1,70 +0,0 @@ -"use client" - -import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from "recharts" - -import { - Card, - CardContent, - CardHeader, - CardTitle, -} from "@/components/ui/card" -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from "@/components/ui/chart" - -interface ChartPieProps { - title: string; - chartData: any; - key: string; - chartConfig: ChartConfig; -} - -export function ChartBar({ title, chartData, key, chartConfig }: ChartPieProps) { - return ( - - - {title} - - - - - - - String(chartData[value]?.name) - } - /> - } - /> - { - return ( - - ) - }} - /> - - - - - ) -} diff --git a/ui/components/custom/DonutChartForStats.tsx b/ui/components/custom/DonutChartForStats.tsx deleted file mode 100644 index 176598b..0000000 --- a/ui/components/custom/DonutChartForStats.tsx +++ /dev/null @@ -1,96 +0,0 @@ -"use client" - -import * as React from "react" -import { Label, Pie, PieChart } from "recharts" - -import { - Card, - CardContent, - CardHeader, - CardTitle, -} from "@/components/ui/card" -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from "@/components/ui/chart" -import { FaClock, FaUsersSlash } from "react-icons/fa" - -interface DonutChartProps { - title: string; - chartData: any; - key: string; - chartConfig: ChartConfig; -} - -export function DonutChartStats({ title, chartData, chartConfig, key }: DonutChartProps) { - const totalCount = React.useMemo(() => { - return chartData.reduce((acc: any, curr: { count: any }) => acc + curr.count, 0) - }, [chartData]) - - return ( - - - {title} - - - - {totalCount === 0 ? - - -

- {totalCount} -

-
- : - } - /> - - - } -
-
-
- ) -} diff --git a/ui/components/custom/Loader.tsx b/ui/components/custom/Loader.tsx deleted file mode 100644 index a1d0dcf..0000000 --- a/ui/components/custom/Loader.tsx +++ /dev/null @@ -1,15 +0,0 @@ -export const Loader = ({ size = '1.25em' }) => { - return ( -
- - Loading... - -
- ); -}; diff --git a/ui/components/custom/PieChart.tsx b/ui/components/custom/PieChart.tsx deleted file mode 100644 index 3dd4b9f..0000000 --- a/ui/components/custom/PieChart.tsx +++ /dev/null @@ -1,153 +0,0 @@ -"use client" - -import { Label, Pie, PieChart, Sector } from "recharts" -import { - Card, - CardContent, - CardHeader, - CardTitle, -} from "../ui/card" -import { - ChartConfig, - ChartContainer, - ChartStyle, - ChartTooltip, - ChartTooltipContent, -} from "../ui/chart" -import React from "react"; -import { PieSectorDataItem } from "recharts/types/polar/Pie"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"; - - -interface ChartPieProps { - title: string; - chartData: any; - key: string; - chartConfig: ChartConfig; -} - -export function ChartPie({ title, chartData, chartConfig, key }: ChartPieProps) { - const id = "pie-interactive" - const [active, setActive] = React.useState(chartData[0]?.name) - const activeIndex = React.useMemo(() => { - const index = (chartData as []).findIndex((item: any) => item.name === active); - return index === -1 ? 0 : index; - }, [active, chartData]); - - const options = React.useMemo(() => chartData.map((item: any) => item.name), [chartData]) - - return ( - - - -
- {title} -
- {(chartData as []).length > 0 && } -
- - - {(chartData as []).length > 0 ? - } - /> - ( - - - - - )} - > - - : - -

- No Data to show -

-
- } -
-
-
- ) -} \ No newline at end of file diff --git a/ui/components/session/SessionTableAll.tsx b/ui/components/session/SessionTableAll.tsx deleted file mode 100644 index 8ea5132..0000000 --- a/ui/components/session/SessionTableAll.tsx +++ /dev/null @@ -1,293 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -import { ISession } from "@/interfaces/ISession"; -import { - AlertDialog, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogCancel, -} from "@/components/ui/alert-dialog"; -import { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, -} from "@/components/ui/dropdown-menu"; -import { ColumnDef } from "@tanstack/react-table"; -import { Loader } from "lucide-react"; -import React, { useCallback, useEffect } from "react"; -import { IoMdMore } from "react-icons/io"; -import { AlertDialogHeader, AlertDialogFooter } from "../ui/alert-dialog"; -import { Button } from "../ui/button"; -import { DataTable } from "../ui/data-table"; -import { addDays, format } from "date-fns"; - -const SessionTableAll: React.FC = () => { - const [loading, setLoading] = React.useState(false); - const [sessions, setSessions] = React.useState([]); - - // fetch all sessions - const fetchAllSessions = useCallback(async () => { - try { - setLoading(true); - const res = await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/get-all`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - cache: "no-cache", - } - ); - const { data } = await res.json(); - setSessions(data); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }, []); - - // revoke session function - const revokeSession = async (session_id: string, uid: string) => { - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/revoke`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - session_id, - uid, - }), - }); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // delete session function - const deleteSession = async (session_id: string, uid: string) => { - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/delete`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - session_id, - uid, - }), - }); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - useEffect(() => { - fetchAllSessions(); - }, [fetchAllSessions]); - - const sessionColumns: ColumnDef[] = [ - { - accessorKey: "user_agent", - header: "User Agent", - cell: ({ row }) => { - const session = row.original; - return ( - // render device type and browser name with logo -
-
-
- {session.device === "smartphone" && - ( - device-logo - )} - {session.device === "pc" && - ( - device-logo - )} -
-
-

{session?.device === "smartphone" ? "Smartphone" : session?.device === "pc" ? "Desktop" : ""} ({session.vendor})

-

{session?.os} - Version {session.os_version}

-
- {session?.browser.includes("Chrome") && ( - browser-logo - )} - {session?.browser.includes("Mozilla") && ( - browser-logo - )} - {session?.browser.includes("Safari") && ( - browser-logo - )} -

{session?.browser} - Version: {session?.browser_version}

-
-
-
- -
- ); - }, - }, - { - accessorKey: "updated_at", - header: "Updated At", - cell: ({ row }) => { - return ( -
- { - format( - parseInt(row.original.updated_at.$date.$numberLong) - , "PP - p" - ) - } -
- ); - }, - }, - { - accessorKey: "created_at", - header: "Expires At", - cell: ({ row }) => { - return ( -
- { - format(addDays( - parseInt(row.original.created_at.$date.$numberLong) - , 45), "PP - p") - } -
- ); - }, - }, - { - accessorKey: "is_revoked", - header: "Revoked", - cell: ({ row }) => { - return ( -
- {row.original.is_revoked ? "Yes" : "No"} -
- ); - }, - }, - { - accessorKey: "action", - header: "Action", - cell: ({ row }) => { - const session = row.original; - return ( -
- - - - - - {!row.original.is_revoked && ( - - - - Revoke - - - - - Are you absolutely sure? - - - This action cannot be undone. - - - - Cancel - - - - - - )} - - - - Delete - - - - - Are you absolutely sure? - - - This action cannot be undone. - - - - Cancel - - - - - - - -
- ); - }, - }, - ]; - - return ( - - ); -}; - -export default SessionTableAll; diff --git a/ui/components/session/SessionTableUser.tsx b/ui/components/session/SessionTableUser.tsx deleted file mode 100644 index b0a0f28..0000000 --- a/ui/components/session/SessionTableUser.tsx +++ /dev/null @@ -1,431 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -import { ISession } from "@/interfaces/ISession"; -import { - AlertDialog, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogCancel, -} from "@/components/ui/alert-dialog"; -import { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, -} from "@/components/ui/dropdown-menu"; -import { ColumnDef } from "@tanstack/react-table"; -import { Loader } from "lucide-react"; -import React, { useCallback, useEffect } from "react"; -import { IoMdMore } from "react-icons/io"; -import { AlertDialogHeader, AlertDialogFooter } from "../ui/alert-dialog"; -import { Button } from "../ui/button"; -import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; -import { DataTable } from "../ui/data-table"; -import UAParser from "ua-parser-js"; -import { addDays, format } from "date-fns"; - -interface SessionTableProps { - userID: string; -} - -const SessionTable: React.FC = ({ userID }) => { - const [loading, setLoading] = React.useState(false); - const [sessions, setSessions] = React.useState([]); - - // fetch all sessions - const fetchAllSessions = useCallback(async () => { - try { - setLoading(true); - const res = await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/get-all-from-uid`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - uid: userID, - }), - cache: "no-cache", - } - ); - const { data } = await res.json(); - setSessions(data); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }, [userID]); - - // revoke session function - const revokeSession = async (session_id: string) => { - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/revoke`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - session_id, - uid: userID, - }), - }); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // delete session function - const deleteSession = async (session_id: string) => { - try { - setLoading(true); - await fetch(`${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/delete`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - session_id, - uid: userID, - }), - }); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // delete all sessions function - const deleteAllSessions = async () => { - try { - setLoading(true); - await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/delete-all`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - uid: userID, - }), - } - ); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - // revoke all sessions function - const revokeAllSessions = async () => { - try { - setLoading(true); - await fetch( - `${process.env.NEXT_PUBLIC_ENDPOINT}/api/session/revoke-all`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - uid: userID, - }), - } - ); - await fetchAllSessions(); - } catch (error) { - console.error("Error during POST request:", error); - } - setLoading(false); - }; - - useEffect(() => { - fetchAllSessions(); - }, [fetchAllSessions]); - - const parser = new UAParser("user-agent"); - - const sessionColumns: ColumnDef[] = [ - { - accessorKey: "user_agent", - header: "User Agent", - cell: ({ row }) => { - const session = row.original; - - return ( - // render device type and browser name with logo -
-
-
- {session.device === "smartphone" && - ( - device-logo - )} - {session.device === "pc" && - ( - device-logo - )} -
-
-

{session?.device === "smartphone" ? "Smartphone" : session?.device === "pc" ? "Desktop" : ""} ({session.vendor})

-

{session?.os} - Version {session.os_version}

-
- {session?.browser.includes("Chrome") && ( - browser-logo - )} - {session?.browser.includes("Mozilla") && ( - browser-logo - )} - {session?.browser.includes("Safari") && ( - browser-logo - )} -

{session?.browser} - Version: {session?.browser_version}

-
-
-
- -
- ); - }, - }, - { - accessorKey: "updated_at", - header: "Updated At", - cell: ({ row }) => { - return ( -
- { - format( - parseInt(row.original.updated_at.$date.$numberLong) - , "PP - p" - ) - } -
- ); - }, - }, - { - accessorKey: "created_at", - header: "Expires At", - cell: ({ row }) => { - return ( -
- { - format(addDays( - parseInt(row.original.created_at.$date.$numberLong) - , 45), "PP - p") - } -
- ); - }, - }, - { - accessorKey: "is_revoked", - header: "Revoked", - cell: ({ row }) => { - return ( -
- {row.original.is_revoked ? "Yes" : "No"} -
- ); - }, - }, - { - accessorKey: "action", - header: "Action", - cell: ({ row }) => { - const session = row.original; - return ( -
- - - - - - {!row.original.is_revoked && ( - - - - Revoke - - - - - Are you absolutely sure? - - - This action cannot be undone. - - - - Cancel - - - - - - )} - - - - Delete - - - - - Are you absolutely sure? - - - This action cannot be undone. - - - - Cancel - - - - - - - -
- ); - }, - }, - ]; - - return ( - - - -

Sessions

- - - - - - - - - Revoke All - - - - - Want to revoke all the sessions? - - - This action cannot be undone. - - - - Cancel - - - - - - - - - Delete All - - - - - Want to delete all the sessions? - - - This action cannot be undone. - - - - Cancel - - - - - - - -
-
- - - -
- ); -}; - -export default SessionTable; diff --git a/ui/components/shared/Navbar.tsx b/ui/components/shared/Navbar.tsx deleted file mode 100644 index d3ebdf8..0000000 --- a/ui/components/shared/Navbar.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -"use client"; - -import React from "react"; -import { usePathname, useRouter } from "next/navigation"; -import { AiOutlineArrowLeft } from "react-icons/ai"; -import { Button } from "../ui/button"; - -const Navbar = () => { - const path = usePathname(); - const router = useRouter(); - - const returnPageName = () => { - if (path.includes("/") && (!path.includes("/user/") && !path.includes("/user"))) { - return ( -
- Overview -
- ) - } - if (path.includes("/user") && (!path.includes("/user/"))) { - return ( -
- Users -
- ) - } - if (path.includes("/user/")) { - return ( -
- - User Details -
- ) - } - } - - return ( -
-
-
- flexauth-logo router.push("/")} - /> -

FlexAuth

-
-

- {returnPageName()} -

-
-
- ); -}; - -export default Navbar; diff --git a/ui/components/shared/Sidebar/Sidebar.tsx b/ui/components/shared/Sidebar/Sidebar.tsx deleted file mode 100644 index 3313774..0000000 --- a/ui/components/shared/Sidebar/Sidebar.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client"; - -import React from 'react' -import { usePathname, useRouter } from 'next/navigation'; -import SidebarItem from './SidebarItem'; - -export interface IPages { - name: string; - icon?: any; - link: string; - showOnSidebar?: boolean; -} - -interface Props { - items: IPages[] -} - -const Sidebar: React.FC = ({ items }) => { - const path = usePathname(); - const router = useRouter(); - - return ( -
-
- {items.map((item) => ( - - ))} -
- -
-

© 2024 FlexAuth • All rights reserved

-
-
- ) -} - -export default Sidebar \ No newline at end of file diff --git a/ui/components/shared/Sidebar/SidebarItem.tsx b/ui/components/shared/Sidebar/SidebarItem.tsx deleted file mode 100644 index 7b03fa0..0000000 --- a/ui/components/shared/Sidebar/SidebarItem.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react' -import { IPages } from './Sidebar' -import Image from 'next/image' - -interface Props { - item: IPages - path: string - router: any -} - -const SidebarItem: React.FC = ({ item, path, router }) => { - const handleClickSidebarItems = (item: IPages) => { - router.push(item.link) - } - - const handleHighlight = (item: IPages) => { - if (path.includes("/user/")) { - return (item.link === "/user") - } - if (path.includes("/users/")) { - return (item.link === "/users") - } - return (path === item.link); - } - - return ( - <> - {item.showOnSidebar && ( -
-
{ handleClickSidebarItems(item) }}> -
- {typeof item.icon === "string" ? sidebar-icons : item.icon} -
-

{item.name}

-
-
-
-
- )} - - ) -} - -export default SidebarItem \ No newline at end of file diff --git a/ui/components/ui/alert-dialog.tsx b/ui/components/ui/alert-dialog.tsx deleted file mode 100644 index 25e7b47..0000000 --- a/ui/components/ui/alert-dialog.tsx +++ /dev/null @@ -1,141 +0,0 @@ -"use client" - -import * as React from "react" -import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" - -import { cn } from "@/lib/utils" -import { buttonVariants } from "@/components/ui/button" - -const AlertDialog = AlertDialogPrimitive.Root - -const AlertDialogTrigger = AlertDialogPrimitive.Trigger - -const AlertDialogPortal = AlertDialogPrimitive.Portal - -const AlertDialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName - -const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - -)) -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName - -const AlertDialogHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogHeader.displayName = "AlertDialogHeader" - -const AlertDialogFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogFooter.displayName = "AlertDialogFooter" - -const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName - -const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogDescription.displayName = - AlertDialogPrimitive.Description.displayName - -const AlertDialogAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName - -const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName - -export { - AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogHeader, - AlertDialogFooter, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, -} diff --git a/ui/components/ui/badge.tsx b/ui/components/ui/badge.tsx deleted file mode 100644 index ecc423c..0000000 --- a/ui/components/ui/badge.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const badgeVariants = cva( - "inline-flex items-center border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", - secondary: - "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - destructive: - "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", - outline: "text-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps { } - -function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) -} - -export { Badge, badgeVariants } diff --git a/ui/components/ui/button.tsx b/ui/components/ui/button.tsx deleted file mode 100644 index 0ba4277..0000000 --- a/ui/components/ui/button.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", - { - variants: { - variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button" - return ( - - ) - } -) -Button.displayName = "Button" - -export { Button, buttonVariants } diff --git a/ui/components/ui/card.tsx b/ui/components/ui/card.tsx deleted file mode 100644 index afa13ec..0000000 --- a/ui/components/ui/card.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import * as React from "react" - -import { cn } from "@/lib/utils" - -const Card = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -Card.displayName = "Card" - -const CardHeader = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardHeader.displayName = "CardHeader" - -const CardTitle = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -

-)) -CardTitle.displayName = "CardTitle" - -const CardDescription = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -

-)) -CardDescription.displayName = "CardDescription" - -const CardContent = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -

-)) -CardContent.displayName = "CardContent" - -const CardFooter = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardFooter.displayName = "CardFooter" - -export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/ui/components/ui/chart.tsx b/ui/components/ui/chart.tsx deleted file mode 100644 index 75b26b9..0000000 --- a/ui/components/ui/chart.tsx +++ /dev/null @@ -1,366 +0,0 @@ -"use client" - -import * as React from "react" -import * as RechartsPrimitive from "recharts" - -import { cn } from "@/lib/utils" - -// Format: { THEME_NAME: CSS_SELECTOR } -const THEMES = { light: "", dark: ".dark" } as const - -export type ChartConfig = { - [k in string]: { - label?: React.ReactNode - icon?: React.ComponentType - } & ( - | { color?: string; theme?: never } - | { color?: never; theme: Record } - ) -} - -type ChartContextProps = { - config: ChartConfig -} - -const ChartContext = React.createContext(null) - -function useChart() { - const context = React.useContext(ChartContext) - - if (!context) { - throw new Error("useChart must be used within a ") - } - - return context -} - -const ChartContainer = React.forwardRef< - HTMLDivElement, - React.ComponentProps<"div"> & { - config: ChartConfig - children: React.ComponentProps< - typeof RechartsPrimitive.ResponsiveContainer - >["children"] - } ->(({ id, className, children, config, ...props }, ref) => { - const uniqueId = React.useId() - const chartId = `chart-${id || uniqueId.replace(/:/g, "")}` - - return ( - -
- - - {children} - -
-
- ) -}) -ChartContainer.displayName = "Chart" - -const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { - const colorConfig = Object.entries(config).filter( - ([_, config]) => config.theme || config.color - ) - - if (!colorConfig.length) { - return null - } - - return ( -