Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/cindy.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/huajie.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/nick.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/pratyush.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AuthButtons } from "@ui/auth-buttons";
import { Button } from "@/components/ui/button";
import { TypesGrid } from "@/components/types-grid";
import { config } from "@/lib/config";
import ResultsMain from "@/components/results/main";

async function getSurveyCount() {
try {
Expand Down Expand Up @@ -87,8 +88,8 @@ export default async function Home() {
</div>
</section>

{/* Types Section */}
<TypesGrid />
{/* Results Section */}
<ResultsMain />
</main>
);
}
79 changes: 79 additions & 0 deletions src/app/type/[typeCode]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { COUPLE_TYPES, CoupleTypeCode } from "@/lib/constants/coupleTypes";
import { notFound } from "next/navigation";
import Image from "next/image";
import dynamic from "next/dynamic";

interface TypePageProps {
params: Promise<{
typeCode: string;
}>;
}

export default async function TypePage({ params }: TypePageProps) {
// Await params in Next.js 15+
const { typeCode } = await params;

// Fixes naming scheme
const enumKey = typeCode.toUpperCase().replace(/-/g, '_') as CoupleTypeCode;
const coupleType = COUPLE_TYPES[enumKey];

// If type not found, show 404
if (!coupleType) {
notFound();
}

// Import Component for later
const Component = dynamic(
() => import(`@/components/types/${typeCode}`),
{
loading: () => <div className="text-center p-8">Loading...</div>,
ssr: true
}
);

return (
<main className="min-h-screen bg-background">
<div className="container mx-auto px-12 py-16">
<div className="max-w-4xl mx-auto">
{/* Header Section probs should just render evevrything in component in final draft but im lazy for this*/}
<div className="text-center mb-12">
<div
className="aspect-square w-32 h-32 rounded-2xl flex items-center justify-center mx-auto mb-6"
style={{
background: `linear-gradient(135deg, ${coupleType.graphic.colorScheme.primary}20, ${coupleType.graphic.colorScheme.secondary}20)`
}}
>
<div
className="w-20 h-20 rounded-full flex items-center justify-center overflow-hidden"
style={{
backgroundColor: `${coupleType.graphic.colorScheme.primary}30`
}}
>
<Image
src={coupleType.graphic.iconUrl}
alt={coupleType.displayName}
width={80}
height={80}
className="w-full h-full object-cover rounded-full"
/>
</div>
</div>
<h1 className="text-4xl font-bold mb-4">{coupleType.displayName}</h1>
<p className="text-xl text-muted-foreground">{coupleType.shortDescription}</p>
</div>

{/* Content Section - Render the actual component */}
<div className="space-y-8">
<Component />
</div>
</div>
</div>
</main>
);
}

export async function generateStaticParams() {
return Object.values(COUPLE_TYPES).map((type) => ({
typeCode: type.code.toLowerCase().replace(/_/g, '-'),
}));
}
140 changes: 140 additions & 0 deletions src/app/type/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { COUPLE_TYPES } from "@/lib/constants/coupleTypes";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import Image from "next/image";

export default function CoupleTypesPage() {
const coupleTypes = Object.values(COUPLE_TYPES);

return (
<main className="min-h-screen">
{/* Row 1 - Types 1-4 */}
<section className="min-h-[75vh] bg-background">
<div className="container mx-auto px-12 py-16">
<div className="grid lg:grid-cols-4 gap-8 items-start h-full">
{coupleTypes.slice(0, 4).map((type, index) => (
<div key={type.code} className="space-y-6 text-center flex flex-col items-center">
<div className="aspect-square bg-gradient-to-br from-primary/10 to-secondary/10 rounded-2xl flex items-center justify-center p-8 w-full">
<Image
src={type.graphic.iconUrl}
alt={type.displayName}
width={96}
height={96}
className="w-full h-full object-cover"
/>
</div>
<div className="space-y-3">
<h3 className="text-xl font-bold">{type.displayName}</h3>
<p className="text-muted-foreground text-sm leading-relaxed">
{type.shortDescription}
</p>
<Link href={`/type/${type.code.toLowerCase().replace(/_/g, '-')}`}>
<Button variant="outline" size="sm" className="mt-4">
Learn More
</Button>
</Link>
</div>
</div>
))}
</div>
</div>
</section>

{/* Row 2 - Types 5-8 */}
<section className="min-h-[75vh] bg-muted/30">
<div className="container mx-auto px-12 py-16">
<div className="grid lg:grid-cols-4 gap-8 items-start h-full">
{coupleTypes.slice(4, 8).map((type, index) => (
<div key={type.code} className="space-y-6 text-center flex flex-col items-center">
<div className="aspect-square bg-gradient-to-br from-secondary/10 to-accent/10 rounded-2xl flex items-center justify-center p-8 w-full">
<Image
src={type.graphic.iconUrl}
alt={type.displayName}
width={96}
height={96}
className="w-full h-full object-cover"
/>
</div>
<div className="space-y-3">
<h3 className="text-xl font-bold">{type.displayName}</h3>
<p className="text-muted-foreground text-sm leading-relaxed">
{type.shortDescription}
</p>
<Link href={`/type/${type.code.toLowerCase().replace(/_/g, '-')}`}>
<Button variant="outline" size="sm" className="mt-4">
Learn More
</Button>
</Link>
</div>
</div>
))}
</div>
</div>
</section>

{/* Row 3 - Types 9-12 */}
<section className="min-h-[75vh] bg-background">
<div className="container mx-auto px-12 py-16">
<div className="grid lg:grid-cols-4 gap-8 items-start h-full">
{coupleTypes.slice(8, 12).map((type, index) => (
<div key={type.code} className="space-y-6 text-center flex flex-col items-center">
<div className="aspect-square bg-gradient-to-br from-accent/10 to-primary/10 rounded-2xl flex items-center justify-center p-8 w-full">
<Image
src={type.graphic.iconUrl}
alt={type.displayName}
width={96}
height={96}
className="w-full h-full object-cover"
/>
</div>
<div className="space-y-3">
<h3 className="text-xl font-bold">{type.displayName}</h3>
<p className="text-muted-foreground text-sm leading-relaxed">
{type.shortDescription}
</p>
<Link href={`/type/${type.code.toLowerCase().replace(/_/g, '-')}`}>
<Button variant="outline" size="sm" className="mt-4">
Learn More
</Button>
</Link>
</div>
</div>
))}
</div>
</div>
</section>

{/* Row 4 - Types 13-16 */}
<section className="min-h-[75vh] bg-muted/20">
<div className="container mx-auto px-12 py-16">
<div className="grid lg:grid-cols-4 gap-8 items-start h-full">
{coupleTypes.slice(12, 16).map((type, index) => (
<div key={type.code} className="space-y-6 text-center flex flex-col items-center">
<div className="aspect-square bg-gradient-to-br from-primary/15 to-secondary/15 rounded-2xl flex items-center justify-center p-8 w-full">
<Image
src={type.graphic.iconUrl}
alt={type.displayName}
width={96}
height={96}
className="w-full h-full object-cover"
/>
</div>
<div className="space-y-3">
<h3 className="text-xl font-bold">{type.displayName}</h3>
<p className="text-muted-foreground text-sm leading-relaxed">
{type.shortDescription}
</p>
<Link href={`/type/${type.code.toLowerCase().replace(/_/g, '-')}`}>
<Button variant="outline" size="sm" className="mt-4">
Learn More
</Button>
</Link>
</div>
</div>
))}
</div>
</div>
</section>
</main>
);
}
21 changes: 13 additions & 8 deletions src/components/navbar/desktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
NavigationMenuList,
} from "@/components/ui/navigation-menu";
import { navigationItems, type NavItem } from "./nav-config";
import { TypeIndicatorDropdown } from "./type-indicator-dropdown";

