diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 224b4fe..e98e793 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@hookform/resolvers": "^3.9.1",
+ "@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-checkbox": "^1.1.2",
@@ -1199,6 +1200,36 @@
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
"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": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.6.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index b1a0db5..ca824eb 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,6 +11,7 @@
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",
+ "@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-checkbox": "^1.1.2",
diff --git a/frontend/src/components/layout/data/sidebar-data.ts b/frontend/src/components/layout/data/sidebar-data.ts
index 6b6a4b8..2e7192b 100644
--- a/frontend/src/components/layout/data/sidebar-data.ts
+++ b/frontend/src/components/layout/data/sidebar-data.ts
@@ -30,7 +30,7 @@ export const sidebarData: SidebarData = {
},
teams: [
{
- name: "Shadcn Admin",
+ name: "SwagShop Admin",
logo: Command,
plan: "Vite + ShadcnUI"
},
diff --git a/frontend/src/components/main-navbar.tsx b/frontend/src/components/main-navbar.tsx
new file mode 100644
index 0000000..d0a8e23
--- /dev/null
+++ b/frontend/src/components/main-navbar.tsx
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+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;
diff --git a/frontend/src/components/ui/accordion.tsx b/frontend/src/components/ui/accordion.tsx
new file mode 100644
index 0000000..e6a723d
--- /dev/null
+++ b/frontend/src/components/ui/accordion.tsx
@@ -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,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+AccordionItem.displayName = "AccordionItem"
+
+const AccordionTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ svg]:rotate-180",
+ className
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+))
+AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
+
+const AccordionContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+))
+
+AccordionContent.displayName = AccordionPrimitive.Content.displayName
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/frontend/src/config/manifest.ts b/frontend/src/config/manifest.ts
new file mode 100644
index 0000000..973f3f2
--- /dev/null
+++ b/frontend/src/config/manifest.ts
@@ -0,0 +1,2 @@
+export const AppName = "SwagShop"
+export const AdminAppName = "SwagShop Admin"
\ No newline at end of file
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 75c007c..5a61c1f 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -141,3 +141,14 @@
@apply min-h-svh w-full bg-background text-foreground;
}
}
+
+
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/frontend/src/pages/auth/auth-layout.tsx b/frontend/src/pages/auth/auth-layout.tsx
index b27b565..09d17f1 100644
--- a/frontend/src/pages/auth/auth-layout.tsx
+++ b/frontend/src/pages/auth/auth-layout.tsx
@@ -1,3 +1,5 @@
+import {AdminAppName} from "@/config/manifest"
+
interface Props {
children: React.ReactNode;
}
@@ -18,7 +20,7 @@ export default function AuthLayout({ children }: Props) {
className="mr-2 h-6 w-6">
- Shadcn Admin
+ {AdminAppName}
{children}
diff --git a/frontend/src/pages/auth/sign-in/sign-in-2.tsx b/frontend/src/pages/auth/sign-in/sign-in-2.tsx
index c40cc93..0ab9dfa 100644
--- a/frontend/src/pages/auth/sign-in/sign-in-2.tsx
+++ b/frontend/src/pages/auth/sign-in/sign-in-2.tsx
@@ -1,5 +1,6 @@
import ViteLogo from "@/assets/vite.svg";
import { UserAuthForm } from "./components/user-auth-form";
+import { AdminAppName } from "@/config/manifest";
export default function SignIn2() {
return (
@@ -18,7 +19,7 @@ export default function SignIn2() {
className="mr-2 h-6 w-6">
- Shadcn Admin
+ {AdminAppName}
+ Ready to Get Started?
+ Join today and start managing your shop with ease.
+
+
+ );
+ };
\ No newline at end of file
diff --git a/frontend/src/pages/home/components/faq.tsx b/frontend/src/pages/home/components/faq.tsx
new file mode 100644
index 0000000..7806af3
--- /dev/null
+++ b/frontend/src/pages/home/components/faq.tsx
@@ -0,0 +1,25 @@
+import {
+ Accordion,
+ AccordionContent,
+ AccordionItem,
+ AccordionTrigger
+} from "@/components/ui/accordion";
+import { faqs } from "../data/faq-data";
+
+export default function FAQ() {
+ return (
+
+
+ Frequently Asked Questions
+
+
+ {faqs.map((faq, index) => (
+
+ {faq.question}
+ {faq.answer}
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/pages/home/components/features.tsx b/frontend/src/pages/home/components/features.tsx
new file mode 100644
index 0000000..43717aa
--- /dev/null
+++ b/frontend/src/pages/home/components/features.tsx
@@ -0,0 +1,19 @@
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
+import { features } from "../data/feature-data";
+
+export default function Features() {
+ return (
+
+ {features.map((feature, index) => (
+
+
+ {feature.title}
+
+
+ {feature.description}
+
+
+ ))}
+
+ );
+}
diff --git a/frontend/src/pages/home/components/hero.tsx b/frontend/src/pages/home/components/hero.tsx
new file mode 100644
index 0000000..d23ce32
--- /dev/null
+++ b/frontend/src/pages/home/components/hero.tsx
@@ -0,0 +1,11 @@
+export default function Hero() {
+ return (
+
+ Manage Your Shop with Ease
+
+ A powerful multitenant API for inventory and product management. Define
+ your products, manage stock, and handle purchases effortlessly.
+
+
+ );
+}
diff --git a/frontend/src/pages/home/components/pricing.tsx b/frontend/src/pages/home/components/pricing.tsx
new file mode 100644
index 0000000..dd4c497
--- /dev/null
+++ b/frontend/src/pages/home/components/pricing.tsx
@@ -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 (
+
+
Pricing Plans
+
+ Prices are subject to change. These estimates help guide your decision.
+
+
+ {plans.map((plan, index) => (
+
+
+ {plan.title}
+
+
+ {plan.price}
+ {plan.description}
+
+ {plan.features.map((feature, i) => (
+ -
+ {feature}
+
+ ))}
+
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/pages/home/data/faq-data.ts b/frontend/src/pages/home/data/faq-data.ts
new file mode 100644
index 0000000..786d310
--- /dev/null
+++ b/frontend/src/pages/home/data/faq-data.ts
@@ -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."
+ }
+];
diff --git a/frontend/src/pages/home/data/feature-data.ts b/frontend/src/pages/home/data/feature-data.ts
new file mode 100644
index 0000000..4c06595
--- /dev/null
+++ b/frontend/src/pages/home/data/feature-data.ts
@@ -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."
+ }
+];
\ No newline at end of file
diff --git a/frontend/src/pages/home/data/pricing-data.ts b/frontend/src/pages/home/data/pricing-data.ts
new file mode 100644
index 0000000..9e8b85e
--- /dev/null
+++ b/frontend/src/pages/home/data/pricing-data.ts
@@ -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"]
+ }
+ ];
\ No newline at end of file
diff --git a/frontend/src/pages/home/index.tsx b/frontend/src/pages/home/index.tsx
index a487dd0..3fc42af 100644
--- a/frontend/src/pages/home/index.tsx
+++ b/frontend/src/pages/home/index.tsx
@@ -1,100 +1,26 @@
-import { useState } from "react";
-import { Button } from "@/components/ui/button";
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-import { Input } from "@/components/ui/input";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
-import { Label } from "@/components/ui/label";
+import MainNavbar from "@/components/main-navbar";
+import Features from "./components/features";
+import Hero from "./components/hero";
+import Pricing from "./components/pricing";
+import FAQ from "./components/faq";
+import CallToAction from "./components/call-to-action";
export default function MainPage() {
- const [email, setEmail] = useState("");
- const [password, setPassword] = useState("");
- const [username, setUsername] = useState("");
-
return (
-
- {/* Showcase Section */}
-
- Welcome to Our Platform
-
- A place where you can explore, connect, and engage. Sign up or log in
- to get started.
-
-
-
+ <>
+
+
- {/* Authentication Section */}
-
-
- Join Us
-
-
-
-
- Login
- Register
-
+ {/* Top screen padding */}
+
+
+
+
+
+
- {/* Login Tab */}
-
-
-
-
- {/* Register Tab */}
-
-
-
-
-
-
-
+ {/* [Optional] Consider inserting an image or illustration here to reinforce the platform’s purpose. */}
+
+ >
);
}
diff --git a/frontend/src/routes/_authenticated/route.tsx b/frontend/src/routes/_authenticated/route.tsx
index 87ee918..4baf216 100644
--- a/frontend/src/routes/_authenticated/route.tsx
+++ b/frontend/src/routes/_authenticated/route.tsx
@@ -8,9 +8,9 @@ import SkipToMain from "@/components/skip-to-main";
export const Route = createFileRoute("/_authenticated")({
beforeLoad: async ({ location }) => {
- if (true) {
+ if (false) {
throw redirect({
- to: "/sign-in",
+ to: "/401",
search: {
redirect: location.href
}
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 730acd0..d162b1a 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -50,6 +50,28 @@ export default {
'4': 'hsl(var(--chart-4))',
'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'
}
}
},