chore(routing): Basic routing within navigation

This commit is contained in:
icld
2025-03-17 17:09:07 -07:00
parent b649299fcc
commit 206132088f
13 changed files with 1015 additions and 31 deletions
@@ -21,14 +21,7 @@ const BuyPrepaidService = () => {
<PageWrapper
header={{
title: 'Buy Prepaid Service',
subtitle: 'Choose a plan that fits your deployment needs',
actions: [
{
label: 'Buy prepaid service',
href: process.env.NEXT_PUBLIC_SHOPIFY_APP_URL,
isPrimary: true
}
]
subtitle: 'Choose a plan that fits your deployment needs'
}}
>
<div className=" mx-auto px-4 py-16 md:py-18 w-full">
@@ -65,8 +58,14 @@ const BuyPrepaidService = () => {
</p>
</CardContent>
<CardFooter>
<Button className="w-full" variant="outline">
Purchase plan
<Button className="w-full" variant="outline" asChild>
<a
href="https://store.laconic.com/products/1-webapp-deployment"
target="_blank"
rel="noopener noreferrer"
>
Purchase plan
</a>
</Button>
</CardFooter>
</Card>
@@ -92,7 +91,15 @@ const BuyPrepaidService = () => {
</p>
</CardContent>
<CardFooter>
<Button className="w-full">Purchase plan</Button>
<Button className="w-full" asChild>
<a
href="https://store.laconic.com/products/10-webapp-deployments"
target="_blank"
rel="noopener noreferrer"
>
Purchase plan
</a>
</Button>
</CardFooter>
</Card>
@@ -114,8 +121,14 @@ const BuyPrepaidService = () => {
</p>
</CardContent>
<CardFooter>
<Button className="w-full" variant="outline">
Purchase plan
<Button className="w-full" variant="outline" asChild>
<a
href="https://store.laconic.com/products/100-webapp-deployments"
target="_blank"
rel="noopener noreferrer"
>
Purchase plan
</a>
</Button>
</CardFooter>
</Card>
@@ -0,0 +1,669 @@
'use client'
import { Separator } from '@radix-ui/react-dropdown-menu'
import { Button } from '@workspace/ui/components/button'
import { Input } from '@workspace/ui/components/input'
import {
Sheet,
SheetContent,
SheetTrigger
} from '@workspace/ui/components/sheet'
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger
} from '@workspace/ui/components/tabs'
import {
ChevronDown,
Code,
Copy,
Github,
Globe,
Menu,
Moon,
Search,
Sun,
Terminal,
X
} from 'lucide-react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
// Add this component after the imports
function ComingSoonOverlay({ routerAction }: { routerAction: () => void }) {
return (
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background/35 backdrop-blur-sm">
<div className="text-center space-y-4 max-w-md px-4 bg-background/80 p-8 rounded-lg shadow-lg">
<Globe className="h-16 w-16 mx-auto text-primary" />
<h1 className="text-4xl font-bold tracking-tight">Coming Soon</h1>
<p className="text-xl text-muted-foreground">
Our documentation is currently under development. Check back soon for
comprehensive guides and tutorials.
</p>
<div className="pt-4">
<Button size="lg" onClick={() => routerAction()}>
Get Notified When We Launch
</Button>
</div>
</div>
</div>
)
}
export default function DocumentationPage() {
const [isMobileNavOpen, setIsMobileNavOpen] = useState(false)
const [isDarkMode, setIsDarkMode] = useState(false)
const router = useRouter()
const toggleDarkMode = () => {
setIsDarkMode(!isDarkMode)
document.documentElement.classList.toggle('dark')
}
return (
<div className={`min-h-screen flex flex-col ${isDarkMode ? 'dark' : ''}`}>
<ComingSoonOverlay routerAction={() => router.back()} />
{/* Header */}
<header className="sticky top-0 z-40 w-full border-b bg-background">
<div className="container flex h-16 items-center space-x-4 sm:justify-between sm:space-x-0">
<div className="flex gap-6 md:gap-10">
<Link href="/" className="flex items-center space-x-2">
<Globe className="h-6 w-6" />
<span className="inline-block font-bold">Laconic Deploy</span>
</Link>
<nav className="hidden md:flex gap-6">
<Link
href="#"
className="flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
>
Documentation
</Link>
<Link
href="#"
className="flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
>
API Reference
</Link>
<Link
href="#"
className="flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
>
Guides
</Link>
<Link
href="#"
className="flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
>
Examples
</Link>
</nav>
</div>
<div className="flex flex-1 items-center space-x-4 sm:justify-end">
<div className="flex-1 sm:grow-0">
<div className="relative hidden md:block">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
type="search"
placeholder="Search documentation..."
className="w-[200px] sm:w-[300px] pl-8"
/>
</div>
</div>
<nav className="flex items-center space-x-1">
<Button variant="ghost" size="icon" onClick={toggleDarkMode}>
{isDarkMode ? (
<Sun className="h-5 w-5" />
) : (
<Moon className="h-5 w-5" />
)}
<span className="sr-only">Toggle theme</span>
</Button>
<Link href="#" target="_blank" rel="noreferrer">
<Button variant="ghost" size="icon">
<Github className="h-5 w-5" />
<span className="sr-only">GitHub</span>
</Button>
</Link>
<Sheet open={isMobileNavOpen} onOpenChange={setIsMobileNavOpen}>
<SheetTrigger asChild>
<Button variant="ghost" size="icon" className="md:hidden">
<Menu className="h-5 w-5" />
<span className="sr-only">Toggle menu</span>
</Button>
</SheetTrigger>
<SheetContent side="left" className="pr-0">
<MobileNav onNavClose={() => setIsMobileNavOpen(false)} />
</SheetContent>
</Sheet>
</nav>
</div>
</div>
</header>
<div className="container flex-1 items-start md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
{/* Sidebar */}
<aside className="fixed top-14 z-30 -ml-2 hidden h-[calc(100vh-3.5rem)] w-full shrink-0 md:sticky md:block">
<div className="h-full py-6 pl-8 pr-6 lg:py-8">
<DocsSidebar />
</div>
</aside>
{/* Main content */}
<main className="relative py-6 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_300px]">
<div className="mx-auto w-full min-w-0">
<div className="mb-4 flex items-center space-x-1 text-sm text-muted-foreground">
<div className="overflow-hidden text-ellipsis whitespace-nowrap">
Docs
</div>
<ChevronDown className="h-4 w-4" />
<div className="font-medium text-foreground">Getting Started</div>
</div>
<div className="space-y-2">
<h1 className="scroll-m-20 text-4xl font-bold tracking-tight">
Getting Started with Laconic Deploy
</h1>
<p className="text-lg text-muted-foreground">
Learn how to deploy your applications with Laconic Deploy in
minutes.
</p>
</div>
<Separator className="my-4 md:my-6" />
<div className="prose prose-slate dark:prose-invert max-w-none">
<p>
Laconic Deploy is a modern deployment platform that makes it
easy to deploy your applications to the cloud. With Laconic
Deploy, you can deploy your applications with just a few clicks
or commands.
</p>
<h2>Installation</h2>
<p>
To get started with Laconic Deploy, you need to install the
Laconic CLI. You can install it using npm:
</p>
<div className="relative my-6 overflow-hidden rounded-lg border bg-muted p-2">
<div className="flex items-center bg-slate-950 px-4 py-2 text-xs text-slate-50 dark:bg-slate-800">
<Terminal className="mr-2 h-4 w-4" />
<span>Terminal</span>
<Button
variant="ghost"
size="icon"
className="ml-auto h-8 w-8"
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy code</span>
</Button>
</div>
<pre className="p-4 text-sm">
<code>npm install -g laconic-cli</code>
</pre>
</div>
<h2>Authentication</h2>
<p>
After installing the CLI, you need to authenticate with Laconic
Deploy:
</p>
<div className="relative my-6 overflow-hidden rounded-lg border bg-muted p-2">
<div className="flex items-center bg-slate-950 px-4 py-2 text-xs text-slate-50 dark:bg-slate-800">
<Terminal className="mr-2 h-4 w-4" />
<span>Terminal</span>
<Button
variant="ghost"
size="icon"
className="ml-auto h-8 w-8"
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy code</span>
</Button>
</div>
<pre className="p-4 text-sm">
<code>laconic login</code>
</pre>
</div>
<h2>Creating Your First Project</h2>
<p>
To create a new project, use the <code>laconic init</code>{' '}
command:
</p>
<div className="relative my-6 overflow-hidden rounded-lg border bg-muted p-2">
<div className="flex items-center bg-slate-950 px-4 py-2 text-xs text-slate-50 dark:bg-slate-800">
<Terminal className="mr-2 h-4 w-4" />
<span>Terminal</span>
<Button
variant="ghost"
size="icon"
className="ml-auto h-8 w-8"
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy code</span>
</Button>
</div>
<pre className="p-4 text-sm">
<code>laconic init my-awesome-project</code>
</pre>
</div>
<h2>Deploying Your Application</h2>
<p>
Once your project is set up, you can deploy it with a single
command:
</p>
<div className="relative my-6 overflow-hidden rounded-lg border bg-muted p-2">
<div className="flex items-center bg-slate-950 px-4 py-2 text-xs text-slate-50 dark:bg-slate-800">
<Terminal className="mr-2 h-4 w-4" />
<span>Terminal</span>
<Button
variant="ghost"
size="icon"
className="ml-auto h-8 w-8"
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy code</span>
</Button>
</div>
<pre className="p-4 text-sm">
<code>laconic deploy</code>
</pre>
</div>
<h2>Configuration</h2>
<p>
Laconic Deploy uses a <code>laconic.config.js</code> file to
configure your deployments. Here's an example configuration:
</p>
<div className="relative my-6 overflow-hidden rounded-lg border bg-muted p-2">
<div className="flex items-center bg-slate-950 px-4 py-2 text-xs text-slate-50 dark:bg-slate-800">
<Code className="mr-2 h-4 w-4" />
<span>laconic.config.js</span>
<Button
variant="ghost"
size="icon"
className="ml-auto h-8 w-8"
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy code</span>
</Button>
</div>
<pre className="p-4 text-sm">
<code>{`module.exports = {
name: 'my-awesome-project',
region: 'us-west-1',
environment: {
NODE_ENV: 'production',
API_URL: 'https://api.example.com'
},
resources: {
compute: {
type: 'container',
size: 'small',
port: 3000
},
database: {
type: 'postgres',
version: '14'
}
}
}`}</code>
</pre>
</div>
<h2>Next Steps</h2>
<p>
Now that you've deployed your first application, you might want
to explore:
</p>
<ul>
<li>Setting up custom domains</li>
<li>Configuring environment variables</li>
<li>Setting up CI/CD pipelines</li>
<li>Monitoring and logging</li>
<li>Scaling your application</li>
</ul>
<div className="not-prose">
<Tabs defaultValue="cli" className="w-full my-6">
<TabsList className="w-full grid grid-cols-3">
<TabsTrigger value="cli">CLI</TabsTrigger>
<TabsTrigger value="api">API</TabsTrigger>
<TabsTrigger value="dashboard">Dashboard</TabsTrigger>
</TabsList>
<TabsContent value="cli" className="p-4 border rounded-b-lg">
<p className="text-sm">
The Laconic CLI provides a powerful command-line interface
for managing your deployments. See the{' '}
<Link href="#" className="text-primary hover:underline">
CLI Reference
</Link>{' '}
for more information.
</p>
</TabsContent>
<TabsContent value="api" className="p-4 border rounded-b-lg">
<p className="text-sm">
The Laconic API allows you to programmatically manage your
deployments. See the{' '}
<Link href="#" className="text-primary hover:underline">
API Reference
</Link>{' '}
for more information.
</p>
</TabsContent>
<TabsContent
value="dashboard"
className="p-4 border rounded-b-lg"
>
<p className="text-sm">
The Laconic Dashboard provides a web interface for
managing your deployments. Visit the{' '}
<Link href="#" className="text-primary hover:underline">
Dashboard
</Link>{' '}
to get started.
</p>
</TabsContent>
</Tabs>
</div>
</div>
<div className="flex justify-between mt-8 border-t pt-4">
<Button variant="outline" size="sm">
<ChevronDown className="mr-2 h-4 w-4 rotate-90" />
Introduction
</Button>
<Button variant="outline" size="sm">
Custom Domains
<ChevronDown className="ml-2 h-4 w-4 -rotate-90" />
</Button>
</div>
</div>
{/* Table of contents - desktop only */}
<div className="hidden text-sm xl:block">
<div className="sticky top-16 -mt-10 pt-10">
<div className="pb-8">
<div className="sticky top-16 -mt-10 pt-10">
<h4 className="mb-1 font-medium">On This Page</h4>
<ul className="m-0 list-none">
<li className="mt-2 pt-2">
<a
href="#installation"
className="text-muted-foreground hover:text-foreground"
>
Installation
</a>
</li>
<li className="mt-2 pt-2">
<a
href="#authentication"
className="text-muted-foreground hover:text-foreground"
>
Authentication
</a>
</li>
<li className="mt-2 pt-2">
<a
href="#creating-your-first-project"
className="text-muted-foreground hover:text-foreground"
>
Creating Your First Project
</a>
</li>
<li className="mt-2 pt-2">
<a
href="#deploying-your-application"
className="text-muted-foreground hover:text-foreground"
>
Deploying Your Application
</a>
</li>
<li className="mt-2 pt-2">
<a
href="#configuration"
className="text-muted-foreground hover:text-foreground"
>
Configuration
</a>
</li>
<li className="mt-2 pt-2">
<a
href="#next-steps"
className="text-muted-foreground hover:text-foreground"
>
Next Steps
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</main>
</div>
<footer className="border-t py-6 md:py-0">
<div className="container flex flex-col items-center justify-between gap-4 md:h-24 md:flex-row">
<p className="text-center text-sm leading-loose text-muted-foreground md:text-left">
© {new Date().getFullYear()} Laconic Deploy. All rights reserved.
</p>
<div className="flex items-center gap-4">
<Link
href="#"
className="text-sm text-muted-foreground hover:text-foreground"
>
Terms
</Link>
<Link
href="#"
className="text-sm text-muted-foreground hover:text-foreground"
>
Privacy
</Link>
<Link
href="#"
className="text-sm text-muted-foreground hover:text-foreground"
>
Contact
</Link>
</div>
</div>
</footer>
</div>
)
}
function MobileNav({ onNavClose }: { onNavClose: () => void }) {
return (
<div className="flex flex-col h-full">
<div className="flex items-center h-16 px-4 border-b">
<Link href="/" className="flex items-center gap-2" onClick={onNavClose}>
<Globe className="h-6 w-6" />
<span className="font-bold">Laconic Deploy</span>
</Link>
<Button
variant="ghost"
size="icon"
className="ml-auto"
onClick={onNavClose}
>
<X className="h-5 w-5" />
<span className="sr-only">Close</span>
</Button>
</div>
<div className="flex-1 overflow-auto py-4">
<div className="px-4 mb-4">
<Input
type="search"
placeholder="Search documentation..."
className="w-full"
/>
</div>
<DocsSidebar mobile onNavClose={onNavClose} />
</div>
</div>
)
}
function DocsSidebar({
mobile = false,
onNavClose
}: { mobile?: boolean; onNavClose?: () => void }) {
const handleLinkClick = () => {
if (mobile && onNavClose) {
onNavClose()
}
}
return (
<div className="w-full">
<div className="pb-4">
<h4 className="mb-1 rounded-md px-2 py-1 text-sm font-medium">
Getting Started
</h4>
<div className="grid grid-flow-row auto-rows-max text-sm">
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Introduction
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-foreground font-medium"
onClick={handleLinkClick}
>
Getting Started
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Installation
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
CLI Setup
</Link>
</div>
</div>
<div className="pb-4">
<h4 className="mb-1 rounded-md px-2 py-1 text-sm font-medium">
Core Concepts
</h4>
<div className="grid grid-flow-row auto-rows-max text-sm">
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Projects
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Environments
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Deployments
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Resources
</Link>
</div>
</div>
<div className="pb-4">
<h4 className="mb-1 rounded-md px-2 py-1 text-sm font-medium">
Guides
</h4>
<div className="grid grid-flow-row auto-rows-max text-sm">
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Custom Domains
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Environment Variables
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
CI/CD Integration
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Monitoring & Logging
</Link>
</div>
</div>
<div className="pb-4">
<h4 className="mb-1 rounded-md px-2 py-1 text-sm font-medium">
API Reference
</h4>
<div className="grid grid-flow-row auto-rows-max text-sm">
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Authentication
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Projects API
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Deployments API
</Link>
<Link
href="#"
className="group flex w-full items-center rounded-md border border-transparent px-2 py-1 hover:underline text-muted-foreground hover:text-foreground"
onClick={handleLinkClick}
>
Resources API
</Link>
</div>
</div>
</div>
)
}
@@ -0,0 +1,12 @@
// Documentation page for the Deploy platform using Pagewrapper component
import PageWrapper from '@/components/foundation/page-wrapper/PageWrapper'
import DocumentationPlaceholder from './DocumentationPlaceholder'
export default function DocumentationPage() {
return (
<PageWrapper header={{ title: 'Documentation' }}>
<DocumentationPlaceholder />
</PageWrapper>
)
}
@@ -0,0 +1,255 @@
'use client'
import type React from 'react'
import {
Bell,
ChevronRight,
CreditCard,
Globe,
HelpCircle,
Lock,
Shield,
User
} from 'lucide-react'
import Link from 'next/link'
import { useState } from 'react'
import { ComingSoonOverlay } from '@/components/foundation'
import { Button } from '@workspace/ui/components/button'
import { Separator } from '@workspace/ui/components/separator'
import { useRouter } from 'next/navigation'
/**
* Settings category item component
* Renders a single settings category with an icon and label
*/
interface SettingsCategoryProps {
/** The icon to display for this category */
icon: React.ReactNode
/** The label text for this category */
label: string
/** Whether this category is currently active */
isActive?: boolean
}
function SettingsCategory({
icon,
label,
isActive = false
}: SettingsCategoryProps) {
return (
<Link
href="#"
className={`flex items-center gap-3 px-4 py-2 rounded-md transition-colors ${
isActive ? 'bg-muted font-medium' : 'hover:bg-muted/50'
}`}
>
{icon}
<span>{label}</span>
{isActive && <ChevronRight className="ml-auto h-4 w-4" />}
</Link>
)
}
/**
* Settings page component
* Displays a simple settings interface with categories and placeholder content
*/
export default function SettingsPage() {
const router = useRouter()
const [activeCategory] = useState('profile')
const [formState, setFormState] = useState({
darkTheme: false,
autoDetectTimezone: true,
allowAnalytics: true
})
/**
* Handle checkbox changes
*/
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { id, checked } = e.target
setFormState((prev) => ({
...prev,
[id]: checked
}))
}
return (
<div className="min-h-screen bg-background">
<ComingSoonOverlay
message="Settings configuration will be available in the next release."
routerAction={() => router.back()}
/>
{/* Header */}
<header className="border-b">
<div className="container py-4">
<div className="flex items-center">
<Link href="/" className="flex items-center gap-2">
<Globe className="h-6 w-6" />
<span className="font-bold">Laconic Deploy</span>
</Link>
<h1 className="text-xl font-semibold ml-8">Settings</h1>
</div>
</div>
</header>
<div className="container py-8">
<div className="grid grid-cols-1 md:grid-cols-[250px_1fr] gap-8">
{/* Sidebar */}
<nav className="space-y-1">
<SettingsCategory
icon={<User className="h-5 w-5" />}
label="Profile"
isActive={activeCategory === 'profile'}
/>
<SettingsCategory
icon={<Bell className="h-5 w-5" />}
label="Notifications"
/>
<SettingsCategory
icon={<Lock className="h-5 w-5" />}
label="Password & Security"
/>
<SettingsCategory
icon={<Shield className="h-5 w-5" />}
label="Access Control"
/>
<SettingsCategory
icon={<CreditCard className="h-5 w-5" />}
label="Billing"
/>
<SettingsCategory
icon={<HelpCircle className="h-5 w-5" />}
label="Help & Support"
/>
</nav>
{/* Main content */}
<div className="space-y-6">
<div>
<h2 className="text-2xl font-bold tracking-tight">
Profile Settings
</h2>
<p className="text-muted-foreground">
Manage your account information and preferences.
</p>
</div>
<Separator />
<div className="space-y-4">
<div className="grid gap-2">
<h3 className="text-lg font-medium">Personal Information</h3>
<p className="text-sm text-muted-foreground">
Update your personal details and how we contact you.
</p>
</div>
<div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2">
<label htmlFor="name" className="text-sm font-medium">
Full Name
</label>
<input
id="name"
type="text"
placeholder="John Doe"
className="w-full px-3 py-2 border rounded-md"
/>
</div>
<div className="space-y-2">
<label htmlFor="email" className="text-sm font-medium">
Email Address
</label>
<input
id="email"
type="email"
placeholder="john@example.com"
className="w-full px-3 py-2 border rounded-md"
/>
</div>
</div>
<div className="flex justify-end">
<Button>Save Changes</Button>
</div>
</div>
<Separator />
<div className="space-y-4">
<div className="grid gap-2">
<h3 className="text-lg font-medium">Preferences</h3>
<p className="text-sm text-muted-foreground">
Customize your experience with Laconic Deploy.
</p>
</div>
<div className="space-y-4">
<div className="flex items-center space-x-2">
<input
id="darkTheme"
type="checkbox"
className="rounded"
checked={formState.darkTheme}
onChange={handleCheckboxChange}
/>
<label htmlFor="darkTheme" className="text-sm font-medium">
Use dark theme
</label>
</div>
<div className="flex items-center space-x-2">
<input
id="autoDetectTimezone"
type="checkbox"
className="rounded"
checked={formState.autoDetectTimezone}
onChange={handleCheckboxChange}
/>
<label
htmlFor="autoDetectTimezone"
className="text-sm font-medium"
>
Automatically detect timezone
</label>
</div>
<div className="flex items-center space-x-2">
<input
id="allowAnalytics"
type="checkbox"
className="rounded"
checked={formState.allowAnalytics}
onChange={handleCheckboxChange}
/>
<label
htmlFor="allowAnalytics"
className="text-sm font-medium"
>
Allow anonymous usage data collection
</label>
</div>
</div>
<div className="flex justify-end">
<Button>Save Preferences</Button>
</div>
</div>
</div>
</div>
</div>
<footer className="border-t mt-auto">
<div className="container py-6">
<p className="text-center text-sm text-muted-foreground">
© {new Date().getFullYear()} Laconic Deploy. All rights reserved.
</p>
</div>
</footer>
</div>
)
}
@@ -0,0 +1,10 @@
import { PageWrapper } from '@/components/foundation'
import SupportPlaceholder from './SupportPlaceholder'
export default function SupportPage() {
return (
<PageWrapper header={{ title: 'Support' }}>
<SupportPlaceholder />
</PageWrapper>
)
}
@@ -0,0 +1,32 @@
import { Button } from '@workspace/ui/components/button'
import { Globe } from 'lucide-react'
/**
* Coming Soon overlay component
* Displays a message indicating a feature is not yet available
*
* @param props.message - Optional custom message to display
* @param props.routerAction - Optional router action to perform when the button is clicked
*/
interface ComingSoonOverlayProps {
message?: string
routerAction?: () => void
buttonText?: string
}
export function ComingSoonOverlay({
message = 'This feature will be available in the next release.',
routerAction,
buttonText = 'Get Notified'
}: ComingSoonOverlayProps) {
return (
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background/35 backdrop-blur-sm">
<div className="text-center space-y-4 max-w-md px-4 bg-background/80 p-8 rounded-lg shadow-lg">
<Globe className="h-16 w-16 mx-auto text-primary" />
<h1 className="text-4xl font-bold tracking-tight">Coming Soon</h1>
<p className="text-lg text-muted-foreground">{message}</p>
{routerAction && <Button onClick={routerAction}>{buttonText}</Button>}
</div>
</div>
)
}
@@ -0,0 +1 @@
export * from './ComingSoonOverlay'
@@ -10,6 +10,7 @@ export * from './page-wrapper'
export * from './navigation-wrapper'
// Top Navigation
export * from './coming-soon-overlay'
export * from './top-navigation/dark-mode-toggle'
export * from './top-navigation/main-navigation'
export * from './top-navigation/navigation-item'
@@ -10,7 +10,7 @@ import {
SheetTitle,
SheetTrigger
} from '@workspace/ui/components/sheet'
import { Menu } from 'lucide-react'
import { CreditCard, Menu, Shapes, WalletIcon } from 'lucide-react'
import Link from 'next/link'
import type React from 'react'
import { DarkModeToggle } from '../dark-mode-toggle'
@@ -201,8 +201,9 @@ export interface TopNavigationProps {
export default function TopNavigation({
config = {
leftItems: [
{ label: 'Projects', href: '/projects' },
{ label: 'Wallet', href: '/wallets' }
{ icon: Shapes, label: 'Projects', href: '/projects' },
{ icon: WalletIcon, label: 'Wallet', href: '/wallet' },
{ icon: CreditCard, label: 'Purchase', href: '/purchase' }
],
rightItems: [
{ label: 'Support', href: '/support' },
@@ -292,7 +292,7 @@ export function NavigationItem({
// For regular navigation items, use the Button component
const content = (
<>
{Icon && <Icon className="mr-2 h-4 w-4" />}
{Icon && <Icon className="h-4 w-4" />}
{children}
</>
)
+4 -14
View File
@@ -3,12 +3,8 @@
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
],
"@workspace/ui/*": [
"../../services/ui/src/*"
]
"@/*": ["./src/*"],
"@workspace/ui/*": ["../../services/ui/src/*"]
},
"plugins": [
{
@@ -20,15 +16,9 @@
"next-env.d.ts",
"next.config.mjs",
"src/**/*.ts",
"src/**/*.tsx"
"src/**/*.tsx",
// ".next/types/**/*.ts"
,
".next/types/**/*.ts"
],
"exclude": [
"node_modules",
".next/*",
".turbo/*",
".vscode/*"
]
"exclude": ["node_modules", ".next/*", ".turbo/*", ".vscode/*"]
}