Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(about): move to custom page #436

Merged
merged 2 commits into from
Jan 7, 2025
Merged
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
59 changes: 0 additions & 59 deletions apps/web/src/app/[locale]/(tina)/about/page.tsx

This file was deleted.

146 changes: 146 additions & 0 deletions apps/web/src/app/[locale]/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import {
Section,
SectionHeader,
SectionHeaderSubtitle,
SectionHeaderTitle,
} from '@repo/design-system/components/section'
import { i18n } from '@repo/i18n/config'
import { getTranslations } from '@repo/i18n/server'
import { type WithLocale } from '@repo/i18n/types'
import { pageParams } from '@repo/og-utils/zod-params'
import { createMetadata } from '@repo/seo/metadata'
import { type Metadata } from 'next'
import { getPathname, getPathnames } from 'routing'
import { BlogOverview } from '../blog/blocks/blog-overview'
import { Testimonials } from '../testimonials/blocks/testimonials'
import { Cta } from '~/app/components/cta'
import {
Hero,
HeroContent,
HeroCTA,
HeroSubtitle,
HeroTitle,
} from '~/app/components/hero'
import { Link } from '~/app/components/link'
import { SkillItem, Skills } from '~/app/components/skills'
import { Split, SplitContent, SplitImage } from '~/app/components/split'

type PageProps = {
params: Promise<WithLocale>
}

export async function generateMetadata(
props: PageProps,
): Promise<Metadata | undefined> {
const { locale } = await props.params

const t = await getTranslations('pages.about')

const title = t('_meta.title')
const description = t('_meta.description')

return createMetadata({
title,
description,
image: `/api/og?${pageParams.toSearchString({
heading: title,
})}`,
alternates: {
canonical: getPathname({ locale, href: '/about' }),
languages: getPathnames(
'/about',
i18n.locales.filter((l) => l !== locale),
),
},
locale,
})
}

export default async function AboutPage(props: PageProps) {
await props.params
const t = await getTranslations('pages.about')

return (
<>
<Hero variant="secondary">
<HeroContent>
<HeroTitle title={t('hero.title')} />
<HeroSubtitle>{t('hero.subtitle')}</HeroSubtitle>
<div className="mt-md w-full">
<HeroCTA href="/contact">{t('hero.cta')}</HeroCTA>
</div>
</HeroContent>
</Hero>
<Section>
<Split>
<SplitContent>
<h2>{t('professional.title')}</h2>
<p>{t('professional.content.first')}</p>
<p>{t('professional.content.second')}</p>
</SplitContent>
<SplitImage
src="/uploads/about/daren-mountains.JPG"
alt={t('professional.image.alt')}
/>
</Split>
</Section>
<Section>
<SectionHeader>
<SectionHeaderTitle>{t('my-toolbox.title')}</SectionHeaderTitle>
<SectionHeaderSubtitle>
{t('my-toolbox.subtitle')}
</SectionHeaderSubtitle>
</SectionHeader>
<Skills>
<SkillItem skill="javascript" />
<SkillItem skill="react" />
<SkillItem skill="node" />
<SkillItem skill="tailwind" />
<SkillItem skill="next" />
<SkillItem skill="sanity" />
<SkillItem skill="webflow" />
<SkillItem skill="typescript" />
<SkillItem skill="vscode" />
<SkillItem skill="css" />
<SkillItem skill="html" />
<SkillItem skill="git" />
<SkillItem skill="figma" />
</Skills>
</Section>
<Section>
<Split>
<SplitImage
src="/uploads/about/daren-cycling.jpeg"
alt={t('personal.image.alt')}
/>
<SplitContent>
<h2>{t('personal.title')}</h2>
<p>{t('personal.content.first')}</p>
<p>{t('personal.content.second')}</p>
</SplitContent>
</Split>
</Section>
<Section>
<Cta
title={t('cta.title')}
subtitle={t('cta.subtitle')}
link={{ href: '/contact', label: t('cta.label') }}
/>
</Section>
<Section>
<SectionHeader cta={{ url: '/blog', title: t('blog.cta'), as: Link }}>
<SectionHeaderTitle>{t('blog.title')}</SectionHeaderTitle>
<SectionHeaderSubtitle>{t('blog.subtitle')}</SectionHeaderSubtitle>
</SectionHeader>
<BlogOverview count={2} />
</Section>
<Section>
<Testimonials
filter={{
type: ['colleague', 'client'],
}}
/>
</Section>
</>
)
}
11 changes: 2 additions & 9 deletions apps/web/src/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { InViewBackground } from '@repo/design-system/components/in-view-background'
import { MagnetButton } from '@repo/design-system/components/magnet'
import {
Section,
SectionHeader,
SectionHeaderSubtitle,
SectionHeaderTitle,
} from '@repo/design-system/components/section'
import { Paragraph } from '@repo/design-system/components/ui'
import { ArrowRightIcon } from '@repo/design-system/lib/icons'
import { i18n } from '@repo/i18n/config'
import { getTranslations } from '@repo/i18n/server'
import { type WithLocale } from '@repo/i18n/types'
Expand All @@ -19,12 +17,12 @@ import { Features } from '../components/features'
import {
Hero,
HeroContent,
HeroCTA,
HeroImage,
HeroSubtitle,
HeroTitle,
} from '../components/hero'
import { Highlights } from '../components/highlights'
import { Link } from '../components/link'
import { BlogOverview } from './blog/blocks/blog-overview'
import { Testimonials } from './testimonials/blocks/testimonials'
import { WorkOverview } from './work/blocks/work-overview'
Expand Down Expand Up @@ -74,12 +72,7 @@ export default async function HomePage(props: { params: Promise<WithLocale> }) {
<HeroSubtitle>{t('hero.subtitle')}</HeroSubtitle>
<Paragraph className="!mt-sm">{t('hero.content')}</Paragraph>
<div className="mt-md w-full">
<MagnetButton size="lg" asChild>
<Link href="/contact" className="flex items-center">
{t('hero.cta')}
<ArrowRightIcon className="text-accent ml-sm size-4" />
</Link>
</MagnetButton>
<HeroCTA href="/contact">{t('hero.cta')}</HeroCTA>
</div>
</HeroContent>
</Hero>
Expand Down
50 changes: 50 additions & 0 deletions apps/web/src/app/components/faq.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use client'

import { cx } from '@nerdfish/utils'
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
H3,
} from '@repo/design-system/components/ui'
import * as React from 'react'

