diff --git a/apps/web/package.json b/apps/web/package.json index 93e5369b..9eb5d891 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -36,6 +36,7 @@ "cmdk": "^1.1.1", "convex": "^1.29.0", "date-fns": "^4.1.0", + "framer-motion": "^12.23.24", "lucide-react": "^0.553.0", "next": "16.0.1", "next-themes": "^0.4.6", diff --git a/apps/web/public/feature.png b/apps/web/public/feature.png new file mode 100644 index 00000000..002bb161 Binary files /dev/null and b/apps/web/public/feature.png differ diff --git a/apps/web/public/features2.png b/apps/web/public/features2.png new file mode 100644 index 00000000..763441c9 Binary files /dev/null and b/apps/web/public/features2.png differ diff --git a/apps/web/public/logo-dark.png b/apps/web/public/logo-dark.png new file mode 100644 index 00000000..7ebcd2f9 Binary files /dev/null and b/apps/web/public/logo-dark.png differ diff --git a/apps/web/public/logo.png b/apps/web/public/logo.png new file mode 100644 index 00000000..ab6fce4b Binary files /dev/null and b/apps/web/public/logo.png differ diff --git a/apps/web/src/app/(Landing)/layout.tsx b/apps/web/src/app/(Landing)/layout.tsx deleted file mode 100644 index 8883f13c..00000000 --- a/apps/web/src/app/(Landing)/layout.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { SignedIn, SignedOut, UserButton } from "@clerk/nextjs"; -import Link from "next/link"; -import { Button } from "@/components/ui/button"; - -export default function HomeLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - <> -
- - - - - - -
- {children} - - ); -} diff --git a/apps/web/src/app/(Landing)/page.tsx b/apps/web/src/app/(Landing)/page.tsx deleted file mode 100644 index beef8cfd..00000000 --- a/apps/web/src/app/(Landing)/page.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { auth } from "@clerk/nextjs/server"; -import Image from "next/image"; -import { redirect } from "next/navigation"; - -export default async function Home() { - const { userId } = await auth(); - - if (userId) { - redirect("/dashboard"); - } - - return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
- -
- - Vercel logomark - Deploy now - - - Read our docs - -
-
- -
- ); -} diff --git a/apps/web/src/app/(landing)/layout.tsx b/apps/web/src/app/(landing)/layout.tsx new file mode 100644 index 00000000..a6af22dc --- /dev/null +++ b/apps/web/src/app/(landing)/layout.tsx @@ -0,0 +1,45 @@ +import { SignedIn, SignedOut, UserButton } from "@clerk/nextjs"; +import Image from "next/image"; +import Link from "next/link"; +import { Button } from "@/components/ui/button"; + +export default function HomeLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + <> +
+
+ AlbertPlus + AlbertPlus +
+ + + + + + + + +
+ + {children} + + ); +} diff --git a/apps/web/src/app/(landing)/page.tsx b/apps/web/src/app/(landing)/page.tsx new file mode 100644 index 00000000..03ae5509 --- /dev/null +++ b/apps/web/src/app/(landing)/page.tsx @@ -0,0 +1,309 @@ +import { auth } from "@clerk/nextjs/server"; +import { ArrowRight, ChevronRight, Sparkles } from "lucide-react"; +import Image from "next/image"; +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import HeroBadge from "@/components/ui/hero-badge"; + +export default async function Home() { + const { userId } = await auth(); + + if (userId) { + redirect("/dashboard"); + } + + return ( +
+ {/* Hero Section */} +
+
+ } + endIcon={} + /> + +

+ Plan better. Track easier.
+ Graduate smarter. +

+ +

+ A smarter student dashboard & course helper for NYU students +

+ +
+ +
+
+
+ + {/* Features Section */} +
+
+ {/* Feature Card 1 */} +
+ + + + Plan your semesters. Stay organized. See the big picture.{" "} + + + A visual Degree Progress Report that shows completed and + missing requirements at a glance. + +
+ Course Catalog +
+
+
+
+ +
+ + + + Track your progress. Understand your path.{" "} + + + A visual Degree Progress Report that shows completed and + missing requirements at a glance. + +
+ Course Catalog +
+
+
+
+ +
+ + + + Find courses faster. Search smarter.{" "} + + + An improved Course Search experience — clearer results, easier + navigation, and instant add options. + +
+ Course Catalog +
+
+
+
+ +
+ + + + Plan directly from Albert+ + + + Use the Sidebar to add courses and build your next semester + plan seamlessly. + +
+ Course Catalog +
+
+
+
+ +
+ + + + Plan your semesters. Stay organized. See the big picture.{" "} + + + A visual Degree Progress Report that shows completed and + missing requirements at a glance. + +
+ Course Catalog +
+
+
+
+
+
+ +
+

+ Explore More Features in Albert+ +

+
+ {/* Feature Card 1 */} +
+ + +
+ + Share your schedule{" "} + + + Show friends or advisors your upcoming semester with one + click. + +
+
+ Course Catalog +
+
+
+
+ +
+ + +
+ + Share your schedule{" "} + + + Show friends or advisors your upcoming semester with one + click. + +
+
+ Course Catalog +
+
+
+
+ +
+ + +
+ + Share your schedule{" "} + + + Show friends or advisors your upcoming semester with one + click. + +
+
+ Course Catalog +
+
+
+
+
+
+ + {/* CTA Section */} +
+
+

+ Want to be an A+ NYU student? Try Albert+ +

+ +
+ + +
+
+
+ + {/* Footer */} + +
+ ); +} diff --git a/apps/web/src/components/ui/hero-badge.tsx b/apps/web/src/components/ui/hero-badge.tsx new file mode 100644 index 00000000..8c9c24cf --- /dev/null +++ b/apps/web/src/components/ui/hero-badge.tsx @@ -0,0 +1,101 @@ +"use client"; + +import { motion, useAnimation, type Variants } from "framer-motion"; +import Link from "next/link"; +import { cn } from "@/lib/utils"; + +const ease: [number, number, number, number] = [0.16, 1, 0.3, 1]; + +interface HeroBadgeProps { + href?: string; + text: string; + icon?: React.ReactNode; + endIcon?: React.ReactNode; + variant?: "default" | "outline" | "ghost"; + size?: "sm" | "md" | "lg"; + className?: string; + onClick?: () => void; +} + +const badgeVariants: Record = { + default: "bg-background hover:bg-muted", + outline: "border-2 hover:bg-muted", + ghost: "hover:bg-muted/50", +}; + +const sizeVariants: Record = { + sm: "px-3 py-1 text-xs gap-1.5", + md: "px-4 py-1.5 text-sm gap-2", + lg: "px-5 py-2 text-base gap-2.5", +}; + +const iconAnimationVariants: Variants = { + initial: { rotate: 0 }, + hover: { rotate: -10 }, +}; + +export default function HeroBadge({ + href, + text, + icon, + endIcon, + variant = "default", + size = "md", + className, + onClick, +}: HeroBadgeProps) { + const controls = useAnimation(); + + const baseClassName = cn( + "inline-flex items-center rounded-full border transition-colors", + badgeVariants[variant], + sizeVariants[size], + className + ); + const wrapperClassName = cn("group", href ? "cursor-pointer" : undefined); + + const content = ( + controls.start("hover")} + onHoverEnd={() => controls.start("initial")} + > + {icon && ( + + {icon} + + )} + {text} + {endIcon && ( + {endIcon} + )} + + ); + + if (href) { + return ( + + {content} + + ); + } + + return ( + + {content} + + ); +} diff --git a/bun.lock b/bun.lock index 0b15d0b6..ad3e1f37 100644 --- a/bun.lock +++ b/bun.lock @@ -88,6 +88,7 @@ "cmdk": "^1.1.1", "convex": "^1.29.0", "date-fns": "^4.1.0", + "framer-motion": "^12.23.24", "lucide-react": "^0.553.0", "next": "16.0.1", "next-themes": "^0.4.6", @@ -1523,6 +1524,8 @@ "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + "framer-motion": ["framer-motion@12.23.24", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w=="], + "fs-extra": ["fs-extra@11.1.1", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -1927,6 +1930,10 @@ "mnemonic-id": ["mnemonic-id@3.2.7", "", {}, "sha512-kysx9gAGbvrzuFYxKkcRjnsg/NK61ovJOV4F1cHTRl9T5leg+bo6WI0pWIvOFh1Z/yDL0cjA5R3EEGPPLDv/XA=="], + "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], + + "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],