diff --git a/package-lock.json b/package-lock.json
index f8ff0c2..58f5edb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
+ "@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-scroll-area": "^1.0.5",
@@ -2423,6 +2424,42 @@
}
}
},
+ "node_modules/@radix-ui/react-navigation-menu": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz",
+ "integrity": "sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-collection": "1.0.3",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-direction": "1.0.1",
+ "@radix-ui/react-dismissable-layer": "1.0.5",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-presence": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-controllable-state": "1.0.1",
+ "@radix-ui/react-use-layout-effect": "1.0.1",
+ "@radix-ui/react-use-previous": "1.0.1",
+ "@radix-ui/react-visually-hidden": "1.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-popover": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz",
diff --git a/package.json b/package.json
index 42a7b3a..f180cf8 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
+ "@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-scroll-area": "^1.0.5",
diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx
new file mode 100644
index 0000000..65d92eb
--- /dev/null
+++ b/src/app/(app)/layout.tsx
@@ -0,0 +1,22 @@
+import Footer from "@/components/footer";
+import Navbar from "@/components/navbar";
+import { Metadata } from "next";
+import React from "react";
+
+export const metadata: Metadata = {
+ title: "Skilled Ai",
+ description: "Skilled Ai",
+};
+
+const Layout = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+
+
+ {children}
+
+
+ );
+};
+
+export default Layout;
diff --git a/src/app/(app)/pricing/page.tsx b/src/app/(app)/pricing/page.tsx
new file mode 100644
index 0000000..83f462e
--- /dev/null
+++ b/src/app/(app)/pricing/page.tsx
@@ -0,0 +1,72 @@
+"use client";
+
+import React, { useState } from "react";
+import PricingHeader from "@/components/pricing/pricing-header";
+import PricingSwitch from "@/components/pricing/pricing-switch";
+import PricingCard from "@/components/pricing/pricing-card";
+
+export default function Page() {
+ const [isYearly, setIsYearly] = useState(false);
+ const togglePricingPeriod = (value: string) =>
+ setIsYearly(parseInt(value) === 1);
+
+ const plans = [
+ {
+ title: "Basic",
+ monthlyPrice: 10,
+ yearlyPrice: 100,
+ description: "Essential features you need to get started",
+ features: [
+ "Full access to our extensive library of courses and tutorials",
+ "Regularly updated content to keep you ahead of the curve",
+ "Skill assessments and progress tracking",
+ "Community forums for networking and support",
+ "Certificate of completion for each course",
+ ],
+ actionLabel: "Get Started",
+ },
+ {
+ title: "Pro",
+ monthlyPrice: 25,
+ yearlyPrice: 250,
+ description: "Perfect for owners of small & medium businessess",
+ features: [
+ "All features included in the Basic tier",
+ "Exclusive access to advanced courses and workshops",
+ "Personalized career coaching sessions",
+ "Priority customer support",
+ "Premium resources such as e-books and industry reports",
+ ],
+ actionLabel: "Get Started",
+ popular: true,
+ },
+ {
+ title: "Enterprise",
+ price: "Custom",
+ description: "Dedicated support and infrastructure to fit your needs",
+ features: [
+ "Tailored solutions for businesses and teams",
+ "Dedicated account management",
+ "Customizable learning paths and content curation",
+ "Team analytics and progress tracking",
+ "On-site workshops and training sessions (optional)",
+ ],
+ actionLabel: "Contact Sales",
+ exclusive: true,
+ },
+ ];
+ return (
+
+
+
+
+ {plans.map((plan) => {
+ return ;
+ })}
+
+
+ );
+}
diff --git a/src/components/footer.tsx b/src/components/footer.tsx
new file mode 100644
index 0000000..725dd75
--- /dev/null
+++ b/src/components/footer.tsx
@@ -0,0 +1,223 @@
+import { Input } from "@/components/ui/input";
+import { Button } from "@/components/ui/button";
+import Link from "next/link";
+
+export default function Footer() {
+ return (
+
+
+
+
+ Stay Connected
+
+
+ Subscribe to our newsletter and follow us on our social media.
+
+
+
+
+ {/*
+
+
+
+
+
+
+
+
+
+
+
+
+
*/}
+
+
+
+
+
+ );
+}
+
+function FacebookIcon(props: any) {
+ return (
+
+
+
+ );
+}
+
+function InstagramIcon(props: any) {
+ return (
+
+
+
+
+
+ );
+}
+
+function LinkedinIcon(props: any) {
+ return (
+
+
+
+
+
+ );
+}
+
+function TwitterIcon(props: any) {
+ return (
+
+
+
+ );
+}
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
new file mode 100644
index 0000000..e05b37b
--- /dev/null
+++ b/src/components/navbar.tsx
@@ -0,0 +1,177 @@
+"use client";
+
+import * as React from "react";
+import Link from "next/link";
+
+import { cn } from "@/lib/utils";
+import { Icons } from "@/components/icons";
+import {
+ NavigationMenu,
+ NavigationMenuContent,
+ NavigationMenuItem,
+ NavigationMenuLink,
+ NavigationMenuList,
+ NavigationMenuTrigger,
+ navigationMenuTriggerStyle,
+} from "@/components/ui/navigation-menu";
+import ThemeToggle from "./layout/ThemeToggle/theme-toggle";
+import { buttonVariants } from "./ui/button";
+
+const careerPaths: { title: string; href: string; description: string }[] = [
+ {
+ title: "Frontend Developer",
+ href: "#",
+ description:
+ "Master frontend technologies like HTML, CSS, and JavaScript to build dynamic and user-friendly web interfaces.",
+ },
+ {
+ title: "Backend Developer",
+ href: "#",
+ description:
+ "Learn server-side programming languages and frameworks to create scalable and efficient web applications.",
+ },
+ {
+ title: "Full Stack Developer",
+ href: "#",
+ description:
+ "Combine frontend and backend development skills to build end-to-end web applications from scratch.",
+ },
+ {
+ title: "Mobile App Developer",
+ href: "#",
+ description:
+ "Specialize in mobile app development for iOS or Android platforms using Swift, Kotlin, or cross-platform frameworks.",
+ },
+ {
+ title: "Game Developer",
+ href: "#",
+ description:
+ "Dive into game development with Unity or Unreal Engine, creating immersive gaming experiences for various platforms.",
+ },
+ {
+ title: "Machine Learning Engineer",
+ href: "#",
+ description:
+ "Develop machine learning models and algorithms to solve complex problems and make predictions based on data.",
+ },
+];
+
+export default function Navbar() {
+ return (
+
+
+
+
SkilledAI
+
+
+
+
+
+
+ Courses
+
+
+
+
+
+ Career Paths
+
+
+ {careerPaths.map((path) => (
+
+ {path.description}
+
+ ))}
+
+
+
+
+
+
+ Community
+
+
+
+
+
+
+ Pricing
+
+
+
+
+
+
+
+ Sign In
+
+
+
+
+
+ );
+}
+
+const ListItem = React.forwardRef<
+ React.ElementRef<"a">,
+ React.ComponentPropsWithoutRef<"a">
+>(({ className, title, children, ...props }, ref) => {
+ return (
+
+
+
+ {title}
+
+ {children}
+
+
+
+
+ );
+});
+ListItem.displayName = "ListItem";
diff --git a/src/components/pricing/check-item.tsx b/src/components/pricing/check-item.tsx
new file mode 100644
index 0000000..48ad54c
--- /dev/null
+++ b/src/components/pricing/check-item.tsx
@@ -0,0 +1,10 @@
+import { CheckCircle2 } from "lucide-react"
+
+const CheckItem = ({ text }: { text: string }) => (
+
+ )
+
+ export default CheckItem
\ No newline at end of file
diff --git a/src/components/pricing/pricing-card.tsx b/src/components/pricing/pricing-card.tsx
new file mode 100644
index 0000000..6500600
--- /dev/null
+++ b/src/components/pricing/pricing-card.tsx
@@ -0,0 +1,100 @@
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { cn } from "@/lib/utils";
+import CheckItem from "./check-item";
+
+type PricingCardProps = {
+ isYearly?: boolean;
+ title: string;
+ monthlyPrice?: number;
+ yearlyPrice?: number;
+ description: string;
+ features: string[];
+ actionLabel: string;
+ popular?: boolean;
+ exclusive?: boolean;
+};
+
+const PricingCard = ({
+ isYearly,
+ title,
+ monthlyPrice,
+ yearlyPrice,
+ description,
+ features,
+ actionLabel,
+ popular,
+ exclusive,
+}: PricingCardProps) => (
+
+
+
+ {isYearly && yearlyPrice && monthlyPrice ? (
+
+
+ {title}
+
+
+ Save ${monthlyPrice * 12 - yearlyPrice}
+
+
+ ) : (
+
+ {title}
+
+ )}
+
+
+ {yearlyPrice && isYearly
+ ? "$" + yearlyPrice
+ : monthlyPrice
+ ? "$" + monthlyPrice
+ : "Custom"}
+
+
+ {yearlyPrice && isYearly ? "/year" : monthlyPrice ? "/month" : null}
+
+
+ {description}
+
+
+ {features.map((feature: string) => (
+
+ ))}
+
+
+
+
+
+ {actionLabel}
+
+
+
+);
+
+export default PricingCard;
diff --git a/src/components/pricing/pricing-header.tsx b/src/components/pricing/pricing-header.tsx
new file mode 100644
index 0000000..3644fe2
--- /dev/null
+++ b/src/components/pricing/pricing-header.tsx
@@ -0,0 +1,9 @@
+const PricingHeader = ({ title, subtitle }: { title: string; subtitle: string }) => (
+
+ {title}
+ {subtitle}
+
+
+ )
+
+ export default PricingHeader
\ No newline at end of file
diff --git a/src/components/pricing/pricing-switch.tsx b/src/components/pricing/pricing-switch.tsx
new file mode 100644
index 0000000..aee08ec
--- /dev/null
+++ b/src/components/pricing/pricing-switch.tsx
@@ -0,0 +1,20 @@
+import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
+
+type PricingSwitchProps = {
+ onSwitch: (value: string) => void;
+};
+
+const PricingSwitch = ({ onSwitch }: PricingSwitchProps) => (
+
+
+
+ Monthly
+
+
+ Yearly
+
+
+
+);
+
+export default PricingSwitch;
diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx
new file mode 100644
index 0000000..5841fb3
--- /dev/null
+++ b/src/components/ui/navigation-menu.tsx
@@ -0,0 +1,128 @@
+import * as React from "react"
+import { ChevronDownIcon } from "@radix-ui/react-icons"
+import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
+import { cva } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const NavigationMenu = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+
+))
+NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
+
+const NavigationMenuList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
+
+const NavigationMenuItem = NavigationMenuPrimitive.Item
+
+const navigationMenuTriggerStyle = cva(
+ "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
+)
+
+const NavigationMenuTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}{" "}
+
+
+))
+NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
+
+const NavigationMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
+
+const NavigationMenuLink = NavigationMenuPrimitive.Link
+
+const NavigationMenuViewport = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+))
+NavigationMenuViewport.displayName =
+ NavigationMenuPrimitive.Viewport.displayName
+
+const NavigationMenuIndicator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+))
+NavigationMenuIndicator.displayName =
+ NavigationMenuPrimitive.Indicator.displayName
+
+export {
+ navigationMenuTriggerStyle,
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuContent,
+ NavigationMenuTrigger,
+ NavigationMenuLink,
+ NavigationMenuIndicator,
+ NavigationMenuViewport,
+}
diff --git a/src/lib/markdown-to-html.ts b/src/lib/markdown-to-html.ts
index 4946106..ef50e64 100644
--- a/src/lib/markdown-to-html.ts
+++ b/src/lib/markdown-to-html.ts
@@ -9,6 +9,7 @@ export async function markdownToHtml(tutorialCode: string) {
.use(remarkParse)
.use(remarkRehype)
.use(rehypePrettyCode, {})
+ // @ts-ignore
.use(rehypeStringify)
.process(tutorialCode);
diff --git a/tailwind.config.js b/tailwind.config.js
index 338e949..8aaf07d 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -69,10 +69,19 @@ module.exports = {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
+ "background-shine": {
+ from: {
+ backgroundPosition: "0 0",
+ },
+ to: {
+ backgroundPosition: "-200% 0",
+ },
+ },
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
+ "background-shine": "background-shine 2s linear infinite",
},
},
},