303 lines
15 KiB
TypeScript
303 lines
15 KiB
TypeScript
import { Head } from '@inertiajs/react';
|
|
import { ButtonLink } from '@/components/site/button';
|
|
import Card from '@/components/site/card';
|
|
import FeatureCard from '@/components/site/feature-card';
|
|
import Glow from '@/components/site/glow';
|
|
import Icon from '@/components/site/icon';
|
|
import IconTile from '@/components/site/icon-tile';
|
|
import ImageCard from '@/components/site/image-card';
|
|
import PageHero from '@/components/site/page-hero';
|
|
import RichText from '@/components/site/rich-text';
|
|
import Section from '@/components/site/section';
|
|
import SectionHeader from '@/components/site/section-header';
|
|
import CtaBanner from '@/components/site/sections/cta-banner';
|
|
import StatCard from '@/components/site/stat-card';
|
|
import { aboutContent } from '@/content/about';
|
|
import { clientsInSector, projectsBySector } from '@/data/projects';
|
|
import { consultationUrl } from '@/data/site';
|
|
import { useContent } from '@/hooks/use-locale';
|
|
import { clients, services } from '@/routes';
|
|
|
|
export default function About() {
|
|
const t = useContent(aboutContent);
|
|
|
|
return (
|
|
<>
|
|
<Head title={t.title} />
|
|
|
|
<PageHero
|
|
badge={t.hero.badge}
|
|
title={<RichText text={t.hero.title} />}
|
|
description={<RichText text={t.hero.description} />}
|
|
>
|
|
<div className="grid grid-cols-1 items-stretch gap-6 lg:grid-cols-12">
|
|
<ImageCard
|
|
src="/images/probindo/about-team.jpg"
|
|
{...t.hero.image}
|
|
className="min-h-[360px] lg:col-span-8 lg:min-h-[440px]"
|
|
/>
|
|
<div className="grid grid-cols-2 gap-4 lg:col-span-4 lg:grid-cols-1">
|
|
{t.hero.stats.map((stat) => (
|
|
<StatCard key={stat.label} {...stat} />
|
|
))}
|
|
<Card className="col-span-2 flex items-center justify-between lg:col-span-1">
|
|
<div className="flex flex-col">
|
|
<span className="font-display text-on-surface text-3xl font-bold">
|
|
Official
|
|
</span>
|
|
<span className="text-primary font-mono text-xs font-semibold tracking-wider uppercase">
|
|
Odoo Partner
|
|
</span>
|
|
</div>
|
|
<IconTile icon="verified_user" size="md" />
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</PageHero>
|
|
|
|
<Section>
|
|
<div className="flex flex-col gap-12">
|
|
<SectionHeader
|
|
align="split"
|
|
eyebrow={t.history.eyebrow}
|
|
title={t.history.title}
|
|
description={t.history.description}
|
|
/>
|
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
|
|
{t.history.milestones.map((milestone) => (
|
|
<Card
|
|
key={milestone.year}
|
|
interactive
|
|
className={
|
|
milestone.featured
|
|
? 'border-primary-container/50 flex flex-col'
|
|
: 'flex flex-col'
|
|
}
|
|
>
|
|
{milestone.featured && (
|
|
<div className="from-primary-container via-primary to-primary-container absolute -top-px right-8 left-8 h-1 rounded-full bg-gradient-to-r" />
|
|
)}
|
|
<div className="mb-4 flex items-center justify-between">
|
|
<span className="border-outline-variant/40 bg-surface-container-high font-display text-primary rounded border px-3 py-1 text-lg font-extrabold tracking-wider">
|
|
{milestone.year}
|
|
</span>
|
|
<IconTile
|
|
icon={milestone.icon}
|
|
groupHover
|
|
/>
|
|
</div>
|
|
<h3 className="font-display text-on-surface mb-2 text-xl font-semibold">
|
|
{milestone.title}
|
|
</h3>
|
|
<p className="text-on-surface-variant mb-4 text-sm leading-relaxed">
|
|
{milestone.description}
|
|
</p>
|
|
<div className="border-outline-variant/30 bg-surface-container-lowest text-on-surface-variant mt-auto flex items-center gap-2 rounded-lg border p-2.5 text-sm">
|
|
<Icon
|
|
name={milestone.note.icon}
|
|
className="text-primary text-base"
|
|
/>
|
|
{milestone.note.label}
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Section>
|
|
|
|
<Section id="visi-misi" tone="muted">
|
|
<div className="flex flex-col gap-12">
|
|
<SectionHeader
|
|
align="center"
|
|
eyebrow={t.visionMission.eyebrow}
|
|
title={t.visionMission.title}
|
|
description={t.visionMission.description}
|
|
/>
|
|
<div className="grid grid-cols-1 items-stretch gap-6 lg:grid-cols-2">
|
|
{t.visionMission.statements.map((statement) => (
|
|
<Card
|
|
key={statement.label}
|
|
padding="lg"
|
|
interactive
|
|
className="flex flex-col justify-between overflow-hidden lg:p-10"
|
|
>
|
|
<Glow className="-top-12 -right-12 h-40 w-40 blur-2xl" />
|
|
<div className="relative flex flex-col gap-4">
|
|
<div className="flex items-center justify-between gap-4">
|
|
<span className="border-primary/40 bg-primary-container/10 text-primary rounded-full border px-3 py-1 font-mono text-[11px] font-bold tracking-wider uppercase">
|
|
{statement.label}
|
|
</span>
|
|
<IconTile
|
|
icon={statement.icon}
|
|
size="md"
|
|
/>
|
|
</div>
|
|
<blockquote className="border-primary/60 font-display text-on-surface my-2 border-l-2 pl-4 text-lg leading-relaxed font-medium italic lg:text-xl">
|
|
“{statement.text}”
|
|
</blockquote>
|
|
</div>
|
|
<div className="border-outline-variant/30 text-on-surface-variant mt-4 flex items-center gap-2 border-t pt-6 text-sm">
|
|
<Icon
|
|
name={statement.footer.icon}
|
|
className="text-primary text-base"
|
|
/>
|
|
{statement.footer.label}
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Section>
|
|
|
|
<Section>
|
|
<div className="flex flex-col gap-12">
|
|
<SectionHeader
|
|
eyebrow={t.philosophy.eyebrow}
|
|
title={t.philosophy.title}
|
|
description={
|
|
<RichText text={t.philosophy.description} />
|
|
}
|
|
/>
|
|
<div className="grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-4">
|
|
{t.philosophy.pillars.map((pillar) => (
|
|
<FeatureCard key={pillar.title} {...pillar} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Section>
|
|
|
|
<Section tone="muted">
|
|
<div className="flex flex-col gap-12">
|
|
<SectionHeader
|
|
align="split"
|
|
eyebrow={t.industries.eyebrow}
|
|
title={t.industries.title}
|
|
aside={
|
|
<ButtonLink
|
|
href={clients()}
|
|
variant="ghost"
|
|
size="inline"
|
|
trailingIcon="arrow_forward"
|
|
>
|
|
{t.industries.link}
|
|
</ButtonLink>
|
|
}
|
|
/>
|
|
<div className="grid grid-cols-1 gap-5 md:grid-cols-3">
|
|
{t.industries.items.map((item) => {
|
|
const clientNames = clientsInSector(item.sector);
|
|
|
|
return (
|
|
<Card
|
|
key={item.sector}
|
|
interactive
|
|
className="flex flex-col gap-4"
|
|
>
|
|
<div className="flex items-center justify-between gap-3">
|
|
<IconTile
|
|
icon={item.icon}
|
|
size="md"
|
|
groupHover
|
|
/>
|
|
<span className="text-primary font-mono text-xs font-semibold">
|
|
{clientNames.length}{' '}
|
|
{t.industries.clients} ·{' '}
|
|
{
|
|
projectsBySector(item.sector)
|
|
.length
|
|
}{' '}
|
|
{t.industries.projects}
|
|
</span>
|
|
</div>
|
|
<h3 className="font-display text-on-surface text-xl font-bold">
|
|
{item.title}
|
|
</h3>
|
|
<p className="text-on-surface-variant text-sm leading-relaxed">
|
|
{item.description}
|
|
</p>
|
|
<div className="border-outline-variant/30 mt-auto border-t pt-4">
|
|
<span className="text-primary font-mono text-[11px] font-bold uppercase">
|
|
{t.industries.examples}
|
|
</span>
|
|
<ul className="text-on-surface mt-2 flex flex-col gap-1 text-sm">
|
|
{clientNames
|
|
.slice(0, 3)
|
|
.map((name) => (
|
|
<li
|
|
key={name}
|
|
className="flex items-start gap-1.5"
|
|
>
|
|
<Icon
|
|
name="check"
|
|
className="text-primary mt-0.5 text-base"
|
|
/>
|
|
{name}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</Card>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</Section>
|
|
|
|
<Section tone="raised" className="py-12 lg:py-12">
|
|
<Card className="flex flex-col items-center justify-between gap-6 lg:flex-row">
|
|
<div className="flex items-center gap-4">
|
|
<IconTile icon="verified_user" size="lg" />
|
|
<div className="flex flex-col">
|
|
<span className="font-display text-on-surface text-lg font-bold">
|
|
{t.legal.title}
|
|
</span>
|
|
<p className="text-on-surface-variant text-sm">
|
|
{t.legal.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex w-full shrink-0 items-center justify-end gap-6 lg:w-auto">
|
|
<div className="flex flex-col text-right">
|
|
<span className="text-primary font-mono text-[11px] font-bold uppercase">
|
|
{t.legal.officeLabel}
|
|
</span>
|
|
<span className="font-display text-on-surface text-lg font-semibold">
|
|
{t.legal.officeValue}
|
|
</span>
|
|
</div>
|
|
<div className="bg-outline-variant/60 hidden h-10 w-px sm:block" />
|
|
<div className="flex flex-col text-right">
|
|
<span className="text-primary font-mono text-[11px] font-bold uppercase">
|
|
{t.legal.standardLabel}
|
|
</span>
|
|
<span className="font-display text-on-surface text-lg font-semibold">
|
|
{t.legal.standardValue}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</Section>
|
|
|
|
<CtaBanner
|
|
badge={t.cta.badge}
|
|
title={t.cta.title}
|
|
description={t.cta.description}
|
|
actions={
|
|
<>
|
|
<ButtonLink href={consultationUrl} icon="send">
|
|
{t.cta.primary}
|
|
</ButtonLink>
|
|
<ButtonLink
|
|
href={services()}
|
|
variant="secondary"
|
|
icon="layers"
|
|
>
|
|
{t.cta.secondary}
|
|
</ButtonLink>
|
|
</>
|
|
}
|
|
/>
|
|
</>
|
|
);
|
|
}
|