From 917787aac4ccdf626f3eb5bd8d4b48e7b98446ce Mon Sep 17 00:00:00 2001 From: icld Date: Thu, 6 Mar 2025 13:44:09 -0800 Subject: [PATCH] chore(ux): basic navigation functions --- .../ps/(create)/cr/(configure)/cf/page.tsx | 0 .../ps/(create)/cr/(deploy)/dp/page.tsx | 0 .../ps/(create)/cr/(success)/sc/[id]/page.tsx | 0 .../cr/(template)/tm/(configure)/cf/page.tsx | 0 .../cr/(template)/tm/(deploy)/dp/page.tsx | 0 .../ps/[id]/(deployments)/dep/page.tsx | 0 .../ps/[id]/(integrations)/int/page.tsx | 0 .../set/(collaborators)/col/page.tsx | 0 .../set/(domains)/dom/(add)/cf/page.tsx | 0 .../(domains)/dom/(add)/config/cf/page.tsx | 0 .../set/(environment-variables)/env/page.tsx | 0 .../ps/[id]/(settings)/set/(git)/page.tsx | 0 .../[orgSlug]/(projects)/ps/[id]/page.tsx | 0 .../[orgSlug]/(settings)/set/page.tsx | 0 .../(projects)/{pr => projects}/error.tsx | 0 .../(projects)/{pr => projects}/loading.tsx | 0 .../(dashboard)/_Navigation/TopNavigation.tsx | 217 ---------------- .../buy-prepaid-service/BuyServices.tsx | 128 ++++++++++ .../(dashboard)/buy-prepaid-service/page.tsx | 9 +- .../(dashboard)/layout.tsx | 14 +- apps/deploy-fe/src/app/favicon.ico | Bin 25931 -> 15406 bytes apps/deploy-fe/src/app/layout.tsx | 12 +- apps/deploy-fe/src/app/loading.tsx | 5 + apps/deploy-fe/src/app/not-found.tsx | 61 ++++- apps/deploy-fe/src/app/page.tsx | 18 +- apps/deploy-fe/src/components/.gitkeep | 0 .../src/components/assets/laconic-mark.tsx | 43 ++++ .../foundation/loading/loading-overlay.tsx | 83 ++++++ .../foundation/navigation-wrapper.tsx | 74 ++++++ .../src/components/foundation/page-header.tsx | 104 ++++++++ .../components/foundation/page-wrapper.tsx | 32 +++ .../src/components/foundation/providers.tsx | 23 ++ .../top-navigation/dark-mode-toggle.tsx | 27 ++ .../top-navigation/navigation-item.tsx | 80 ++++++ .../top-navigation/top-navigation.tsx | 120 +++++++++ .../foundation/top-navigation/types.ts | 14 ++ .../top-navigation/wallet-session-badge.tsx | 66 +++++ .../src/components/foundation/types.ts | 64 +++++ .../components/layouts/dashboard-layout.tsx | 34 --- .../deploy-fe/src/components/layouts/index.ts | 1 - .../src/components/navigation/main-nav.tsx | 38 --- .../src/components/navigation/mobile-nav.tsx | 82 ------ .../src/components/navigation/user-nav.tsx | 67 ----- .../components/page-header/breadcrumbs.tsx | 71 ------ .../src/components/page-header/header.tsx | 78 ------ .../components/page-header/page-header.tsx | 30 --- .../page-header/search-combobox.tsx | 236 ------------------ .../src/components/page-header/search.tsx | 52 ---- apps/deploy-fe/src/components/providers.tsx | 31 --- apps/deploy-fe/src/config/dashboard.ts | 110 -------- apps/deploy-fe/src/navigation/README.md | 163 ------------ apps/deploy-fe/src/navigation/breadcrumb.tsx | 60 ----- .../src/navigation/example-usage.tsx | 41 --- apps/deploy-fe/src/navigation/index.ts | 22 -- .../src/navigation/layout-wrapper.tsx | 122 --------- apps/deploy-fe/src/navigation/main-nav.tsx | 108 -------- apps/deploy-fe/src/navigation/nav-item.tsx | 47 ---- .../src/navigation/navigation-provider.tsx | 59 ----- apps/deploy-fe/src/navigation/page-header.tsx | 40 --- apps/deploy-fe/src/navigation/types.ts | 80 ------ clean.sh | 63 +++++ package.json | 3 +- services/ui/src/components/accordion.tsx | 16 +- services/ui/src/components/button.tsx | 40 +-- standards/tech-documentation.md | 215 ++++++++++++++++ 65 files changed, 1248 insertions(+), 1855 deletions(-) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(configure)/cf/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(deploy)/dp/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(success)/sc/[id]/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(configure)/cf/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(deploy)/dp/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(deployments)/dep/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(integrations)/int/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(collaborators)/col/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/cf/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/config/cf/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(environment-variables)/env/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(git)/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(projects)/ps/[id]/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/[provider]/[orgSlug]/(settings)/set/page.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/error.tsx (100%) rename apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/{pr => projects}/loading.tsx (100%) delete mode 100644 apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/_Navigation/TopNavigation.tsx create mode 100644 apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/BuyServices.tsx create mode 100644 apps/deploy-fe/src/app/loading.tsx delete mode 100644 apps/deploy-fe/src/components/.gitkeep create mode 100644 apps/deploy-fe/src/components/assets/laconic-mark.tsx create mode 100644 apps/deploy-fe/src/components/foundation/loading/loading-overlay.tsx create mode 100644 apps/deploy-fe/src/components/foundation/navigation-wrapper.tsx create mode 100644 apps/deploy-fe/src/components/foundation/page-header.tsx create mode 100644 apps/deploy-fe/src/components/foundation/page-wrapper.tsx create mode 100644 apps/deploy-fe/src/components/foundation/providers.tsx create mode 100644 apps/deploy-fe/src/components/foundation/top-navigation/dark-mode-toggle.tsx create mode 100644 apps/deploy-fe/src/components/foundation/top-navigation/navigation-item.tsx create mode 100644 apps/deploy-fe/src/components/foundation/top-navigation/top-navigation.tsx create mode 100644 apps/deploy-fe/src/components/foundation/top-navigation/types.ts create mode 100644 apps/deploy-fe/src/components/foundation/top-navigation/wallet-session-badge.tsx create mode 100644 apps/deploy-fe/src/components/foundation/types.ts delete mode 100644 apps/deploy-fe/src/components/layouts/dashboard-layout.tsx delete mode 100644 apps/deploy-fe/src/components/layouts/index.ts delete mode 100644 apps/deploy-fe/src/components/navigation/main-nav.tsx delete mode 100644 apps/deploy-fe/src/components/navigation/mobile-nav.tsx delete mode 100644 apps/deploy-fe/src/components/navigation/user-nav.tsx delete mode 100644 apps/deploy-fe/src/components/page-header/breadcrumbs.tsx delete mode 100644 apps/deploy-fe/src/components/page-header/header.tsx delete mode 100644 apps/deploy-fe/src/components/page-header/page-header.tsx delete mode 100644 apps/deploy-fe/src/components/page-header/search-combobox.tsx delete mode 100644 apps/deploy-fe/src/components/page-header/search.tsx delete mode 100644 apps/deploy-fe/src/components/providers.tsx delete mode 100644 apps/deploy-fe/src/config/dashboard.ts delete mode 100644 apps/deploy-fe/src/navigation/README.md delete mode 100644 apps/deploy-fe/src/navigation/breadcrumb.tsx delete mode 100644 apps/deploy-fe/src/navigation/example-usage.tsx delete mode 100644 apps/deploy-fe/src/navigation/index.ts delete mode 100644 apps/deploy-fe/src/navigation/layout-wrapper.tsx delete mode 100644 apps/deploy-fe/src/navigation/main-nav.tsx delete mode 100644 apps/deploy-fe/src/navigation/nav-item.tsx delete mode 100644 apps/deploy-fe/src/navigation/navigation-provider.tsx delete mode 100644 apps/deploy-fe/src/navigation/page-header.tsx delete mode 100644 apps/deploy-fe/src/navigation/types.ts create mode 100644 clean.sh create mode 100644 standards/tech-documentation.md diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(configure)/cf/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(configure)/cf/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(configure)/cf/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(configure)/cf/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(deploy)/dp/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(deploy)/dp/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(deploy)/dp/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(deploy)/dp/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(success)/sc/[id]/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(success)/sc/[id]/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(success)/sc/[id]/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(success)/sc/[id]/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(configure)/cf/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(configure)/cf/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(configure)/cf/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(configure)/cf/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(deploy)/dp/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(deploy)/dp/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(deploy)/dp/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/(create)/cr/(template)/tm/(deploy)/dp/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(deployments)/dep/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(deployments)/dep/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(deployments)/dep/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(deployments)/dep/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(integrations)/int/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(integrations)/int/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(integrations)/int/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(integrations)/int/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(collaborators)/col/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(collaborators)/col/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(collaborators)/col/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(collaborators)/col/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/cf/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/cf/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/cf/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/cf/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/config/cf/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/config/cf/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/config/cf/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(domains)/dom/(add)/config/cf/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(environment-variables)/env/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(environment-variables)/env/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(environment-variables)/env/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(environment-variables)/env/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(git)/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(git)/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(git)/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/(settings)/set/(git)/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(projects)/ps/[id]/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(projects)/ps/[id]/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(settings)/set/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(settings)/set/page.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/[provider]/[orgSlug]/(settings)/set/page.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/[provider]/[orgSlug]/(settings)/set/page.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/error.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/error.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/error.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/error.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/loading.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/loading.tsx similarity index 100% rename from apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/pr/loading.tsx rename to apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/(projects)/projects/loading.tsx diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/_Navigation/TopNavigation.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/_Navigation/TopNavigation.tsx deleted file mode 100644 index 4c030e5..0000000 --- a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/_Navigation/TopNavigation.tsx +++ /dev/null @@ -1,217 +0,0 @@ -// 'use client'; - -// import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'; -// import { LaconicMark } from '@/laconic-assets/laconic-mark'; -// import { Menu, Plus, Shapes, Wallet } from 'lucide-react'; -// import Link from 'next/link'; -// import { useRouter } from 'next/navigation'; -// import { useState } from 'react'; -// import { ProjectSearchBar } from '../search/ProjectSearchBar'; -// import { ColorModeToggle } from './components/ColorModeToggle'; -// import { GitHubSessionButton } from './components/GitHubSessionButton'; -// import { WalletSessionId } from './components/WalletSessionId'; -// import { Button } from '@workspace/ui/components/button'; - -// /** -// * TopNavigation Component -// * -// * Renders the top navigation bar, adapting its layout for desktop and mobile views. -// * It includes the project search bar, navigation links, user authentication via GitHub, -// * color mode toggle, and wallet session information. On mobile, it utilizes a sheet -// * for a responsive and accessible navigation experience. -// */ -// export function TopNavigation() { -// const router = useRouter(); -// const [showOnboarding, setShowOnboarding] = useState(false); - -// // In a real implementation, these would be from context/hooks -// const isGitHubConnected = true; // Example value -// const defaultOrg = { slug: 'demo-org' }; // Example value -// const isReady = true; // Wallet ready status - -// const handleOnboardingClose = () => { -// setShowOnboarding(false); -// // In a real implementation, would refresh organization data after onboarding -// }; - -// // Navigate to create page with organization slug -// const handleCreateNew = () => { -// if (defaultOrg) { -// router.push(`/${defaultOrg.slug}/ps/cr`); -// } else { -// // If no organization is available, show onboarding -// setShowOnboarding(true); -// } -// }; - -// const handleRunOnboarding = () => { -// // Clear existing onboarding progress data -// if (typeof window !== 'undefined') { -// localStorage.removeItem('onboarding_progress'); -// localStorage.removeItem('onboarding_state'); -// // Force starting from connect step -// localStorage.setItem('onboarding_force_connect', 'true'); -// } - -// setShowOnboarding(true); -// }; - -// return ( -//
-// {/* Top Navigation - Desktop */} -// - -// {/* Top Navigation - Mobile */} -// - -//
-// ); -// } diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/BuyServices.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/BuyServices.tsx new file mode 100644 index 0000000..70f372b --- /dev/null +++ b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/BuyServices.tsx @@ -0,0 +1,128 @@ +'use client' + +import PageWrapper from '@/components/foundation/page-wrapper' +import { Button } from '@workspace/ui/components/button' +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle +} from '@workspace/ui/components/card' +/** + * BuyPrepaidService component allows users to buy prepaid services. + * It checks if the user's balance is sufficient and redirects them to the home page if it is. + * + * @returns {JSX.Element} A JSX element that renders the buy prepaid service page. + */ +const BuyPrepaidService = () => { + return ( + +
+
+
+