export interface FAQItemProps
extends React.ComponentProps<typeof AccordionItem> {
question: string
answer: string
}

export function FAQItem({ question, answer, ...props }: FAQItemProps) {
const id = React.useId()

return (
<AccordionItem
{...props}
value={id}
className="rounded-container bg-muted p-lg py-sm focus-within:outline-active hover:bg-muted/50 group border-none outline-none transition-colors"
>
<AccordionTrigger className="py-lg !outline-none after:hidden hover:no-underline">
<H3 variant="primary" as="span">
{question}
</H3>
</AccordionTrigger>
darenmalfait marked this conversation as resolved.
Show resolved Hide resolved
<AccordionContent className="prose prose-xl pt-md text-primary text-xl">
{answer}
</AccordionContent>
</AccordionItem>
)
}

export type FAQProps = React.ComponentProps<typeof Accordion>

export function FAQ({ className, children, ...props }: FAQProps) {
return (
<div className="relative">
<Accordion {...props} className={cx('space-y-md', className)}>
{children}
</Accordion>
</div>
)
}
18 changes: 18 additions & 0 deletions apps/web/src/app/components/hero.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { cx } from '@nerdfish/utils'
import { MagnetButton } from '@repo/design-system/components/magnet'
import {
Section,
SectionHeaderSubtitle,
} from '@repo/design-system/components/section'
import { TextSlideUp } from '@repo/design-system/components/text-slide-up'
import { ArrowRightIcon } from '@repo/design-system/lib/icons'
import capitalize from 'lodash/capitalize'
import Image from 'next/image'
import * as React from 'react'
import { Link } from './link'

const AnimatedText = React.forwardRef<
HTMLSpanElement,
Expand Down Expand Up @@ -75,6 +78,21 @@ export function HeroTitle({
)
}

export function HeroCTA({
children,
className,
...props
}: React.ComponentProps<typeof Link>) {
return (
<MagnetButton size="lg" asChild>
<Link {...props} className={cx('flex items-center', className)}>
{children}
<ArrowRightIcon className="text-accent ml-sm size-4" />
</Link>
</MagnetButton>
)
}

export type HeroImageProps = React.ComponentProps<typeof Image>

export function HeroImage({ src, className, ...props }: HeroImageProps) {
Expand Down
37 changes: 37 additions & 0 deletions apps/web/src/app/components/keyword-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { cx } from '@nerdfish/utils'
import { H1, Marquee } from '@repo/design-system/components/ui'
import type * as React from 'react'

export interface KeywordProps
extends Omit<React.ComponentProps<typeof H1>, 'children'> {
children: string
}

export function Keyword({ children, className, ...props }: KeywordProps) {
return (
<H1
as="span"
variant="primary"
aria-label={children}
className={cx('uppercase', className)}
{...props}
>
<span>{children}</span>
<span aria-hidden className="ml-md">
-
</span>
</H1>
)
}

export type KeywordListProps = React.ComponentProps<typeof Marquee>

export function KeywordList({ children, ...props }: KeywordListProps) {
return (
<div className="max-w-full overflow-hidden">
<Marquee pauseOnHover duration={20000} repeat={5} {...props}>
{children}
</Marquee>
</div>
)
}
Loading