export function DesktopNavbar() {
const { data: session } = useSession();
Expand All @@ -40,14 +41,18 @@ export function DesktopNavbar() {
<NavigationMenuList>
{filteredNavItems.map((item) => (
<NavigationMenuItem key={item.href}>
<NavigationMenuLink asChild>
<Link
href={item.href}
className="group inline-flex h-10 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"
>
{item.label}
</Link>
</NavigationMenuLink>
{item.label === "Type Indicator" ? (
<TypeIndicatorDropdown />
) : (
<NavigationMenuLink asChild>
<Link
href={item.href}
className="group inline-flex h-10 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"
>
{item.label}
</Link>
</NavigationMenuLink>
)}
</NavigationMenuItem>
))}
</NavigationMenuList>
Expand Down
4 changes: 4 additions & 0 deletions src/components/navbar/nav-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ export const navigationItems: NavItem[] = [
label: "About",
href: "/about",
},
{
label: "Type Indicator",
href: "/type",
}
];
101 changes: 101 additions & 0 deletions src/components/navbar/type-indicator-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"use client";

import Link from "next/link";
import { COUPLE_TYPES } from "@/lib/constants/coupleTypes";
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
} from "@/components/ui/navigation-menu";

export interface DropdownItem {
label: string;
href: string;
}