+ Laconic +

+

+ Webapp Deployment Plans +

+

+ Choose the perfect deployment plan for your needs. Scale your + applications with confidence. +

+
+ +
+ {/* Basic Plan */} + + + Basic + + A simple deployment option for small projects + +
+ $5.00 + /month +
+
+ +

+ 1 monthly webapp deployment +

+
+ + + +
+ + {/* Standard Plan */} + +
+ Most popular +
+ + Standard + + Perfect for growing projects and businesses + +
+ $50.00 + /month +
+
+ +

+ 10 monthly webapp deployments +

+
+ + + +
+ + {/* Premium Plan */} + + + Premium + + For enterprises with high-volume needs + +
+ $500.00 + /month +
+
+ +

+ 100 monthly webapp deployments +

+
+ + + +
+
+
+
+
+ ) +} + +export default BuyPrepaidService diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/page.tsx index 7c4a8ac..98bdb78 100644 --- a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/page.tsx +++ b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/buy-prepaid-service/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next' +import BuyPrepaidService from './BuyServices' export const metadata: Metadata = { title: 'Buy Prepaid Service', @@ -6,13 +7,7 @@ export const metadata: Metadata = { } const Page = () => { - return ( -
-

- Hello from (web3-authenticated)/(dashboard)/(buy-prepaid-service)/bp -

