Skip to content

Commit cc8573e

Browse files
authored
Feat: Adding Services page (#18)
* Feat: Adding Services page * Fix conflict
1 parent 1d54982 commit cc8573e

28 files changed

+7019
-154
lines changed

app/(main)/[lang]/data.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ import {
3636

3737
export const mainNav = (lang: SupportedLanguage) => {
3838
const data = [
39-
{ label: mainNavItems0Label(lang), href: "#services" },
40-
{ label: mainNavItems1Label(lang), href: "#case-studies" },
41-
{ label: mainNavItems2Label(lang), href: "#open-source" },
42-
{ label: mainNavItems3Label(lang), href: "#faqs" }
39+
{ label: mainNavItems0Label(lang), href: "/services" },
40+
{ label: mainNavItems1Label(lang), href: "/#case-studies" },
41+
{ label: mainNavItems2Label(lang), href: "/#open-source" },
42+
{ label: mainNavItems3Label(lang), href: "/#faqs" }
4343
];
4444
return data;
4545
};

app/(main)/[lang]/home.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,7 @@ function Services({ lang }: { lang: SupportedLanguage }) {
9292
cardClassName="rounded"
9393
lang={lang}
9494
/>
95-
<GridItemsMoreButton
96-
text={mainCtaLabel(lang)}
97-
href={link}
98-
gaEvent={{
99-
event: gaEventName,
100-
category: "engagement",
101-
label: "Service CTA"
102-
}}
103-
/>
95+
<GridItemsMoreButton text="View More" href="/services" />
10496
</GridItemsContainer>
10597
);
10698
}

app/(main)/[lang]/language-picker.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "@/locales/.generated/types";
88
import Link from "next/link";
99

10-
export default function LanguagePicker({
10+
export function LanguagePicker({
1111
lang,
1212
isOpen
1313
}: {
@@ -41,3 +41,38 @@ export default function LanguagePicker({
4141
</div>
4242
);
4343
}
44+
45+
export function LanguagePickerServices({
46+
lang,
47+
isOpen
48+
}: {
49+
lang: SupportedLanguage;
50+
isOpen?: boolean;
51+
}) {
52+
return (
53+
<div className="flex gap-2">
54+
{supportedLanguages.map((l) => {
55+
const isActive = lang === l;
56+
57+
return (
58+
<Link
59+
scroll={false}
60+
key={l}
61+
href={`/services/${l}`}
62+
className={cn(
63+
"flex h-8 w-8 items-center justify-center rounded-md text-sm font-medium transition-colors",
64+
isActive
65+
? isOpen
66+
? "bg-hyperjump-black"
67+
: "bg-hyperjump-blue text-white"
68+
: isOpen
69+
? "text-hyperjump-black"
70+
: "text-hyperjump-black group-data-[scroll='true']:text-hyperjump-black"
71+
)}>
72+
{l.toUpperCase()}
73+
</Link>
74+
);
75+
})}
76+
</div>
77+
);
78+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
"use client";
2+
3+
import { SupportedLanguage } from "@/locales/.generated/types";
4+
import {
5+
servicesCtoaasTitle,
6+
servicesHeading,
7+
servicesCtoaasText,
8+
servicesCtoaasDesc,
9+
servicesCtoaasItems0,
10+
servicesCtoaasItems1,
11+
servicesCtoaasItems2,
12+
servicesSaasTitle,
13+
servicesSaasText,
14+
servicesSaasDesc,
15+
servicesSaasItems0,
16+
servicesSaasItems1,
17+
servicesSaasItems2,
18+
servicesTechDueDiligenceTitle,
19+
servicesTechDueDiligenceText,
20+
servicesTechDueDiligenceDesc,
21+
servicesTechDueDiligenceItems0,
22+
servicesTechDueDiligenceItems1,
23+
servicesTechDueDiligenceItems2,
24+
servicesErpTitle,
25+
servicesErpText,
26+
servicesErpDesc,
27+
servicesErpItems0,
28+
servicesErpItems1,
29+
servicesErpItems2,
30+
servicesCtaLabel,
31+
servicesCtaHeading,
32+
servicesCtaDesc,
33+
servicesPartnersHeading,
34+
servicesPartnersDesc
35+
} from "@/locales/.generated/server";
36+
import { ServiceCard } from "../components/service-card";
37+
import { Button } from "@/components/ui/button";
38+
import Link from "next/link";
39+
import Image from "next/image";
40+
41+
export default function Home({ lang }: { lang: SupportedLanguage }) {
42+
return (
43+
<main className="xxl:max-w-7xl mx-auto flex w-full max-w-6xl flex-wrap items-center justify-center px-4 py-12 text-center md:px-20 xl:px-0">
44+
<h3 className="mb-14 text-[34px] font-medium text-hyperjump-black md:text-[40px]">
45+
{servicesHeading(lang)}
46+
</h3>
47+
<section className="space-y-16">
48+
<ServiceCard
49+
title={servicesCtoaasTitle(lang)}
50+
text={servicesCtoaasText(lang)}
51+
desc={servicesCtoaasDesc(lang)}
52+
items={[
53+
servicesCtoaasItems0(lang),
54+
servicesCtoaasItems1(lang),
55+
servicesCtoaasItems2(lang)
56+
]}
57+
image="/images/services/ctoaas.webp"
58+
icon="/images/services/ctoaas-icon.svg"
59+
/>
60+
61+
<ServiceCard
62+
title={servicesSaasTitle(lang)}
63+
text={servicesSaasText(lang)}
64+
desc={servicesSaasDesc(lang)}
65+
items={[
66+
servicesSaasItems0(lang),
67+
servicesSaasItems1(lang),
68+
servicesSaasItems2(lang)
69+
]}
70+
image="/images/services/saas.webp"
71+
icon="/images/services/saas-icon.svg"
72+
reverse
73+
/>
74+
75+
<ServiceCard
76+
title={servicesTechDueDiligenceTitle(lang)}
77+
text={servicesTechDueDiligenceText(lang)}
78+
desc={servicesTechDueDiligenceDesc(lang)}
79+
items={[
80+
servicesTechDueDiligenceItems0(lang),
81+
servicesTechDueDiligenceItems1(lang),
82+
servicesTechDueDiligenceItems2(lang)
83+
]}
84+
image="/images/services/tech-due-diligence.webp"
85+
icon="/images/services/tech-due-diligence-icon.svg"
86+
/>
87+
88+
<ServiceCard
89+
title={servicesErpTitle(lang)}
90+
text={servicesErpText(lang)}
91+
desc={servicesErpDesc(lang)}
92+
items={[
93+
servicesErpItems0(lang),
94+
servicesErpItems1(lang),
95+
servicesErpItems2(lang)
96+
]}
97+
image="/images/services/erp.webp"
98+
icon="/images/services/erp-icon.svg"
99+
withBorder={false}
100+
reverse
101+
/>
102+
</section>
103+
104+
<section className="relative mb-10 mt-20 w-full">
105+
<h3 className="mb-4 text-[28px] font-medium text-hyperjump-black md:text-4xl">
106+
{servicesPartnersHeading(lang)}
107+
</h3>
108+
<p className="mx-auto mb-8 w-full max-w-3xl text-center text-base text-hyperjump-gray md:text-lg">
109+
{servicesPartnersDesc(lang)}
110+
</p>
111+
112+
<div className="flex flex-wrap items-center justify-center gap-8">
113+
{[
114+
{
115+
imageUrl: "/images/clients/services/my-republic.svg",
116+
name: "My Republic"
117+
},
118+
{ imageUrl: "/images/clients/services/btn.svg", name: "BTN" },
119+
{ imageUrl: "/images/clients/services/aruna.svg", name: "Aruna" }
120+
].map(({ imageUrl, name }) => (
121+
<Image
122+
key={name}
123+
src={imageUrl}
124+
alt={name}
125+
height={36}
126+
width={120}
127+
className="h-6 w-auto object-contain sm:h-7"
128+
priority
129+
/>
130+
))}
131+
</div>
132+
</section>
133+
134+
<section className="relative mt-10 w-full max-w-7xl overflow-hidden rounded-lg">
135+
<div className="absolute inset-0 z-0">
136+
<Image
137+
src="/images/swatch.svg"
138+
alt="CTA Background"
139+
width={1440}
140+
height={308}
141+
className="pointer-events-none h-full select-none object-cover"
142+
style={{
143+
background:
144+
"linear-gradient(134.7deg, #5954DA 3.43%, #0B0B0D 48.93%)"
145+
}}
146+
/>
147+
</div>
148+
<div className="relative flex flex-col items-center justify-center px-6 py-11 text-center">
149+
<h4 className="mb-3 text-3xl font-medium text-white md:text-4xl">
150+
{servicesCtaHeading(lang)}
151+
</h4>
152+
<p className="mb-8 text-lg text-white">{servicesCtaDesc(lang)}</p>
153+
154+
<Button
155+
asChild
156+
size="lg"
157+
className="bg-hyperjump-blue text-base font-semibold text-white hover:bg-hyperjump-blue/90">
158+
<Link href="#" target="_blank" rel="noreferrer noopener">
159+
{servicesCtaLabel(lang)}
160+
</Link>
161+
</Button>
162+
</div>
163+
</section>
164+
</main>
165+
);
166+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import ScrollObserver from "@/app/components/scroll-observer";
2+
import { SupportedLanguage } from "@/locales/.generated/types";
3+
import Hero from "../components/hero";
4+
import Nav from "@/app/components/nav";
5+
import Footer from "@/app/components/footer";
6+
7+
export default function ServicesLangLayout({
8+
children,
9+
params
10+
}: {
11+
children: React.ReactNode;
12+
params: { lang: string };
13+
}) {
14+
return (
15+
<div className="bg-white">
16+
<ScrollObserver />
17+
<Nav
18+
type="services"
19+
className="xxl:max-w-7xl max-w-6xl"
20+
lang={params.lang as SupportedLanguage}
21+
/>
22+
<Hero lang={params.lang as SupportedLanguage} />
23+
{children}
24+
<Footer lang={params.lang as SupportedLanguage} />
25+
</div>
26+
);
27+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { SupportedLanguage } from "@/locales/.generated/types";
2+
import Home from "./home";
3+
4+
export const generateStaticParams = async () => {
5+
return [{ lang: "en" }, { lang: "id" }];
6+
};
7+
8+
export default function ServicesPage({
9+
params
10+
}: {
11+
params: { lang: SupportedLanguage };
12+
}) {
13+
return <Home lang={params.lang} />;
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"use client";
2+
3+
import { SupportedLanguage } from "@/locales/.generated/types";
4+
import {
5+
servicesHeroHeading,
6+
servicesHeroDesc
7+
} from "@/locales/.generated/server";
8+
9+
export default function Hero({ lang }: { lang: SupportedLanguage }) {
10+
return (
11+
<section className="relative h-[415px] w-full bg-services-hero px-4 text-center text-hyperjump-black">
12+
<div className="mx-auto flex h-full max-w-3xl flex-col items-center justify-center pt-16">
13+
<h1 className="mb-4 text-4xl font-medium text-hyperjump-black md:text-[40px]">
14+
{servicesHeroHeading(lang)}
15+
</h1>
16+
<p className="text-lg text-hyperjump-gray">{servicesHeroDesc(lang)}</p>
17+
</div>
18+
</section>
19+
);
20+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import Image from "next/image";
2+
import { Button } from "@/components/ui/button";
3+
import Link from "next/link";
4+
import { servicesSeeMore } from "@/locales/.generated/server";
5+
import { SupportedLanguage } from "@/locales/.generated/types";
6+
7+
interface ServiceCardProps {
8+
title: string;
9+
text: string;
10+
desc: string;
11+
items: string[];
12+
image: string;
13+
icon: string;
14+
url?: string;
15+
reverse?: boolean;
16+
withBorder?: boolean;
17+
}
18+
19+
export function ServiceCard(
20+
{
21+
title,
22+
text,
23+
desc,
24+
items,
25+
image,
26+
icon,
27+
reverse,
28+
url = "#",
29+
withBorder = true
30+
}: ServiceCardProps,
31+
{ lang }: { lang: SupportedLanguage }
32+
) {
33+
return (
34+
<div
35+
className={`mb-14 flex flex-col gap-6 ${
36+
withBorder ? "border-b border-gray-200 pb-14" : ""
37+
} md:flex-row ${reverse ? "md:flex-row-reverse" : ""} items-center`}>
38+
<div className="relative w-full md:w-1/2">
39+
<Image
40+
src={image}
41+
alt={title}
42+
className="h-auto w-full rounded-[20px]"
43+
width={660}
44+
height={400}
45+
/>
46+
<div className="absolute -bottom-3 left-1 rounded-md">
47+
<Image src={icon} alt={`${title} icon`} width={80} height={80} />
48+
</div>
49+
</div>
50+
51+
<div className="w-full md:w-1/2">
52+
<div className="text-left">
53+
<h3 className="mb-4 text-[28px] font-medium text-hyperjump-black md:text-4xl">
54+
{title}
55+
</h3>
56+
<p className="mb-4 text-lg text-gray-700">{text}</p>
57+
<p className="mb-6 inline-block border-b-2 border-gray-200 text-lg text-gray-700">
58+
{desc}
59+
</p>
60+
</div>
61+
62+
<ul className="mb-8 list-none text-base text-gray-700 md:text-lg">
63+
{items.map((point, i) => (
64+
<li key={i} className="mb-4 flex items-start gap-2">
65+
<Image
66+
src="/images/checklist.svg"
67+
alt="icon"
68+
width={24}
69+
height={24}
70+
/>
71+
<span>{point}</span>
72+
</li>
73+
))}
74+
</ul>
75+
<div className="md:text-left">
76+
<Button
77+
asChild
78+
size="lg"
79+
className="w-full bg-hyperjump-blue text-base font-semibold text-white hover:bg-hyperjump-blue/90 md:w-44">
80+
<Link href={url}>{servicesSeeMore(lang)}</Link>
81+
</Button>
82+
</div>
83+
</div>
84+
</div>
85+
);
86+
}

0 commit comments

Comments
 (0)