[rewrite] Updated main page
This commit is contained in:
parent
a9c85cefe1
commit
c3502f9ede
31
frontend/package-lock.json
generated
31
frontend/package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.9.1",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
|
"@radix-ui/react-accordion": "^1.2.3",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.2",
|
"@radix-ui/react-alert-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-avatar": "^1.1.1",
|
"@radix-ui/react-avatar": "^1.1.1",
|
||||||
"@radix-ui/react-checkbox": "^1.1.2",
|
"@radix-ui/react-checkbox": "^1.1.2",
|
||||||
@ -1199,6 +1200,36 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
|
||||||
"integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="
|
"integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-accordion": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.1",
|
||||||
|
"@radix-ui/react-collapsible": "1.1.3",
|
||||||
|
"@radix-ui/react-collection": "1.1.2",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.1",
|
||||||
|
"@radix-ui/react-context": "1.1.1",
|
||||||
|
"@radix-ui/react-direction": "1.1.0",
|
||||||
|
"@radix-ui/react-id": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.2",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-alert-dialog": {
|
"node_modules/@radix-ui/react-alert-dialog": {
|
||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.6.tgz",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.9.1",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
|
"@radix-ui/react-accordion": "^1.2.3",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.2",
|
"@radix-ui/react-alert-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-avatar": "^1.1.1",
|
"@radix-ui/react-avatar": "^1.1.1",
|
||||||
"@radix-ui/react-checkbox": "^1.1.2",
|
"@radix-ui/react-checkbox": "^1.1.2",
|
||||||
|
@ -30,7 +30,7 @@ export const sidebarData: SidebarData = {
|
|||||||
},
|
},
|
||||||
teams: [
|
teams: [
|
||||||
{
|
{
|
||||||
name: "Shadcn Admin",
|
name: "SwagShop Admin",
|
||||||
logo: Command,
|
logo: Command,
|
||||||
plan: "Vite + ShadcnUI"
|
plan: "Vite + ShadcnUI"
|
||||||
},
|
},
|
||||||
|
125
frontend/src/components/main-navbar.tsx
Normal file
125
frontend/src/components/main-navbar.tsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import { Menu } from "lucide-react";
|
||||||
|
import { Card } from "@/components/ui/card";
|
||||||
|
import { ThemeSwitch } from "./theme-switch";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
const MainNavbar = () => {
|
||||||
|
return (
|
||||||
|
<div className="fixed left-0 top-0 z-50 box-border w-full border-b px-4 py-3 backdrop-blur-lg transition-all duration-300">
|
||||||
|
<Card className="flex items-center justify-between gap-6 border-0 bg-transparent shadow-none">
|
||||||
|
<ul className="hidden items-center gap-10 text-card-foreground md:flex">
|
||||||
|
<li className="font-medium text-primary">
|
||||||
|
<a href="#home">Home</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#pricing">Pricing</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#faqs">FAQs</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Button variant="secondary" className="hidden px-2 md:block">
|
||||||
|
<Link to="/sign-in">Login</Link>
|
||||||
|
</Button>
|
||||||
|
<Button className="ml-2 mr-2 hidden md:block"><Link to="/sign-up">Get Started</Link></Button>
|
||||||
|
|
||||||
|
<div className="mr-2 flex items-center gap-2 md:hidden">
|
||||||
|
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button variant="outline" size="icon">
|
||||||
|
<Menu className="h-5 w-5 rotate-0 scale-100" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<a href="#home">Home</a>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<a href="#features">Features</a>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<a href="#pricing">Pricing</a>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<a href="#faqs">FAQs</a>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Button variant="secondary" className="w-full text-sm">
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<Button className="w-full text-sm">Get Started</Button>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ThemeSwitch />
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const landings = [
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 01",
|
||||||
|
route: "/project-management"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 02",
|
||||||
|
route: "/crm-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 03",
|
||||||
|
route: "/ai-content-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 04",
|
||||||
|
route: "/new-intro-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 05",
|
||||||
|
route: "/about-us-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 06",
|
||||||
|
route: "/contact-us-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 07",
|
||||||
|
route: "/faqs-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 08",
|
||||||
|
route: "/pricing-landing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: nanoid(),
|
||||||
|
title: "Landing 09",
|
||||||
|
route: "/career-landing"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default MainNavbar;
|
56
frontend/src/components/ui/accordion.tsx
Normal file
56
frontend/src/components/ui/accordion.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
||||||
|
import { ChevronDown } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Accordion = AccordionPrimitive.Root
|
||||||
|
|
||||||
|
const AccordionItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn("border-b", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
AccordionItem.displayName = "AccordionItem"
|
||||||
|
|
||||||
|
const AccordionTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Header className="flex">
|
||||||
|
<AccordionPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
|
||||||
|
</AccordionPrimitive.Trigger>
|
||||||
|
</AccordionPrimitive.Header>
|
||||||
|
))
|
||||||
|
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const AccordionContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className={cn("pb-4 pt-0", className)}>{children}</div>
|
||||||
|
</AccordionPrimitive.Content>
|
||||||
|
))
|
||||||
|
|
||||||
|
AccordionContent.displayName = AccordionPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|
2
frontend/src/config/manifest.ts
Normal file
2
frontend/src/config/manifest.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const AppName = "SwagShop"
|
||||||
|
export const AdminAppName = "SwagShop Admin"
|
@ -141,3 +141,14 @@
|
|||||||
@apply min-h-svh w-full bg-background text-foreground;
|
@apply min-h-svh w-full bg-background text-foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border outline-ring/50;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import {AdminAppName} from "@/config/manifest"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
@ -18,7 +20,7 @@ export default function AuthLayout({ children }: Props) {
|
|||||||
className="mr-2 h-6 w-6">
|
className="mr-2 h-6 w-6">
|
||||||
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
||||||
</svg>
|
</svg>
|
||||||
<h1 className="text-xl font-medium">Shadcn Admin</h1>
|
<h1 className="text-xl font-medium">{AdminAppName}</h1>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import ViteLogo from "@/assets/vite.svg";
|
import ViteLogo from "@/assets/vite.svg";
|
||||||
import { UserAuthForm } from "./components/user-auth-form";
|
import { UserAuthForm } from "./components/user-auth-form";
|
||||||
|
import { AdminAppName } from "@/config/manifest";
|
||||||
|
|
||||||
export default function SignIn2() {
|
export default function SignIn2() {
|
||||||
return (
|
return (
|
||||||
@ -18,7 +19,7 @@ export default function SignIn2() {
|
|||||||
className="mr-2 h-6 w-6">
|
className="mr-2 h-6 w-6">
|
||||||
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
||||||
</svg>
|
</svg>
|
||||||
Shadcn Admin
|
{AdminAppName}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
|
11
frontend/src/pages/home/components/call-to-action.tsx
Normal file
11
frontend/src/pages/home/components/call-to-action.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
export default function CallToAction() {
|
||||||
|
return (
|
||||||
|
<div className="text-center py-12">
|
||||||
|
<h2 className="text-3xl font-bold mb-4">Ready to Get Started?</h2>
|
||||||
|
<p className="mb-6 text-gray-600">Join today and start managing your shop with ease.</p>
|
||||||
|
<Button className="px-6 py-2">Sign Up Now</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
25
frontend/src/pages/home/components/faq.tsx
Normal file
25
frontend/src/pages/home/components/faq.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionContent,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionTrigger
|
||||||
|
} from "@/components/ui/accordion";
|
||||||
|
import { faqs } from "../data/faq-data";
|
||||||
|
|
||||||
|
export default function FAQ() {
|
||||||
|
return (
|
||||||
|
<div className="mt-12 max-w-4xl">
|
||||||
|
<h2 id="faqs" className="mb-6 text-center text-3xl font-bold">
|
||||||
|
Frequently Asked Questions
|
||||||
|
</h2>
|
||||||
|
<Accordion type="single" collapsible>
|
||||||
|
{faqs.map((faq, index) => (
|
||||||
|
<AccordionItem key={index} value={`faq-${index}`}>
|
||||||
|
<AccordionTrigger>{faq.question}</AccordionTrigger>
|
||||||
|
<AccordionContent>{faq.answer}</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
19
frontend/src/pages/home/components/features.tsx
Normal file
19
frontend/src/pages/home/components/features.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
|
||||||
|
import { features } from "../data/feature-data";
|
||||||
|
|
||||||
|
export default function Features() {
|
||||||
|
return (
|
||||||
|
<div className="grid max-w-5xl gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<Card key={index}>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>{feature.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p>{feature.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
11
frontend/src/pages/home/components/hero.tsx
Normal file
11
frontend/src/pages/home/components/hero.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function Hero() {
|
||||||
|
return (
|
||||||
|
<section className="flex w-full max-w-4xl flex-grow flex-col items-center justify-center text-center">
|
||||||
|
<h1 className="mb-4 text-4xl font-bold">Manage Your Shop with Ease</h1>
|
||||||
|
<p className="mb-6 text-gray-600">
|
||||||
|
A powerful multitenant API for inventory and product management. Define
|
||||||
|
your products, manage stock, and handle purchases effortlessly.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
35
frontend/src/pages/home/components/pricing.tsx
Normal file
35
frontend/src/pages/home/components/pricing.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import { plans } from "../data/pricing-data";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
export default function Pricing() {
|
||||||
|
return (
|
||||||
|
<div className="max-w-4xl text-center">
|
||||||
|
<h2 id="pricing" className="mb-6 text-3xl font-bold">Pricing Plans</h2>
|
||||||
|
<p className="mb-6 text-gray-600">
|
||||||
|
Prices are subject to change. These estimates help guide your decision.
|
||||||
|
</p>
|
||||||
|
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{plans.map((plan, index) => (
|
||||||
|
<Card key={index} className="p-4">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>{plan.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p className="mb-4 text-xl font-semibold">{plan.price}</p>
|
||||||
|
<p className="mb-4 text-gray-600">{plan.description}</p>
|
||||||
|
<ul className="mb-4 text-left">
|
||||||
|
{plan.features.map((feature, i) => (
|
||||||
|
<li key={i} className="list-inside list-disc text-sm">
|
||||||
|
{feature}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Button>Choose Plan</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
15
frontend/src/pages/home/data/faq-data.ts
Normal file
15
frontend/src/pages/home/data/faq-data.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export const faqs = [
|
||||||
|
{
|
||||||
|
question: "How do I get started?",
|
||||||
|
answer:
|
||||||
|
"Sign up for a free account and start integrating our API into your shop."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "Can I upgrade or downgrade my plan?",
|
||||||
|
answer: "Yes, you can change your plan anytime from your dashboard."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "Is there customer support?",
|
||||||
|
answer: "Yes, we offer different levels of support depending on your plan."
|
||||||
|
}
|
||||||
|
];
|
31
frontend/src/pages/home/data/feature-data.ts
Normal file
31
frontend/src/pages/home/data/feature-data.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export const features = [
|
||||||
|
{
|
||||||
|
title: "Inventory Control",
|
||||||
|
description:
|
||||||
|
"Easily manage product stock, availability, and updates in real time."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Flexible API",
|
||||||
|
description:
|
||||||
|
"Build custom storefronts with a backend that adapts to your needs."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Seamless Transactions",
|
||||||
|
description: "Handle purchases smoothly with minimal backend complexity."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "User Roles & Permissions",
|
||||||
|
description:
|
||||||
|
"Predefined roles (Owner, Manager, Employee) with different access levels to manage store operations efficiently."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Multi-Currency Support",
|
||||||
|
description:
|
||||||
|
"Each shop can define its default currency to handle transactions in the appropriate financial context."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Future-Ready Analytics",
|
||||||
|
description:
|
||||||
|
"Upcoming analytics and statistics to help businesses track performance and make data-driven decisions."
|
||||||
|
}
|
||||||
|
];
|
20
frontend/src/pages/home/data/pricing-data.ts
Normal file
20
frontend/src/pages/home/data/pricing-data.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export const plans = [
|
||||||
|
{
|
||||||
|
title: "Free Plan",
|
||||||
|
price: "$0/month",
|
||||||
|
description: "Basic features for small shops starting out.",
|
||||||
|
features: ["Basic Inventory Management", "Limited API Requests", "Community Support"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Pro Plan",
|
||||||
|
price: "$29/month",
|
||||||
|
description: "For growing businesses needing more control.",
|
||||||
|
features: ["Advanced Inventory Management", "Higher API Limits", "Email Support"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Enterprise Plan",
|
||||||
|
price: "$99/month",
|
||||||
|
description: "For high-scale businesses requiring full access.",
|
||||||
|
features: ["Unlimited API Access", "Priority Support", "Custom Integrations"]
|
||||||
|
}
|
||||||
|
];
|
@ -1,100 +1,26 @@
|
|||||||
import { useState } from "react";
|
import MainNavbar from "@/components/main-navbar";
|
||||||
import { Button } from "@/components/ui/button";
|
import Features from "./components/features";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import Hero from "./components/hero";
|
||||||
import { Input } from "@/components/ui/input";
|
import Pricing from "./components/pricing";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import FAQ from "./components/faq";
|
||||||
import { Label } from "@/components/ui/label";
|
import CallToAction from "./components/call-to-action";
|
||||||
|
|
||||||
export default function MainPage() {
|
export default function MainPage() {
|
||||||
const [email, setEmail] = useState("");
|
|
||||||
const [password, setPassword] = useState("");
|
|
||||||
const [username, setUsername] = useState("");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-100 p-6">
|
<>
|
||||||
{/* Showcase Section */}
|
<MainNavbar />
|
||||||
<section className="mb-8 w-full max-w-4xl text-center">
|
<div className="flex min-h-screen flex-col items-center justify-center overflow-hidden p-6 gap-24">
|
||||||
<h1 className="mb-4 text-4xl font-bold">Welcome to Our Platform</h1>
|
|
||||||
<p className="mb-6 text-gray-600">
|
|
||||||
A place where you can explore, connect, and engage. Sign up or log in
|
|
||||||
to get started.
|
|
||||||
</p>
|
|
||||||
<Button className="px-6 py-2">Learn More</Button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Authentication Section */}
|
{/* Top screen padding */}
|
||||||
<Card className="w-full max-w-md">
|
<div className="h-[20vh] min-h-[20vh]"></div>
|
||||||
<CardHeader>
|
<Hero />
|
||||||
<CardTitle>Join Us</CardTitle>
|
<Features />
|
||||||
</CardHeader>
|
<Pricing />
|
||||||
<CardContent>
|
<FAQ />
|
||||||
<Tabs defaultValue="login" className="w-full">
|
<CallToAction />
|
||||||
<TabsList className="grid w-full grid-cols-2">
|
|
||||||
<TabsTrigger value="login">Login</TabsTrigger>
|
|
||||||
<TabsTrigger value="register">Register</TabsTrigger>
|
|
||||||
</TabsList>
|
|
||||||
|
|
||||||
{/* Login Tab */}
|
{/* [Optional] Consider inserting an image or illustration here to reinforce the platform’s purpose. */}
|
||||||
<TabsContent value="login">
|
</div>
|
||||||
<form className="space-y-4">
|
</>
|
||||||
<div>
|
|
||||||
<Label>Email</Label>
|
|
||||||
<Input
|
|
||||||
type="email"
|
|
||||||
value={email}
|
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
|
||||||
placeholder="Enter your email"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>Password</Label>
|
|
||||||
<Input
|
|
||||||
type="password"
|
|
||||||
value={password}
|
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
|
||||||
placeholder="Enter your password"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Button className="w-full">Login</Button>
|
|
||||||
</form>
|
|
||||||
</TabsContent>
|
|
||||||
|
|
||||||
{/* Register Tab */}
|
|
||||||
<TabsContent value="register">
|
|
||||||
<form className="space-y-4">
|
|
||||||
<div>
|
|
||||||
<Label>Username</Label>
|
|
||||||
<Input
|
|
||||||
type="text"
|
|
||||||
value={username}
|
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
|
||||||
placeholder="Choose a username"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>Email</Label>
|
|
||||||
<Input
|
|
||||||
type="email"
|
|
||||||
value={email}
|
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
|
||||||
placeholder="Enter your email"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>Password</Label>
|
|
||||||
<Input
|
|
||||||
type="password"
|
|
||||||
value={password}
|
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
|
||||||
placeholder="Create a password"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Button className="w-full">Register</Button>
|
|
||||||
</form>
|
|
||||||
</TabsContent>
|
|
||||||
</Tabs>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ import SkipToMain from "@/components/skip-to-main";
|
|||||||
|
|
||||||
export const Route = createFileRoute("/_authenticated")({
|
export const Route = createFileRoute("/_authenticated")({
|
||||||
beforeLoad: async ({ location }) => {
|
beforeLoad: async ({ location }) => {
|
||||||
if (true) {
|
if (false) {
|
||||||
throw redirect({
|
throw redirect({
|
||||||
to: "/sign-in",
|
to: "/401",
|
||||||
search: {
|
search: {
|
||||||
redirect: location.href
|
redirect: location.href
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,28 @@ export default {
|
|||||||
'4': 'hsl(var(--chart-4))',
|
'4': 'hsl(var(--chart-4))',
|
||||||
'5': 'hsl(var(--chart-5))'
|
'5': 'hsl(var(--chart-5))'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
'accordion-down': {
|
||||||
|
from: {
|
||||||
|
height: '0'
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
height: 'var(--radix-accordion-content-height)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'accordion-up': {
|
||||||
|
from: {
|
||||||
|
height: 'var(--radix-accordion-content-height)'
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
height: '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||||
|
'accordion-up': 'accordion-up 0.2s ease-out'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user