feat: initial commit — Webflow to Next.js conversion
QuantumLab template converted to Next.js 16 + React 19 + TypeScript: - 8 page routes (home, about, blog, contact, careers, team-members, coming-soon, 404) - Dynamic routes for blog posts, career positions, and team members - GSAP animations (marquee, counters, button hovers) - IntersectionObserver-based scroll reveal (blur-to-clear transitions) - Dark mode with next-themes - React Hook Form + Zod contact form - Framer Motion page transitions - Lottie animations via lottie-web Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import type { Metadata } from "next"
|
||||
import { HeroSection, MissionSection, TeamSection, ValuesSection, CareersSection, SocialLinksSection } from "@/components/about"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "About",
|
||||
description: "Learn about DalCode's mission, team, and values. We're building the next generation of AI-powered developer tools.",
|
||||
openGraph: {
|
||||
title: "About DalCode",
|
||||
description: "Learn about DalCode's mission, team, and values.",
|
||||
},
|
||||
}
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection />
|
||||
<MissionSection />
|
||||
<TeamSection />
|
||||
<ValuesSection />
|
||||
<CareersSection />
|
||||
<SocialLinksSection />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { Metadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { BLOG_POSTS } from "@/lib/blog-data"
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return BLOG_POSTS.map((post) => ({ slug: post.slug }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params
|
||||
const post = BLOG_POSTS.find((p) => p.slug === slug)
|
||||
if (!post) return { title: "Post Not Found" }
|
||||
return {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
images: [{ url: post.image }],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function BlogPostPage({ params }: Props) {
|
||||
const { slug } = await params
|
||||
const post = BLOG_POSTS.find((p) => p.slug === slug)
|
||||
if (!post) notFound()
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="text-center">
|
||||
<div className="blog-details-wrapper" style={{ justifyContent: "center" }}>
|
||||
<div className="item-details">{post.date}</div>
|
||||
<div className="item-details-divider">·</div>
|
||||
<div className="item-details">{post.category}</div>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<h1>{post.title}</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>{post.excerpt}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="corner-gradient-container">
|
||||
<div className="border-wrapper" style={{ position: "relative", aspectRatio: "16/9" }}>
|
||||
<Image
|
||||
src={post.image}
|
||||
alt={post.imageAlt}
|
||||
fill
|
||||
style={{ objectFit: "cover", borderRadius: 12 }}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<div className="corner-gradient-wrapper">
|
||||
<div className="corner-gradient-horizontal top-left" />
|
||||
<div className="corner-gradient-horizontal bottom-left" />
|
||||
<div className="corner-gradient-horizontal top-right" />
|
||||
<div className="corner-gradient-horizontal bottom-right" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="blog-post-rich-text w-richtext">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.</p>
|
||||
<h2>Key Insights</h2>
|
||||
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit.</p>
|
||||
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.</p>
|
||||
<h2>Looking Ahead</h2>
|
||||
<p>Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center text-center">
|
||||
<Link href="/blog" className="primary-button w-inline-block">
|
||||
<div className="button-content">
|
||||
<div>Back to all articles</div>
|
||||
<div className="button-icon-wrapper primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 17 17" fill="none" className="squared-icon">
|
||||
<path d="M6.25391 3.45312L10.7458 8.01563L6.25391 12.5781" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
|
||||
</svg>
|
||||
<div className="button-icon-bg" />
|
||||
<div className="button-icon-bg-inside" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Metadata } from "next"
|
||||
import { HeroSection, CtaSection, PostsGridSection } from "@/components/blog"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Blog",
|
||||
description: "Insights on AI, machine learning, and the future of software development from the DalCode team.",
|
||||
openGraph: {
|
||||
title: "DalCode Blog",
|
||||
description: "Insights on AI, machine learning, and the future of software development.",
|
||||
},
|
||||
}
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection />
|
||||
<CtaSection />
|
||||
<PostsGridSection />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { CAREERS } from "@/lib/careers-data"
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return CAREERS.map((career) => ({ slug: career.slug }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params
|
||||
const career = CAREERS.find((c) => c.slug === slug)
|
||||
if (!career) return { title: "Position Not Found" }
|
||||
return {
|
||||
title: career.title,
|
||||
description: career.description,
|
||||
openGraph: {
|
||||
title: `${career.title} - DalCode Careers`,
|
||||
description: career.description,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function CareerDetailPage({ params }: Props) {
|
||||
const { slug } = await params
|
||||
const career = CAREERS.find((c) => c.slug === slug)
|
||||
if (!career) notFound()
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="text-center">
|
||||
<div className="blog-details-wrapper" style={{ justifyContent: "center" }}>
|
||||
<div className="item-details">{career.department}</div>
|
||||
<div className="item-details-divider">·</div>
|
||||
<div className="item-details">{career.location}</div>
|
||||
<div className="item-details-divider">·</div>
|
||||
<div className="item-details">{career.type}</div>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<h1>{career.title}</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>{career.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="blog-post-rich-text w-richtext">
|
||||
<h2>About the role</h2>
|
||||
<p>We are looking for a {career.title} to join our {career.department} team. In this role, you will work alongside world-class engineers and researchers to push the boundaries of what's possible with AI.</p>
|
||||
<h2>Responsibilities</h2>
|
||||
<ul role="list">
|
||||
<li>Collaborate with cross-functional teams to design, develop, and deploy AI solutions</li>
|
||||
<li>Contribute to research and development of novel AI architectures and algorithms</li>
|
||||
<li>Write clean, maintainable, and well-tested code</li>
|
||||
<li>Participate in code reviews and contribute to engineering best practices</li>
|
||||
<li>Stay up-to-date with the latest developments in AI and machine learning</li>
|
||||
</ul>
|
||||
<h2>Requirements</h2>
|
||||
<ul role="list">
|
||||
<li>Strong background in computer science, mathematics, or a related field</li>
|
||||
<li>Experience with modern AI/ML frameworks and tools</li>
|
||||
<li>Excellent problem-solving and communication skills</li>
|
||||
<li>Ability to work independently and as part of a team</li>
|
||||
</ul>
|
||||
<h2>What we offer</h2>
|
||||
<ul role="list">
|
||||
<li>Competitive salary and equity package</li>
|
||||
<li>Comprehensive health, dental, and vision insurance</li>
|
||||
<li>Flexible work arrangements</li>
|
||||
<li>Learning and development budget</li>
|
||||
<li>Regular team events and offsites</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center text-center">
|
||||
<Link href="/careers" className="primary-button w-inline-block">
|
||||
<div className="button-content">
|
||||
<div>Back to all positions</div>
|
||||
<div className="button-icon-wrapper primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 17 17" fill="none" className="squared-icon">
|
||||
<path d="M6.25391 3.45312L10.7458 8.01563L6.25391 12.5781" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
|
||||
</svg>
|
||||
<div className="button-icon-bg" />
|
||||
<div className="button-icon-bg-inside" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
import { CAREERS } from "@/lib/careers-data"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Careers",
|
||||
description: "Join our team and help shape the future of AI. Explore open positions at DalCode.",
|
||||
openGraph: {
|
||||
title: "Careers at DalCode",
|
||||
description: "Join our team and help shape the future of AI.",
|
||||
},
|
||||
}
|
||||
|
||||
export default function CareersPage() {
|
||||
return (
|
||||
<main>
|
||||
<section className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="text-center">
|
||||
<div className="subtitle">Careers</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<h1>Join our team</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>We're looking for talented people to help us build the future of AI-powered development tools.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="corner-gradient-container">
|
||||
<div className="border-wrapper">
|
||||
<div className="positions-list-wrapper">
|
||||
{CAREERS.map((career) => (
|
||||
<Link key={career.slug} href={`/careers/${career.slug}`} className="position-item w-inline-block">
|
||||
<div className="position-item-content">
|
||||
<div className="position-info">
|
||||
<h3 className="display-4">{career.title}</h3>
|
||||
<div className="position-details">
|
||||
<div className="item-details">{career.department}</div>
|
||||
<div className="item-details-divider">·</div>
|
||||
<div className="item-details">{career.location}</div>
|
||||
<div className="item-details-divider">·</div>
|
||||
<div className="item-details">{career.type}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="button-icon-wrapper primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 17 17" fill="none" className="squared-icon">
|
||||
<path d="M6.25391 3.45312L10.7458 8.01563L6.25391 12.5781" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
|
||||
</svg>
|
||||
<div className="button-icon-bg" />
|
||||
<div className="button-icon-bg-inside" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="corner-gradient-wrapper">
|
||||
<div className="corner-gradient-horizontal top-left" />
|
||||
<div className="corner-gradient-horizontal bottom-left" />
|
||||
<div className="corner-gradient-horizontal top-right" />
|
||||
<div className="corner-gradient-horizontal bottom-right" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Coming Soon",
|
||||
description: "This page is coming soon. Stay tuned for updates.",
|
||||
}
|
||||
|
||||
export default function ComingSoonPage() {
|
||||
return (
|
||||
<main className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="text-center" style={{ padding: "120px 0" }}>
|
||||
<div className="subtitle">Coming soon</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<h1>Under construction</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>We're working on something exciting. Check back soon for updates.</p>
|
||||
</div>
|
||||
<div className="mg-top-24px">
|
||||
<Link href="/" className="primary-button w-inline-block">
|
||||
<div className="button-content">
|
||||
<div>Back to home</div>
|
||||
<div className="button-icon-wrapper primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 17 17" fill="none" className="squared-icon">
|
||||
<path d="M6.25391 3.45312L10.7458 8.01563L6.25391 12.5781" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
|
||||
</svg>
|
||||
<div className="button-icon-bg" />
|
||||
<div className="button-icon-bg-inside" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Metadata } from "next"
|
||||
import { HeroSection, FormSection, CardsSection } from "@/components/contact"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Contact",
|
||||
description: "Get in touch with the DalCode team. We'd love to hear from you about partnerships, support, or general inquiries.",
|
||||
openGraph: {
|
||||
title: "Contact DalCode",
|
||||
description: "Get in touch with the DalCode team.",
|
||||
},
|
||||
}
|
||||
|
||||
export default function ContactPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection />
|
||||
<FormSection />
|
||||
<CardsSection />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,92 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/* Webflow base resets are in webflow.css */
|
||||
|
||||
/* Dark mode: override Webflow CSS variables */
|
||||
.dark {
|
||||
--core--colors--neutral--800: #f5f5f5;
|
||||
--core--colors--neutral--700: #e0e0e0;
|
||||
--core--colors--neutral--600: #a0a0a0;
|
||||
--core--colors--neutral--500: #707070;
|
||||
--core--colors--neutral--400: #2a2a2a;
|
||||
--core--colors--neutral--300: #1e1e1e;
|
||||
--core--colors--neutral--200: #161616;
|
||||
--core--colors--neutral--100: #0d0d0d;
|
||||
--font--colors--title: var(--core--colors--neutral--800);
|
||||
--font--colors--paragraph: var(--core--colors--neutral--600);
|
||||
}
|
||||
|
||||
.dark body,
|
||||
.dark .page-wrapper {
|
||||
background-color: #0d0d0d;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.dark .section-small,
|
||||
.dark .section,
|
||||
.dark .hero-v1-grid-wrapper,
|
||||
.dark .cta-section:not(.v4) {
|
||||
background-color: #0d0d0d;
|
||||
}
|
||||
|
||||
.dark .border-wrapper,
|
||||
.dark .corner-gradient-container:not(.row) {
|
||||
background-color: #141414;
|
||||
}
|
||||
|
||||
.dark .input:not(.dark-mode) {
|
||||
background-color: #1a1a1a;
|
||||
border-color: #2a2a2a;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.dark .input:not(.dark-mode)::placeholder {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.dark .header-wrapper,
|
||||
.dark .header-wrapper---absolute {
|
||||
background-color: rgba(13, 13, 13, 0.9);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.dark .link .link-text {
|
||||
color: #d0d0d0;
|
||||
}
|
||||
|
||||
.dark .footer-wrapper {
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
|
||||
/* Show/hide elements based on theme */
|
||||
.show-dark-mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dark .show-dark-mode {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dark .show-light-mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Theme toggle button */
|
||||
.theme-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--core--colors--neutral--400);
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--core--colors--neutral--700);
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.theme-toggle:hover {
|
||||
background-color: var(--core--colors--neutral--300);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import type { Metadata } from "next"
|
||||
import { Inter, Inter_Tight } from "next/font/google"
|
||||
import { ThemeProvider } from "next-themes"
|
||||
import Header from "@/components/Header"
|
||||
import Footer from "@/components/Footer"
|
||||
import GsapAnimations from "@/components/GsapAnimations"
|
||||
import RevealObserver from "@/components/RevealObserver"
|
||||
import PageTransition from "@/components/PageTransition"
|
||||
import "./webflow.css"
|
||||
import "./globals.css"
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "600"],
|
||||
variable: "--font-inter",
|
||||
display: "swap",
|
||||
})
|
||||
|
||||
const interTight = Inter_Tight({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "600"],
|
||||
variable: "--font-inter-tight",
|
||||
display: "swap",
|
||||
})
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: "DalCode - AI Code Intelligence",
|
||||
template: "%s | DalCode",
|
||||
},
|
||||
description: "DalCode - AI-powered code intelligence platform for innovation-driven teams.",
|
||||
openGraph: {
|
||||
type: "website",
|
||||
siteName: "DalCode",
|
||||
},
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`w-mod-js ${inter.variable} ${interTight.variable}`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<body className={inter.className}>
|
||||
<ThemeProvider attribute="class" defaultTheme="light" enableSystem>
|
||||
<div className="page-wrapper">
|
||||
<Header />
|
||||
<PageTransition>{children}</PageTransition>
|
||||
<Footer />
|
||||
</div>
|
||||
<RevealObserver />
|
||||
<GsapAnimations />
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import Link from "next/link"
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<main className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="text-center" style={{ padding: "120px 0" }}>
|
||||
<div className="subtitle">404</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<h1>Page not found</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>The page you're looking for doesn't exist or has been moved.</p>
|
||||
</div>
|
||||
<div className="mg-top-24px">
|
||||
<Link href="/" className="form-button w-button">
|
||||
Back to home
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Metadata } from "next"
|
||||
import { HeroSection, IntegrationsSection, PrinciplesSection, CtaSection, BlogPreviewSection } from "@/components/home"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "DalCode - AI Code Intelligence Platform",
|
||||
description: "Transform your development workflow with AI-powered code intelligence. DalCode helps innovation-driven teams ship faster with smart automation and deep code understanding.",
|
||||
openGraph: {
|
||||
title: "DalCode - AI Code Intelligence Platform",
|
||||
description: "Transform your development workflow with AI-powered code intelligence.",
|
||||
},
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection />
|
||||
<IntegrationsSection />
|
||||
<PrinciplesSection />
|
||||
<CtaSection />
|
||||
<BlogPreviewSection />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import type { Metadata } from "next"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { TEAM_MEMBERS } from "@/lib/team-data"
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ id: string }>
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return TEAM_MEMBERS.map((member) => ({ id: member.slug }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { id } = await params
|
||||
const member = TEAM_MEMBERS.find((m) => m.slug === id)
|
||||
if (!member) return { title: "Team Member Not Found" }
|
||||
return {
|
||||
title: member.name,
|
||||
description: `${member.name} - ${member.role} at DalCode`,
|
||||
openGraph: {
|
||||
title: `${member.name} - ${member.role}`,
|
||||
description: member.bio,
|
||||
images: [{ url: member.image }],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function TeamMemberPage({ params }: Props) {
|
||||
const { id } = await params
|
||||
const member = TEAM_MEMBERS.find((m) => m.slug === id)
|
||||
if (!member) notFound()
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section className="section-small top overflow-hidden">
|
||||
<div className="w-layout-blockcontainer container-default w-container">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="text-center">
|
||||
<div className="team-member-avatar-large" style={{ position: "relative", width: 200, height: 200, margin: "0 auto", borderRadius: "50%", overflow: "hidden" }}>
|
||||
<Image
|
||||
src={member.image}
|
||||
alt={member.name}
|
||||
fill
|
||||
style={{ objectFit: "cover" }}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<h1>{member.name}</h1>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<div className="subtitle">{member.role}</div>
|
||||
</div>
|
||||
<div className="mg-top-4x-extra-small">
|
||||
<p>{member.bio}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="blog-post-rich-text w-richtext">
|
||||
<h2>About</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat.</p>
|
||||
<p>Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center">
|
||||
<div className="team-member-buttons-wrapper" style={{ justifyContent: "center" }}>
|
||||
<div>
|
||||
<a href="https://x.com" className="social-square-icon-link w-inline-block" target="_blank" rel="noopener noreferrer">
|
||||
<div className="social-square-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 19 18" fill="none" className="social-media-icon">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M7.04543 9.42969L0.0390625 0.25H5.98663L10.1792 5.74312L14.8487 0.25H17.7333L11.5439 7.53115L18.9618 17.25H13.0143L8.41014 11.2177L3.28238 17.25H0.397729L7.04543 9.42969ZM13.8802 15.4998L3.57671 2.00024H5.12071L15.4242 15.4998H13.8802Z" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="social-square-bg" />
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://linkedin.com" className="social-square-icon-link w-inline-block" target="_blank" rel="noopener noreferrer">
|
||||
<div className="social-square-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 20 20" fill="none" className="social-media-icon">
|
||||
<path d="M1 2.99134C1 2.41413 1.20271 1.93794 1.60811 1.56277C2.01351 1.18758 2.54055 1 3.18919 1C3.82626 1 4.34169 1.18469 4.73552 1.55411C5.14092 1.93506 5.34363 2.43145 5.34363 3.04329C5.34363 3.5974 5.14672 4.05915 4.7529 4.42857C4.3475 4.80952 3.81467 5 3.15444 5H3.13707C2.49999 5 1.98456 4.80952 1.59073 4.42857C1.19691 4.04762 1 3.56854 1 2.99134ZM1.22587 18.1429V6.57576H5.08301V18.1429H1.22587ZM7.22008 18.1429H11.0772V11.684C11.0772 11.2799 11.1236 10.9682 11.2162 10.7489C11.3784 10.3564 11.6245 10.0245 11.9546 9.75324C12.2847 9.48195 12.6988 9.34632 13.1969 9.34632C14.4942 9.34632 15.1429 10.2179 15.1429 11.961V18.1429H19V11.5108C19 9.8023 18.5946 8.50649 17.7838 7.62337C16.973 6.74026 15.9015 6.2987 14.5695 6.2987C13.0753 6.2987 11.9112 6.93939 11.0772 8.22078V8.25541H11.0598L11.0772 8.22078V6.57576H7.22008C7.24324 6.94516 7.25483 8.09378 7.25483 10.0216C7.25483 11.9495 7.24324 14.6565 7.22008 18.1429Z" fill="currentColor" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="social-square-bg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mg-top-regular">
|
||||
<div className="inner-container _650px center text-center">
|
||||
<Link href="/about" className="primary-button w-inline-block">
|
||||
<div className="button-content">
|
||||
<div>Back to team</div>
|
||||
<div className="button-icon-wrapper primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 17 17" fill="none" className="squared-icon">
|
||||
<path d="M6.25391 3.45312L10.7458 8.01563L6.25391 12.5781" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
|
||||
</svg>
|
||||
<div className="button-icon-bg" />
|
||||
<div className="button-icon-bg-inside" />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
+11061
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user