-
- ) + return } export default Page diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/layout.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/layout.tsx index d4d8d2d..65afc8a 100644 --- a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/layout.tsx +++ b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/layout.tsx @@ -1,8 +1,7 @@ 'use client' -import { DashboardLayout } from '@/components/layouts' -import { defaultDashboardConfig } from '@/config/dashboard' -import type React from 'react' +import NavigationWrapper from '@/components/foundation/navigation-wrapper' +import { TopNavigation } from '@/components/foundation/top-navigation/top-navigation' interface LayoutProps { children: React.ReactNode @@ -10,13 +9,10 @@ interface LayoutProps { const Layout: React.FC = ({ children }) => { return ( - //
- //
- + + {children} - - //
- //
+ ) } diff --git a/apps/deploy-fe/src/app/favicon.ico b/apps/deploy-fe/src/app/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..ebae81e9a5987d13483269445c857818f9daeec6 100644 GIT binary patch literal 15406 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 literal 25931 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 LrJugUA?W`A8`#=m diff --git a/apps/deploy-fe/src/app/layout.tsx b/apps/deploy-fe/src/app/layout.tsx index 5115821..0b4d4c1 100644 --- a/apps/deploy-fe/src/app/layout.tsx +++ b/apps/deploy-fe/src/app/layout.tsx @@ -1,4 +1,4 @@ -import { Providers } from '@/components/providers' +import { Providers } from '@/components/foundation/providers' // import '@workspace/ui/globals.css' import type { Metadata } from 'next' @@ -26,16 +26,8 @@ export default function RootLayout({ }>) { return ( - +
- {children}
diff --git a/apps/deploy-fe/src/app/loading.tsx b/apps/deploy-fe/src/app/loading.tsx new file mode 100644 index 0000000..4170997 --- /dev/null +++ b/apps/deploy-fe/src/app/loading.tsx @@ -0,0 +1,5 @@ +import { LoadingOverlay } from '@/components/foundation/loading/loading-overlay' + +export default function Loading() { + return +} diff --git a/apps/deploy-fe/src/app/not-found.tsx b/apps/deploy-fe/src/app/not-found.tsx index 965cc12..73e0e4a 100644 --- a/apps/deploy-fe/src/app/not-found.tsx +++ b/apps/deploy-fe/src/app/not-found.tsx @@ -2,21 +2,62 @@ import type { Metadata } from 'next' import Link from 'next/link' export const metadata: Metadata = { - title: 'Page Not Found', - description: 'The requested page could not be found' + title: '404', + description: 'Page not found' } export default function NotFound() { return (
-

404 - Page Not Found

-

The page you are looking for does not exist.

- - Return Home - +
+

404

+

Page not found

+

+ Add a brief, empathetic explanation that acknowledges the error while + maintaining brand voice. Keep it light and helpful. +

+ +
+ +
+
Go back to homepage
+
+ Lorem ipsum dolor sit amet, consectetur adipisci. +
+
+ + + + +
+
Read our documentation
+
+ Lorem ipsum dolor sit amet, consectetur adipisci. +
+
+ + + + +
+
Explore our blog
+
+ Lorem ipsum dolor sit amet, consectetur adipisci. +
+
+ + +
+
) } diff --git a/apps/deploy-fe/src/app/page.tsx b/apps/deploy-fe/src/app/page.tsx index 45c225d..928ebe4 100644 --- a/apps/deploy-fe/src/app/page.tsx +++ b/apps/deploy-fe/src/app/page.tsx @@ -1,3 +1,4 @@ +import PageWrapper from '@/components/foundation/page-wrapper' import { Button } from '@workspace/ui/components/button' import type { Metadata } from 'next' @@ -7,5 +8,20 @@ export const metadata: Metadata = { } export default function Page() { - return + return ( + +
+
Hero section
+

+ Headline that solves user's main problem +

+

+ Follow with one or two sentences that expand on your value + proposition. Focus on key benefits and address why users should take + action now. Keep it scannable, short and benefit-driven. +

+ +
+
+ ) } diff --git a/apps/deploy-fe/src/components/.gitkeep b/apps/deploy-fe/src/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/deploy-fe/src/components/assets/laconic-mark.tsx b/apps/deploy-fe/src/components/assets/laconic-mark.tsx new file mode 100644 index 0000000..faa858e --- /dev/null +++ b/apps/deploy-fe/src/components/assets/laconic-mark.tsx @@ -0,0 +1,43 @@ +/** + * The Laconic logo mark component. + * + * @component + * @example + * // Basic usage + * + * + * // With custom color + * + * + * // With custom size + * + */ +export function LaconicMark({ + /** + * Optional className for styling the SVG + * Use this to customize the size, color, and other SVG properties + */ + className = '' +}: { + className?: string +}) { + return ( + + Laconic logo + + + ) +} diff --git a/apps/deploy-fe/src/components/foundation/loading/loading-overlay.tsx b/apps/deploy-fe/src/components/foundation/loading/loading-overlay.tsx new file mode 100644 index 0000000..c8c2c8a --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/loading/loading-overlay.tsx @@ -0,0 +1,83 @@ +'use client' + +import { LaconicMark } from '@/components/assets/laconic-mark' +import { cn } from '@workspace/ui/lib/utils' +import { Loader2 } from 'lucide-react' + +export interface LoadingOverlayProps { + /** + * Controls the visibility of the overlay. + * When false, the component returns null. + * @default true + */ + isLoading?: boolean + + /** + * Optional className for styling the overlay container. + * This will be merged with the default styles. + */ + className?: string + + /** + * Whether to show the Laconic logo in the overlay. + * @default true + */ + showLogo?: boolean + + /** + * Whether to show the loading spinner below the logo. + * @default true + */ + showSpinner?: boolean + + /** + * The z-index value for the overlay. + * Adjust this if you need the overlay to appear above or below other elements. + * @default 50 + */ + zIndex?: number + + /** + * Whether to use solid black background instead of semi-transparent. + * Useful for initial page load and full-screen loading states. + * @default false + */ + solid?: boolean +} + +export function LoadingOverlay({ + isLoading = true, + className, + showLogo = true, + showSpinner = true, + zIndex = 50, + solid = false +}: LoadingOverlayProps) { + if (!isLoading) return null + + return ( +
+ {showLogo && ( +
+ +
+ )} + {showSpinner && ( +
+ ) +} diff --git a/apps/deploy-fe/src/components/foundation/navigation-wrapper.tsx b/apps/deploy-fe/src/components/foundation/navigation-wrapper.tsx new file mode 100644 index 0000000..d249da9 --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/navigation-wrapper.tsx @@ -0,0 +1,74 @@ +import { cn } from '@workspace/ui/lib/utils' +import type { NavigationWrapperProps } from './types' + +/** + * NavigationWrapper component + * + * Provides a layout wrapper with a top navigation bar. + * This component is intended to be used at the layout level, + * wrapping the entire application or major sections of it. + * + * @example + * ```tsx + * // In app/layout.tsx + * export default function RootLayout({ children }) { + * return ( + * + * + * + * {children} + * + * + * + * ); + * } + * ``` + * + * @param props - The component props + * @returns A layout wrapper with top navigation + */ +export default function NavigationWrapper({ + children, + className +}: NavigationWrapperProps) { + return ( +
+ {/* Top Navigation */} + {/*
+
+
+ + App Logo + +
+ +
+ +
+
+
*/} + + {/* Main Content */} + {children} +
+ ) +} diff --git a/apps/deploy-fe/src/components/foundation/page-header.tsx b/apps/deploy-fe/src/components/foundation/page-header.tsx new file mode 100644 index 0000000..eb78dea --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/page-header.tsx @@ -0,0 +1,104 @@ +'use client' + +import { Button } from '@workspace/ui/components/button' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@workspace/ui/components/dropdown-menu' +import { cn } from '@workspace/ui/lib/utils' +import { MoreVertical } from 'lucide-react' +import Link from 'next/link' +import type { PageAction, PageHeaderProps } from './types' + +export default function PageHeader({ + title, + description, + actions = [], + className +}: PageHeaderProps) { + // Separate primary actions from secondary actions + const primaryActions = actions.filter((action) => action.isPrimary) + const secondaryActions = actions.filter((action) => !action.isPrimary) + + // Render an action (either as button or link) + const renderAction = (action: PageAction, key: string) => { + const variant = action.variant || (action.isPrimary ? 'default' : 'outline') + + if (action.href) { + return ( + + ) + } + + return ( + + ) + } + + return ( +
+
+
+

+ {title} +

+ {description && ( +

+ {description} +

+ )} +
+ + {actions.length > 0 && ( + <> + {/* Desktop buttons */} +
+ {actions.map((action, index) => + renderAction(action, `desktop-${index}`) + )} +
+ + {/* Mobile buttons */} +
+ {primaryActions.map((action, index) => + renderAction(action, `mobile-primary-${index}`) + )} + + {secondaryActions.length > 0 && ( + + + + + + {secondaryActions.map((action) => + action.href ? ( + + {action.label} + + ) : ( + + {action.label} + + ) + )} + + + )} +
+ + )} +
+
+ ) +} diff --git a/apps/deploy-fe/src/components/foundation/page-wrapper.tsx b/apps/deploy-fe/src/components/foundation/page-wrapper.tsx new file mode 100644 index 0000000..1921439 --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/page-wrapper.tsx @@ -0,0 +1,32 @@ +import { cn } from '@workspace/ui/lib/utils' +import PageHeader from './page-header' +import type { PageWrapperProps } from './types' + +export default function PageWrapper({ + header, + children, + layout = 'default', + className, + contentClassName +}: PageWrapperProps) { + return ( +
+ {header && ( +
+ +
+ )} +
+
+ {children} +
+
+
+ ) +} diff --git a/apps/deploy-fe/src/components/foundation/providers.tsx b/apps/deploy-fe/src/components/foundation/providers.tsx new file mode 100644 index 0000000..a00b0a9 --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/providers.tsx @@ -0,0 +1,23 @@ +'use client' +import { ThemeProvider } from 'next-themes' +import type * as React from 'react' +import '@workspace/ui/globals.css' +import { Toaster } from 'sonner' + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + <> + + + {children} + + + ) +} diff --git a/apps/deploy-fe/src/components/foundation/top-navigation/dark-mode-toggle.tsx b/apps/deploy-fe/src/components/foundation/top-navigation/dark-mode-toggle.tsx new file mode 100644 index 0000000..c113acf --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/top-navigation/dark-mode-toggle.tsx @@ -0,0 +1,27 @@ +'use client' + +import { Button } from '@workspace/ui/components/button' +import { Moon, Sun } from 'lucide-react' +import { useTheme } from 'next-themes' + +export function DarkModeToggle() { + const { theme, setTheme } = useTheme() + + return ( + + ) +} diff --git a/apps/deploy-fe/src/components/foundation/top-navigation/navigation-item.tsx b/apps/deploy-fe/src/components/foundation/top-navigation/navigation-item.tsx new file mode 100644 index 0000000..93d5273 --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/top-navigation/navigation-item.tsx @@ -0,0 +1,80 @@ +'use client' + +import { Button } from '@workspace/ui/components/button' +import { cn } from '@workspace/ui/lib/utils' +import type { LucideIcon } from 'lucide-react' +import Link from 'next/link' +import type React from 'react' + +interface NavigationItemProps { + href?: string + onClick?: () => void + className?: string + active?: boolean + icon?: LucideIcon + children: React.ReactNode + variant?: + | 'default' + | 'destructive' + | 'outline' + | 'secondary' + | 'ghost' + | 'link' + isDrawerItem?: boolean +} + +export function NavigationItem({ + href, + onClick, + className, + active = false, + icon: Icon, + children, + variant = 'ghost', + isDrawerItem = false +}: NavigationItemProps) { + // For drawer items, use a simpler styling approach + if (isDrawerItem) { + const content = ( +
+ {children} +
+ ) + + if (href) { + return {content} + } + + return + } + + // For regular navigation items, use the Button component + const content = ( + <> + {Icon && } + {children} + + ) + + const buttonClassName = cn(active && 'font-semibold', className) + + if (href) { + return ( + + ) + } + + return ( + + ) +} diff --git a/apps/deploy-fe/src/components/foundation/top-navigation/top-navigation.tsx b/apps/deploy-fe/src/components/foundation/top-navigation/top-navigation.tsx new file mode 100644 index 0000000..6873bdf --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/top-navigation/top-navigation.tsx @@ -0,0 +1,120 @@ +'use client' + +import { LaconicMark } from '@/components/assets/laconic-mark' +import { Button } from '@workspace/ui/components/button' +import { + Sheet, + SheetClose, + SheetContent, + SheetTrigger +} from '@workspace/ui/components/sheet' +import { Menu } from 'lucide-react' +import Link from 'next/link' +import type React from 'react' +import { DarkModeToggle } from './dark-mode-toggle' +import { NavigationItem } from './navigation-item' +import type { TopNavigationConfig } from './types' +import { WalletSessionBadge } from './wallet-session-badge' + +interface TopNavigationProps { + config?: TopNavigationConfig + children?: React.ReactNode +} + +export function TopNavigation({ + config = { + leftItems: [ + { label: 'Projects', href: '/projects' }, + { label: 'Wallet', href: '/wallets' } + ], + rightItems: [ + { label: 'Support', href: '/support' }, + { label: 'Documentation', href: '/documentation' } + ] + } +}: TopNavigationProps) { + const { leftItems = [], rightItems = [] } = config + + return ( +
+
+ {/* Mobile menu trigger - positioned on the left */} +
+ + + + + +
+ + + + + Close + +
+
+ +
+
+
+
+ + + + + +
+ {leftItems.map((item) => ( + + {item.label} + + ))} +
+ +
+ + + + +
+
+
+ ) +} diff --git a/apps/deploy-fe/src/components/foundation/top-navigation/types.ts b/apps/deploy-fe/src/components/foundation/top-navigation/types.ts new file mode 100644 index 0000000..f1a8e5d --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/top-navigation/types.ts @@ -0,0 +1,14 @@ +import type { LucideIcon } from 'lucide-react' + +export interface NavigationItemConfig { + label: string + href?: string + onClick?: () => void + icon?: LucideIcon + active?: boolean +} + +export interface TopNavigationConfig { + leftItems?: NavigationItemConfig[] + rightItems?: NavigationItemConfig[] +} diff --git a/apps/deploy-fe/src/components/foundation/top-navigation/wallet-session-badge.tsx b/apps/deploy-fe/src/components/foundation/top-navigation/wallet-session-badge.tsx new file mode 100644 index 0000000..2a049de --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/top-navigation/wallet-session-badge.tsx @@ -0,0 +1,66 @@ +'use client' + +import { Button } from '@workspace/ui/components/button' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from '@workspace/ui/components/dropdown-menu' +import { cn } from '@workspace/ui/lib/utils' +import { ChevronDown, LogOut } from 'lucide-react' +import { useState } from 'react' + +interface WalletSessionBadgeProps { + address: string + className?: string +} + +export function WalletSessionBadge({ + address, + className +}: WalletSessionBadgeProps) { + const [isConnected, setIsConnected] = useState(true) + + return ( + + + + + + setIsConnected(false)} + > + + Disconnect + + + + ) +} diff --git a/apps/deploy-fe/src/components/foundation/types.ts b/apps/deploy-fe/src/components/foundation/types.ts new file mode 100644 index 0000000..55b7dfa --- /dev/null +++ b/apps/deploy-fe/src/components/foundation/types.ts @@ -0,0 +1,64 @@ +import type { ReactNode } from 'react' + +/** + * Props for the NavigationWrapper component + */ +export interface NavigationWrapperProps { + /** + * Content to be displayed within the navigation wrapper + * Typically includes PageWrapper components + */ + children: ReactNode + + /** + * Optional CSS class name to apply custom styles to the wrapper container + */ + className?: string +} + +export interface PageAction { + label: string + variant?: + | 'default' + | 'destructive' + | 'outline' + | 'secondary' + | 'ghost' + | 'link' + onClick?: () => void + href?: string + isPrimary?: boolean +} + +export interface PageHeaderProps { + title: string + description?: string + actions?: PageAction[] + className?: string +} + +export type PageWrapperLayout = 'default' | 'bento' + +export interface PageWrapperProps { + /** + * Optional header props for the page + */ + header?: PageHeaderProps + /** + * Content to be displayed below the header + */ + children: ReactNode + /** + * Layout style for the page + * @default "default" + */ + layout?: PageWrapperLayout + /** + * Optional className for additional styling + */ + className?: string + /** + * Optional className for the content container + */ + contentClassName?: string +} diff --git a/apps/deploy-fe/src/components/layouts/dashboard-layout.tsx b/apps/deploy-fe/src/components/layouts/dashboard-layout.tsx deleted file mode 100644 index 5f5c2ac..0000000 --- a/apps/deploy-fe/src/components/layouts/dashboard-layout.tsx +++ /dev/null @@ -1,34 +0,0 @@ -'use client' - -import { Header } from '@/components/page-header/header' -import { PageHeader } from '@/components/page-header/page-header' -import type { DashboardLayoutConfig } from '@/types/dashboard' -import { cn } from '@workspace/ui/lib/utils' -import type React from 'react' - -interface DashboardLayoutProps { - config: DashboardLayoutConfig - children: React.ReactNode - className?: string -} - -export function DashboardLayout({ - config, - children, - className -}: DashboardLayoutProps) { - const { headerConfig, pageHeaderConfig } = config - - return ( -
- {/* Top Navigation */} -
- - {/* Page Header with breadcrumbs */} - - - {/* Content Area */} -
{children}
-
- ) -} diff --git a/apps/deploy-fe/src/components/layouts/index.ts b/apps/deploy-fe/src/components/layouts/index.ts deleted file mode 100644 index a6606ce..0000000 --- a/apps/deploy-fe/src/components/layouts/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { DashboardLayout } from './dashboard-layout' diff --git a/apps/deploy-fe/src/components/navigation/main-nav.tsx b/apps/deploy-fe/src/components/navigation/main-nav.tsx deleted file mode 100644 index 582026b..0000000 --- a/apps/deploy-fe/src/components/navigation/main-nav.tsx +++ /dev/null @@ -1,38 +0,0 @@ -'use client' - -import type { NavItem } from '@/types/dashboard' -import { cn } from '@workspace/ui/lib/utils' -import Link from 'next/link' -import { usePathname } from 'next/navigation' - -interface MainNavProps { - items: NavItem[] - className?: string -} - -export function MainNav({ items, className }: MainNavProps) { - const pathname = usePathname() - - return ( - - ) -} diff --git a/apps/deploy-fe/src/components/navigation/mobile-nav.tsx b/apps/deploy-fe/src/components/navigation/mobile-nav.tsx deleted file mode 100644 index 74fcff9..0000000 --- a/apps/deploy-fe/src/components/navigation/mobile-nav.tsx +++ /dev/null @@ -1,82 +0,0 @@ -'use client' - -import { useNavigation } from '@/navigation' -import type { NavItem } from '@/types/dashboard' -import { Button } from '@workspace/ui/components/button' -import { - Sheet, - SheetContent, - SheetHeader, - SheetTitle, - SheetTrigger -} from '@workspace/ui/components/sheet' -import { cn } from '@workspace/ui/lib/utils' -import { Menu, Package2 } from 'lucide-react' -import Link from 'next/link' -import { usePathname } from 'next/navigation' -import type { ReactNode } from 'react' - -interface MobileNavProps { - items: NavItem[] - logo?: ReactNode - title?: string - className?: string -} - -export function MobileNav({ - items, - logo = , - title = 'Navigation', - className -}: MobileNavProps) { - const pathname = usePathname() - const { mobileMenuOpen, toggleMobileMenu } = useNavigation() - - return ( - - - - - - - - {logo} - {title} - - - - - - ) -} diff --git a/apps/deploy-fe/src/components/navigation/user-nav.tsx b/apps/deploy-fe/src/components/navigation/user-nav.tsx deleted file mode 100644 index 628ba64..0000000 --- a/apps/deploy-fe/src/components/navigation/user-nav.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client' - -import type { UserNavConfig } from '@/types/dashboard' -import { Button } from '@workspace/ui/components/button' -import { CircleUser } from 'lucide-react' - -interface UserNavProps extends UserNavConfig { - className?: string -} - -export function UserNav({ - avatarSrc, - username, - email, - showMobile = true, - className -}: UserNavProps) { - return ( -
- {/* Desktop user button */} - - - {/* Mobile user button */} - {showMobile && ( - - )} -
- ) -} - -import { cn } from '@workspace/ui/lib/utils' diff --git a/apps/deploy-fe/src/components/page-header/breadcrumbs.tsx b/apps/deploy-fe/src/components/page-header/breadcrumbs.tsx deleted file mode 100644 index 3625627..0000000 --- a/apps/deploy-fe/src/components/page-header/breadcrumbs.tsx +++ /dev/null @@ -1,71 +0,0 @@ -'use client' - -import type { BreadcrumbsConfig } from '@/types/dashboard' -import { cn } from '@workspace/ui/lib/utils' -import { ChevronRight } from 'lucide-react' -import Link from 'next/link' -import { usePathname } from 'next/navigation' -import React from 'react' - -interface BreadcrumbsProps extends BreadcrumbsConfig { - className?: string -} - -export function Breadcrumbs({ - homeLabel = 'Home', - homeHref = '/', - pathMap = {}, - className -}: BreadcrumbsProps) { - const pathname = usePathname() - - // Generate breadcrumbs from the current path - const breadcrumbs = generateBreadcrumbs(pathname, pathMap) - - return ( -
- - {homeLabel} - - - {breadcrumbs.map((crumb) => ( - - - - {crumb.label} - - - ))} -
- ) -} - -// Helper function to generate breadcrumbs from the current path -function generateBreadcrumbs( - pathname: string, - pathMap: Record = {} -): Array<{ href: string; label: string }> { - const paths = pathname.split('/').filter(Boolean) - - return paths.map((path, index) => { - // Build the URL up to this point - const href = `/${paths.slice(0, index + 1).join('/')}` - - // Use the mapping if available, otherwise capitalize the path - const label = pathMap[path] || path.charAt(0).toUpperCase() + path.slice(1) - - return { href, label } - }) -} diff --git a/apps/deploy-fe/src/components/page-header/header.tsx b/apps/deploy-fe/src/components/page-header/header.tsx deleted file mode 100644 index 9e59007..0000000 --- a/apps/deploy-fe/src/components/page-header/header.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client' - -import { MainNav } from '@/components/navigation/main-nav' -import { MobileNav } from '@/components/navigation/mobile-nav' -import { UserNav } from '@/components/navigation/user-nav' -import { SearchCombobox } from '@/components/page-header/search-combobox' -import type { HeaderConfig } from '@/types/dashboard' -import { cn } from '@workspace/ui/lib/utils' -import { Package2 } from 'lucide-react' -import Link from 'next/link' - -interface HeaderProps extends HeaderConfig { - className?: string -} - -export function Header({ - logo = , - logoMobile, - navItems, - searchConfig, - userConfig, - className -}: HeaderProps) { - // Use the mobile logo if provided, otherwise use the desktop logo - const mobileLogoElement = logoMobile || ( -
- - Application Logo - - -
- ) - - return ( -
- {/* Mobile: Left section with menu */} -
- -
- - {/* Desktop: Left section with logo and nav */} -
- {logo} - -
- - {/* Mobile: Center logo */} -
- {mobileLogoElement} -
- - {/* Right section */} -
- - -
-
- ) -} diff --git a/apps/deploy-fe/src/components/page-header/page-header.tsx b/apps/deploy-fe/src/components/page-header/page-header.tsx deleted file mode 100644 index c7a674f..0000000 --- a/apps/deploy-fe/src/components/page-header/page-header.tsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client' - -import type React from 'react' - -import { Breadcrumbs } from '@/components/page-header/breadcrumbs' -import type { PageHeaderConfig } from '@/types/dashboard' -import { cn } from '@workspace/ui/lib/utils' - -interface PageHeaderProps extends PageHeaderConfig { - className?: string - children?: React.ReactNode -} - -export function PageHeader({ - breadcrumbsConfig, - className, - children -}: PageHeaderProps) { - return ( -
-
- {/* Breadcrumb */} - - - {/* Optional content */} - {children} -
-
- ) -} diff --git a/apps/deploy-fe/src/components/page-header/search-combobox.tsx b/apps/deploy-fe/src/components/page-header/search-combobox.tsx deleted file mode 100644 index 99168e9..0000000 --- a/apps/deploy-fe/src/components/page-header/search-combobox.tsx +++ /dev/null @@ -1,236 +0,0 @@ -'use client' - -import type { SearchConfig, SearchResultItem } from '@/types/dashboard' -import { Button } from '@workspace/ui/components/button' -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList -} from '@workspace/ui/components/command' -import { Input } from '@workspace/ui/components/input' -import { - Popover, - PopoverContent, - PopoverTrigger -} from '@workspace/ui/components/popover' -import { cn } from '@workspace/ui/lib/utils' -import { - FileText, - Laptop, - Package, - SearchIcon, - Settings, - Users -} from 'lucide-react' -import * as React from 'react' - -interface SearchComboboxProps extends SearchConfig { - className?: string -} - -// Default icons for different categories -const categoryIcons = { - projects: , - documents: , - settings: , - users: , - default: -} as const satisfies Record - -export function SearchCombobox({ - placeholder = 'Search...', - onSearch, - showMobile = true, - searchResults = [], - onSelectItem, - categories = [], - className -}: SearchComboboxProps) { - const [open, setOpen] = React.useState(false) - const [query, setQuery] = React.useState('') - const [groupedResults, setGroupedResults] = React.useState< - Record - >({}) - - // Filter results based on query - const filteredResults = query - ? searchResults.filter( - (item) => - item.title.toLowerCase().includes(query.toLowerCase()) || - item.description?.toLowerCase().includes(query.toLowerCase()) - ) - : searchResults - - // Group results by category - React.useEffect(() => { - const grouped: Record = {} - - // Initialize with empty arrays for each category - for (const category in categories) { - if (Object.prototype.hasOwnProperty.call(categories, category)) { - const cat = categories[category] as string - grouped[cat] = [] - } - } - - // Add "Other" category if there are items without a category - grouped.Other = [] - - // Group items by category - for (const idx in filteredResults) { - if (Object.prototype.hasOwnProperty.call(filteredResults, idx)) { - const result = filteredResults[idx] as SearchResultItem - const categoryKey = (result.category ?? 'default') as - | keyof typeof categoryIcons - | 'Other' - - if (Object.keys(categoryIcons).includes(categoryKey)) { - if (!grouped[categoryKey]) { - grouped[categoryKey] = [] - } - grouped[categoryKey].push(result) - } else { - grouped.Other.push(result) - } - } - } - - // Remove empty categories - setGroupedResults( - Object.fromEntries( - Object.entries(grouped).filter(([_, items]) => items.length > 0) - ) - ) - }, [filteredResults, categories]) - - const handleSelect = (item: SearchResultItem) => { - setOpen(false) - if (onSelectItem) { - onSelectItem(item) - } - } - - const handleSearch = (e: React.FormEvent) => { - e.preventDefault() - if (onSearch) { - onSearch(query) - } - } - - return ( -
- {/* Mobile search button */} - {showMobile && ( - - - - - - - - - No results found. - {Object.entries(groupedResults).map(([category, items]) => ( - - {items.map((item) => ( - handleSelect(item)} - className="flex items-center" - > - {item.icon ? ( - - ) : ( - categoryIcons[ - item.category && - Object.keys(categoryIcons).includes(item.category) - ? (item.category as keyof typeof categoryIcons) - : 'default' - ] - )} -
- {item.title} - {item.description && ( - - {item.description} - - )} -
-
- ))} -
- ))} -
-
-
-
- )} - - {/* Desktop search */} -
- - -
- -
- setQuery(e.target.value)} - onFocus={() => setOpen(true)} - /> -
-
-
- - - - No results found. - {Object.entries(groupedResults).map(([category, items]) => ( - - {items.map((item) => ( - handleSelect(item)} - className="flex items-center" - > - {item.icon ? ( - - ) : ( - categoryIcons[ - item.category && - Object.keys(categoryIcons).includes(item.category) - ? (item.category as keyof typeof categoryIcons) - : 'default' - ] - )} -
- {item.title} - {item.description && ( - - {item.description} - - )} -
-
- ))} -
- ))} -
-
-
-
-
-
- ) -} diff --git a/apps/deploy-fe/src/components/page-header/search.tsx b/apps/deploy-fe/src/components/page-header/search.tsx deleted file mode 100644 index ac28150..0000000 --- a/apps/deploy-fe/src/components/page-header/search.tsx +++ /dev/null @@ -1,52 +0,0 @@ -'use client' - -import type React from 'react' - -import type { SearchConfig } from '@/types/dashboard' -import { Button } from '@workspace/ui/components/button' -import { Input } from '@workspace/ui/components/input' -import { cn } from '@workspace/ui/lib/utils' -import { SearchIcon } from 'lucide-react' -import { useState } from 'react' - -interface SearchProps extends SearchConfig { - className?: string -} - -export function Search({ - placeholder = 'Search...', - onSearch, - showMobile = true, - className -}: SearchProps) { - const [query, setQuery] = useState('') - - const handleSearch = (e: React.FormEvent) => { - e.preventDefault() - if (onSearch) { - onSearch(query) - } - } - - return ( -
- {/* Mobile search button */} - {showMobile && ( - - )} - - {/* Desktop search */} -
- - setQuery(e.target.value)} - /> - -
- ) -} diff --git a/apps/deploy-fe/src/components/providers.tsx b/apps/deploy-fe/src/components/providers.tsx deleted file mode 100644 index 1d1dec0..0000000 --- a/apps/deploy-fe/src/components/providers.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client' - -import { Button } from '@workspace/ui/components/button' -import { ThemeProvider as NextThemesProvider } from 'next-themes' -import type * as React from 'react' -import '@workspace/ui/globals.css' -import { Toaster, toast } from 'sonner' -export function Providers({ children }: { children: React.ReactNode }) { - return ( - - - - {children} - - ) -} diff --git a/apps/deploy-fe/src/config/dashboard.ts b/apps/deploy-fe/src/config/dashboard.ts deleted file mode 100644 index a30995a..0000000 --- a/apps/deploy-fe/src/config/dashboard.ts +++ /dev/null @@ -1,110 +0,0 @@ -import type { - DashboardLayoutConfig, - NavItem, - SearchResultItem -} from '@/types/dashboard' -import { - FileText, - Package2, - Settings, - ShoppingCart, - Users, - Wallet -} from 'lucide-react' - -// Navigation items for the dashboard -export const dashboardNavItems: NavItem[] = [ - { - title: 'Projects', - href: '/projects', - icon: Package2 - }, - { - title: 'Buy Prepaid', - href: '/bp', - icon: ShoppingCart - }, - { - title: 'Wallet', - href: '/wallet', - icon: Wallet - } -] - -// Path mapping for breadcrumbs -export const dashboardPathMap: Record = { - projects: 'Projects', - bp: 'Buy Prepaid', - wallet: 'Wallet' -} - -// Sample search results for the combobox -export const sampleSearchResults: SearchResultItem[] = [ - { - id: '1', - title: 'Project Alpha', - description: 'Main production project', - href: '/projects/alpha', - icon: Package2, - category: 'Projects' - }, - { - id: '2', - title: 'Project Beta', - description: 'Development environment', - href: '/projects/beta', - icon: Package2, - category: 'Projects' - }, - { - id: '3', - title: 'Billing Settings', - description: 'Manage payment methods', - href: '/wallet/settings', - icon: Settings, - category: 'Settings' - }, - { - id: '4', - title: 'Team Members', - description: 'Manage team access', - href: '/team', - icon: Users, - category: 'Users' - }, - { - id: '5', - title: 'API Documentation', - description: 'Developer resources', - href: '/docs/api', - icon: FileText, - category: 'Documents' - } -] - -// Default dashboard layout configuration -export const defaultDashboardConfig: DashboardLayoutConfig = { - headerConfig: { - navItems: dashboardNavItems, - searchConfig: { - placeholder: 'Search projects, docs, settings...', - searchResults: sampleSearchResults, - categories: ['Projects', 'Documents', 'Settings', 'Users'], - onSelectItem: (item) => { - // In a real app, you would use router.push(item.href) - console.log('Selected item:', item) - window.location.href = item.href - } - }, - userConfig: { - showMobile: true - } - }, - pageHeaderConfig: { - breadcrumbsConfig: { - homeLabel: 'Home', - homeHref: '/', - pathMap: dashboardPathMap - } - } -} diff --git a/apps/deploy-fe/src/navigation/README.md b/apps/deploy-fe/src/navigation/README.md deleted file mode 100644 index a1b31ce..0000000 --- a/apps/deploy-fe/src/navigation/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Navigation Components - -A collection of reusable navigation components for the deploy-fe application. - -## Components - -### MainNav - -The main navigation bar component that displays the logo, menu items, and user profile. - -```tsx -import { MainNav } from "@/navigation"; - -const navItems = [ - { - href: "/dashboard", - label: "Dashboard", - icon: LayoutDashboard, - }, - { - href: "/orders", - label: "Orders", - icon: ShoppingCart, - badge: "2", - }, - // ... -]; - -const user = { - name: "John Doe", - avatarUrl: "/avatar.png", - menuItems: [ - { label: "Profile", href: "/profile" }, - { label: "Settings", href: "/settings" }, - { label: "Logout", href: "/logout" }, - ], -}; - - -``` - -### PageHeader - -The page header component that displays the title, description, breadcrumbs, and action buttons. - -```tsx -import { PageHeader } from "@/navigation"; -import { Button } from "@workspace/ui/components/button"; - -Share, - , - , - , - ]} -/> -``` - -### Breadcrumb - -The breadcrumb component that displays a navigation trail. - -```tsx -import { Breadcrumb } from "@/navigation"; - - -``` - -### NavItem - -The navigation item component that displays a link with an optional icon and badge. - -```tsx -import { NavItem } from "@/navigation"; -import { Home } from "lucide-react"; - - -``` - -### LayoutWrapper - -A wrapper component that combines the MainNav and PageHeader components. - -```tsx -import { LayoutWrapper } from "@/navigation"; -import { Button } from "@workspace/ui/components/button"; - -Share, - , - , - , - ]} -> -
Your content here
-
-``` - -## State Management - -### useNavigation - -A Zustand store hook that provides access to the navigation state. This can be used directly from any component without needing a provider. - -```tsx -import { useNavigation } from "@/navigation"; - -function MyComponent() { - const { activePath, mobileMenuOpen, toggleMobileMenu } = useNavigation(); - - return ( -
- -
Active path: {activePath}
-
- ); -} -``` - -### NavigationProvider (Optional) - -The navigation provider component that syncs the active path with the URL. This is optional and only needed if you want to automatically update the active path based on the current URL. - -```tsx -import { NavigationProvider } from "@/navigation"; - - - - -``` - -## Example - -See the `example-usage.tsx` file for a complete example of how to use these components together. diff --git a/apps/deploy-fe/src/navigation/breadcrumb.tsx b/apps/deploy-fe/src/navigation/breadcrumb.tsx deleted file mode 100644 index 9bd3108..0000000 --- a/apps/deploy-fe/src/navigation/breadcrumb.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { cn } from '@workspace/ui/lib/utils' -import { ChevronRight } from 'lucide-react' -import Link from 'next/link' - -import type { BreadcrumbProps } from './types' - -/** - * Breadcrumb component - * Displays a breadcrumb trail for navigation - * - * @param props - Component props - * @returns Breadcrumb component - */ -export function Breadcrumb({ - items, - separator = , - className -}: BreadcrumbProps) { - if (!items || items.length === 0) { - return null - } - - return ( - - ) -} diff --git a/apps/deploy-fe/src/navigation/example-usage.tsx b/apps/deploy-fe/src/navigation/example-usage.tsx deleted file mode 100644 index 2608503..0000000 --- a/apps/deploy-fe/src/navigation/example-usage.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Button } from '@workspace/ui/components/button' - -import { LayoutWrapper } from './layout-wrapper' - -/** - * ExampleUsage component - * Demonstrates how to use the LayoutWrapper component - * - * @returns ExampleUsage component - */ -export function ExampleUsage() { - return ( - - Share - , - , - , - - ]} - > -
- Slot (swap it with your content) -
-
- ) -} diff --git a/apps/deploy-fe/src/navigation/index.ts b/apps/deploy-fe/src/navigation/index.ts deleted file mode 100644 index ebc9d11..0000000 --- a/apps/deploy-fe/src/navigation/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Export components -export { Breadcrumb } from './breadcrumb' -export { ExampleUsage } from './example-usage' -export { LayoutWrapper } from './layout-wrapper' -export { MainNav } from './main-nav' -export { NavItem } from './nav-item' -export { PageHeader } from './page-header' - -// Export providers -export { NavigationProvider, useNavigation } from './navigation-provider' - -// Export types -export type { - BreadcrumbItem, - BreadcrumbProps, - MainNavProps, - NavItemProps, - NavItem as NavItemType, - PageHeaderProps, - UserMenuItem, - UserProfile -} from './types' diff --git a/apps/deploy-fe/src/navigation/layout-wrapper.tsx b/apps/deploy-fe/src/navigation/layout-wrapper.tsx deleted file mode 100644 index c44bb81..0000000 --- a/apps/deploy-fe/src/navigation/layout-wrapper.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { - LayoutDashboard, - Package, - Settings, - ShoppingCart, - Users -} from 'lucide-react' -import type { ReactNode } from 'react' - -import { MainNav } from './main-nav' -import { NavigationProvider } from './navigation-provider' -import { PageHeader } from './page-header' -import type { BreadcrumbItem } from './types' - -interface LayoutWrapperProps { - children: ReactNode - title: string - description?: string - breadcrumbs?: BreadcrumbItem[] - actions?: ReactNode[] -} - -/** - * LayoutWrapper component - * Provides a consistent layout with navigation and page header - * - * @param props - Component props - * @returns LayoutWrapper component - */ -export function LayoutWrapper({ - children, - title, - description, - breadcrumbs, - actions -}: LayoutWrapperProps) { - // Example navigation items - const navItems = [ - { - href: '/dashboard', - label: 'Dashboard', - icon: LayoutDashboard - }, - { - href: '/orders', - label: 'Orders', - icon: ShoppingCart, - badge: '2' - }, - { - href: '/products', - label: 'Products', - icon: Package - }, - { - href: '/customers', - label: 'Customers', - icon: Users - }, - { - href: '/settings', - label: 'Settings', - icon: Settings - } - ] - - // Example user profile - const user = { - name: 'John Doe', - avatarUrl: '', - menuItems: [ - { label: 'Profile', href: '/profile' }, - { label: 'Settings', href: '/settings' }, - { label: 'Logout', href: '/logout' } - ] - } - - return ( - -
- - -
- - -
{children}
-
-
-
- ) -} - -/** - * Example usage: - * - * ```tsx - * Share, - * , - * , - * , - * ]} - * > - *
- * Slot (swap it with your content) - *
- *
- * ``` - */ diff --git a/apps/deploy-fe/src/navigation/main-nav.tsx b/apps/deploy-fe/src/navigation/main-nav.tsx deleted file mode 100644 index 932e050..0000000 --- a/apps/deploy-fe/src/navigation/main-nav.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { Button } from '@workspace/ui/components/button' -import { cn } from '@workspace/ui/lib/utils' -import { Menu } from 'lucide-react' - -import { NavItem } from './nav-item' -import { useNavigation } from './navigation-provider' -import type { MainNavProps } from './types' - -/** - * MainNav component - * Renders the main navigation bar with logo, menu items, and user profile - * - * @param props - Component props - * @returns MainNav component - */ -export function MainNav({ logo, items, user, className }: MainNavProps) { - const { mobileMenuOpen, toggleMobileMenu } = useNavigation() - - return ( -
-
- {/* Logo and mobile menu toggle */} -
- {logo ? ( -
{logo}
- ) : ( -
- Logo -
-
- )} - - -
- - {/* Desktop navigation */} - - - {/* Mobile navigation */} - {mobileMenuOpen && ( -
- -
- )} - - {/* Right side items (user profile, etc.) */} -
- {user && ( -
-
- {user.name} -
-
- -
- )} -
-
-
- ) -} diff --git a/apps/deploy-fe/src/navigation/nav-item.tsx b/apps/deploy-fe/src/navigation/nav-item.tsx deleted file mode 100644 index 55bbb42..0000000 --- a/apps/deploy-fe/src/navigation/nav-item.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { cn } from '@workspace/ui/lib/utils' -import Link from 'next/link' - -import { useNavigation } from './navigation-provider' -import type { NavItemProps } from './types' - -/** - * NavItem component - * Renders a navigation link with optional icon and badge - * - * @param props - Component props - * @returns NavItem component - */ -export function NavItem({ - href, - label, - icon: Icon, - badge, - isActive: forcedActive, - className -}: NavItemProps) { - const { activePath } = useNavigation() - const isActive = - forcedActive !== undefined ? forcedActive : activePath === href - - return ( - - {Icon &&