// Generate dropdown items from couple types
const generateTypeIndicatorDropdown = (): DropdownItem[] => {
return Object.values(COUPLE_TYPES)
.filter(coupleType => coupleType && coupleType.displayName && coupleType.code)
.map((coupleType) => ({
label: coupleType.displayName,
href: `/type/${coupleType.code.toLowerCase().replace(/_/g, '-')}`,
}));
};

interface TypeIndicatorDropdownProps {
dropdown?: DropdownItem[];
}

export function TypeIndicatorDropdown({ dropdown = generateTypeIndicatorDropdown() }: TypeIndicatorDropdownProps) {
return (
<NavigationMenu viewport={false}>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>
<Link href="/type">Type Indicator</Link>
</NavigationMenuTrigger>
<NavigationMenuContent className="min-w-[480px] p-4 !transform-none !translate-x-0 !translate-y-0 ![animation:none] data-[motion]:!transform-none !left-auto !right-0" style={{ marginTop: '2vh' }}>
{/* Row 1 */}
<div className="grid grid-cols-4 gap-2 mb-3">
{dropdown.slice(0, 4).map((dropdownItem, index) => (
<NavigationMenuLink key={`row1-${index}-${dropdownItem.href}`} asChild>
<Link href={dropdownItem.href || '#'} className="text-center">
<div className="text-sm font-medium leading-none">
{dropdownItem.label || 'Loading...'}
</div>
</Link>
</NavigationMenuLink>
))}
</div>
<div className="h-px bg-border mb-3"></div>

{/* Row 2 */}
<div className="grid grid-cols-4 gap-2 mb-3">
{dropdown.slice(4, 8).map((dropdownItem, index) => (
<NavigationMenuLink key={`row2-${index}-${dropdownItem.href}`} asChild>
<Link href={dropdownItem.href || '#'} className="text-center">
<div className="text-sm font-medium leading-none">
{dropdownItem.label || 'Loading...'}
</div>
</Link>
</NavigationMenuLink>
))}
</div>
<div className="h-px bg-border mb-3"></div>

{/* Row 3 */}
<div className="grid grid-cols-4 gap-2 mb-3">
{dropdown.slice(8, 12).map((dropdownItem, index) => (
<NavigationMenuLink key={`row3-${index}-${dropdownItem.href}`} asChild>
<Link href={dropdownItem.href || '#'} className="text-center">
<div className="text-sm font-medium leading-none">
{dropdownItem.label || 'Loading...'}
</div>
</Link>
</NavigationMenuLink>
))}
</div>
<div className="h-px bg-border mb-3"></div>

{/* Row 4 */}
<div className="grid grid-cols-4 gap-2">
{dropdown.slice(12, 16).map((dropdownItem, index) => (
<NavigationMenuLink key={`row4-${index}-${dropdownItem.href}`} asChild>
<Link href={dropdownItem.href || '#'} className="text-center">
<div className="text-sm font-medium leading-none">
{dropdownItem.label || 'Loading...'}
</div>
</Link>
</NavigationMenuLink>
))}
</div>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
);
}
Loading