From c47bacf3a9a223c226f237e6868c1ecd07edfd66 Mon Sep 17 00:00:00 2001 From: myusername Date: Fri, 15 May 2026 12:11:16 +0530 Subject: [PATCH] feat: Topbar component created. --- src/layouts/AdminLayout.tsx | 270 ++++++++++++++++++ src/layouts/MainLayout/BaseLayout.tsx | 28 +- src/routes/MainRouters.tsx | 21 +- src/routes/index.tsx | 2 +- .../composites/SidebarNav/SidebarNav.tsx | 2 +- .../composites/Topbar/Topbar.stories.tsx | 70 +++++ src/shared/composites/Topbar/Topbar.tsx | 60 ++++ src/shared/composites/Topbar/index.ts | 2 + src/views/LoginPage.tsx | 128 +-------- 9 files changed, 429 insertions(+), 154 deletions(-) create mode 100644 src/layouts/AdminLayout.tsx create mode 100644 src/shared/composites/Topbar/Topbar.stories.tsx create mode 100644 src/shared/composites/Topbar/Topbar.tsx create mode 100644 src/shared/composites/Topbar/index.ts diff --git a/src/layouts/AdminLayout.tsx b/src/layouts/AdminLayout.tsx new file mode 100644 index 0000000..dab3b6d --- /dev/null +++ b/src/layouts/AdminLayout.tsx @@ -0,0 +1,270 @@ +import React, { useState } from 'react' + +import { Outlet } from 'react-router-dom' + +import { SidebarNav } from '@/shared/composites/SidebarNav' + +import { Topbar } from '@/shared/composites/Topbar' + +import { AvatarMenu } from '@/shared/composites/AvatarMenu/AvatarMenu' + +import { ToastProvider } from '@/shared/integrations/Toast' + +import { + CheckIcon, + ExclamationTriangleIcon, + PresentationChartLineIcon, + QueueListIcon, + UsersIcon, +} from '@heroicons/react/24/outline' + +const AdminLayout = () => { + const [collapsed, setCollapsed] = useState(false) + const [activeItem, setActiveItem] = useState('Queue') + + return ( + //
+ // + + // {/* Sidebar */} + // + //
+ //
+ //
+ + //
+ // + //
+ //
+ //
+
+ + + + +
+ } + searchSlot={ + + } + /> + +
+ +
+
+
+ ) +} + +export default AdminLayout diff --git a/src/layouts/MainLayout/BaseLayout.tsx b/src/layouts/MainLayout/BaseLayout.tsx index 6851278..b480ce6 100644 --- a/src/layouts/MainLayout/BaseLayout.tsx +++ b/src/layouts/MainLayout/BaseLayout.tsx @@ -1,29 +1,17 @@ -import AvatarMenu from '@/shared/composites/AvatarMenu/AvatarMenu' -import { ToastProvider } from '@/shared/integrations/Toast' -import { Tooltip } from '@/shared/primitives/Tooltip' -// import ThemeToggleSwitch from '@/ThemeToggleSwitch' import React, { Suspense } from 'react' + import { Outlet } from 'react-router-dom' +import { ToastProvider } from '@/shared/integrations/Toast' + const BaseLayout: React.FC = () => { return ( -
- {/* Main Content */} +
-
-
- - -
- } - content="Settings" - position="left" - /> -
-
-
-
+ + + +
) } diff --git a/src/routes/MainRouters.tsx b/src/routes/MainRouters.tsx index 03270a3..60827bc 100644 --- a/src/routes/MainRouters.tsx +++ b/src/routes/MainRouters.tsx @@ -1,6 +1,6 @@ -import OAuthCallback from '@views/Auth/OAuthCallBack' -import BaseLayout from '@layouts/MainLayout/BaseLayout' -import NotFound from '@views/NotFound/NotFound' +// import OAuthCallback from '@views/Auth/OAuthCallBack' +// import BaseLayout from '@layouts/MainLayout/BaseLayout' +// import NotFound from '@views/NotFound/NotFound' // import HomePage from "@/views/Home/Home"; // import InscriptionDetails from "@/views/InscriptionDetailPage.tsx/InscriptionDetails"; // import Upload from "@/views/Upload/Upload"; @@ -12,24 +12,15 @@ import NotFound from '@views/NotFound/NotFound' // import Setting from "@views/Setting/Setting"; // import { Navigate } from 'react-router-dom' import LoginPage from '@/views/LoginPage' +import AdminLayout from '@/layouts/AdminLayout' -const MainRoutes = { +export const MainRoutes = { path: '/', - element: , + element: , children: [ { index: true, element: , }, - { - path: 'oauth/callback', - element: , - }, - { - path: '*', - element: , - }, ], } - -export default MainRoutes diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 15a4517..a4bade8 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,5 +1,5 @@ import { createBrowserRouter } from 'react-router-dom' -import MainRoutes from './MainRouters' +import { MainRoutes } from './MainRouters' const router = createBrowserRouter([MainRoutes]) diff --git a/src/shared/composites/SidebarNav/SidebarNav.tsx b/src/shared/composites/SidebarNav/SidebarNav.tsx index 4b54264..9c006bd 100644 --- a/src/shared/composites/SidebarNav/SidebarNav.tsx +++ b/src/shared/composites/SidebarNav/SidebarNav.tsx @@ -79,7 +79,7 @@ export function SidebarNav({ })} > {/* Header */} -
+
{!collapsed && (

ModerationOS

diff --git a/src/shared/composites/Topbar/Topbar.stories.tsx b/src/shared/composites/Topbar/Topbar.stories.tsx new file mode 100644 index 0000000..413a380 --- /dev/null +++ b/src/shared/composites/Topbar/Topbar.stories.tsx @@ -0,0 +1,70 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' + +import { MagnifyingGlassIcon, BellIcon } from '@heroicons/react/24/outline' + +import { Topbar } from './Topbar' + +import { AvatarMenu } from '@/shared/composites/AvatarMenu/AvatarMenu' + +import { Button } from '@/shared/primitives/Button' + +const meta = { + title: 'Shared/Composites/Topbar', + + component: Topbar, + + tags: ['autodocs'], +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + title: 'Moderation Queue', + + actionsSlot: ( + <> + + + + + ), + }, +} + +export const WithSearch: Story = { + args: { + title: 'Moderation Queue', + + searchSlot: ( +
+ + + +
+ ), + + actionsSlot: , + }, +} + +export const Mobile: Story = { + parameters: { + viewport: { + defaultViewport: 'mobile1', + }, + }, + + args: { + title: 'Moderation Queue', + + actionsSlot: , + }, +} diff --git a/src/shared/composites/Topbar/Topbar.tsx b/src/shared/composites/Topbar/Topbar.tsx new file mode 100644 index 0000000..5f6e0b1 --- /dev/null +++ b/src/shared/composites/Topbar/Topbar.tsx @@ -0,0 +1,60 @@ +import React from 'react' + +import { Bars3Icon } from '@heroicons/react/24/outline' + +export interface TopbarProps { + title: string + + searchSlot?: React.ReactNode + + actionsSlot?: React.ReactNode + + onMenuToggle?: () => void + + className?: string +} + +export function Topbar({ + title, + + searchSlot, + + actionsSlot, + + onMenuToggle, + + className = '', +}: TopbarProps) { + return ( +
+ {/* Left */} +
+ {/* Mobile hamburger */} + + + {/* Title */} +

{title}

+
+ + {/* Desktop Search */} + {searchSlot && ( +
+
{searchSlot}
+
+ )} + + {/* Right Actions */} +
{actionsSlot}
+
+ ) +} + +export default Topbar diff --git a/src/shared/composites/Topbar/index.ts b/src/shared/composites/Topbar/index.ts new file mode 100644 index 0000000..0e78927 --- /dev/null +++ b/src/shared/composites/Topbar/index.ts @@ -0,0 +1,2 @@ +export * from './Topbar' +export { default } from './Topbar' diff --git a/src/views/LoginPage.tsx b/src/views/LoginPage.tsx index fa22f7a..51940c8 100644 --- a/src/views/LoginPage.tsx +++ b/src/views/LoginPage.tsx @@ -1,127 +1,21 @@ import LoginCard from '@/LoginCard' -import { SidebarNav } from '@/shared/composites/SidebarNav' +// import { SidebarNav } from '@/shared/composites/SidebarNav' -import { - CheckIcon, - ExclamationTriangleIcon, - PresentationChartLineIcon, - QueueListIcon, - UsersIcon, -} from '@heroicons/react/24/outline' +// import { +// CheckIcon, +// ExclamationTriangleIcon, +// PresentationChartLineIcon, +// QueueListIcon, +// UsersIcon, +// } from '@heroicons/react/24/outline' -import { useState } from 'react' +// import { useState } from 'react' const LoginPage = () => { - const [collapsed, setCollapsed] = useState(false) - const [activeItem, setActiveItem] = useState('Queue') return ( -
- {/* Sidebar */} - - - {/* Main Content */} -
- -
+
+
) }