Skip to content

Commit 75a0b26

Browse files
authored
Refactor: Improve hero page consistency (#132)
* chore: improve capitalization consistency * refactor: improve hero consistency * fix: type error * fix: broken e2e test
1 parent a26bf28 commit 75a0b26

File tree

18 files changed

+174
-226
lines changed

18 files changed

+174
-226
lines changed

app/[lang]/(hyperjump)/case-studies/page.tsx

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import Link from "next/link";
2+
import { Metadata } from "next";
3+
4+
import { Hero } from "@/app/components/hero";
5+
import { Button } from "@/components/ui/button";
6+
import { dynamicOpengraph } from "@/lib/default-metadata";
17
import {
28
supportedLanguages,
39
type SupportedLanguage
@@ -8,11 +14,8 @@ import {
814
caseStudyHeroDesc,
915
caseStudyHeroHeading
1016
} from "@/locales/.generated/server";
17+
1118
import { getCaseStudies } from "./data";
12-
import { Button } from "@/components/ui/button";
13-
import Link from "next/link";
14-
import { Metadata } from "next";
15-
import { dynamicOpengraph } from "@/lib/default-metadata";
1619

1720
export const generateStaticParams = async () => {
1821
return supportedLanguages.map((lang) => ({ lang }));
@@ -50,8 +53,11 @@ export default async function CaseStudiesPage({ params }: CaseStudyProps) {
5053

5154
return (
5255
<main className="bg-white">
53-
<Hero lang={lang} />
54-
<div className="xxl:max-w-7xl mx-auto flex w-full max-w-6xl flex-wrap items-center justify-center px-4 pb-6 text-center md:px-20 xl:px-0">
56+
<Hero
57+
title={caseStudyHeroHeading(lang)}
58+
subtitle={caseStudyHeroDesc(lang)}
59+
/>
60+
<div className="xxl:max-w-7xl mx-auto flex w-full max-w-6xl flex-wrap items-center justify-center px-4 py-6 text-center md:px-20 xl:px-0">
5561
<h3 className="text-hyperjump-black w-72 text-[28px] font-medium md:w-full md:text-[40px]">
5662
{caseStudyExplore(lang)}
5763
</h3>
@@ -61,26 +67,6 @@ export default async function CaseStudiesPage({ params }: CaseStudyProps) {
6167
);
6268
}
6369

64-
function Hero({ lang }: { lang: SupportedLanguage }) {
65-
return (
66-
<section
67-
id="hero"
68-
className="bg-services-hero text-hyperjump-black relative h-[451px] w-full px-4 text-center">
69-
<div className="mx-auto flex h-full max-w-3xl flex-col items-center justify-center pt-12">
70-
<div
71-
className="text-hyperjump-black mb-4 text-3xl font-medium sm:text-4xl md:text-[40px]"
72-
dangerouslySetInnerHTML={{
73-
__html: caseStudyHeroHeading(lang)
74-
}}
75-
/>
76-
<p className="text-hyperjump-gray text-base sm:text-lg">
77-
{caseStudyHeroDesc(lang)}
78-
</p>
79-
</div>
80-
</section>
81-
);
82-
}
83-
8470
function CaseStudies({ lang }: { lang: SupportedLanguage }) {
8571
return (
8672
<section className="bg-white pt-5 pb-10">
Lines changed: 23 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import type { Metadata } from "next";
2+
3+
import GridItemsContainer, { GridItems } from "@/app/components/grid-items";
4+
import { Hero } from "@/app/components/hero";
5+
import { dynamicOpengraph } from "@/lib/default-metadata";
16
import {
27
supportedLanguages,
38
type SupportedLanguage
@@ -6,26 +11,24 @@ import {
611
productsHeroDesc,
712
productsHeroHeading
813
} from "@/locales/.generated/server";
9-
import { Metadata } from "next";
10-
import { dynamicOpengraph } from "@/lib/default-metadata";
11-
import GridItemsContainer, { GridItems } from "@/app/components/grid-items";
14+
1215
import { getCommercialProduct, getOpenSource } from "./data";
1316

1417
export const generateStaticParams = async () => {
1518
return supportedLanguages.map((lang) => ({ lang }));
1619
};
1720

18-
type productsProps = {
21+
type ProductsProps = {
1922
params: Promise<{ lang: SupportedLanguage }>;
2023
};
2124

2225
export async function generateMetadata({
2326
params
24-
}: productsProps): Promise<Metadata> {
27+
}: ProductsProps): Promise<Metadata> {
2528
const { lang } = await params;
2629

2730
const meta = {
28-
title: `Our Products - ${productsHeroHeading(lang)}`,
31+
title: productsHeroHeading(lang),
2932
description: productsHeroDesc(lang),
3033
alternates: {
3134
canonical: `https://hyperjump.tech/${lang}/products`,
@@ -42,66 +45,25 @@ export async function generateMetadata({
4245
return dynamicOpengraph(meta);
4346
}
4447

45-
export default async function productsPage({ params }: productsProps) {
48+
export default async function productsPage({ params }: ProductsProps) {
4649
const { lang } = await params;
4750

4851
return (
4952
<main className="bg-white">
50-
<Hero lang={lang} />
51-
<div className="xxl:max-w-7xl mx-auto -mt-10 flex w-full max-w-6xl flex-wrap items-center justify-center px-2 pb-6 md:px-20 xl:px-0">
52-
<ProductCommercial lang={lang} />
53-
<OpenSourceProducts lang={lang} />
53+
<Hero
54+
subtitle={productsHeroDesc(lang)}
55+
title={productsHeroHeading(lang)}
56+
/>
57+
<div className="xxl:max-w-7xl mx-auto -mt-10 flex w-full max-w-6xl flex-wrap items-center justify-center px-2 py-6 md:-mt-24 md:px-20 xl:px-0">
58+
<GridItemsContainer id="commercial-product">
59+
<GridItems
60+
items={[...getCommercialProduct(lang), ...getOpenSource(lang)]}
61+
columns={{ base: 1, sm: 2, lg: 3 }}
62+
cardClassName="rounded"
63+
lang={lang}
64+
/>
65+
</GridItemsContainer>
5466
</div>
5567
</main>
5668
);
5769
}
58-
59-
function Hero({ lang }: { lang: SupportedLanguage }) {
60-
return (
61-
<section
62-
id="hero"
63-
className="bg-services-hero text-hyperjump-black relative h-[415px] w-full px-4 text-center">
64-
<div className="mx-auto flex h-full max-w-3xl flex-col items-center justify-center pt-12">
65-
<h1
66-
className="text-hyperjump-black mb-4 text-3xl font-medium sm:text-4xl md:text-[40px]"
67-
dangerouslySetInnerHTML={{
68-
__html: productsHeroHeading(lang)
69-
}}
70-
/>
71-
<p className="text-hyperjump-gray text-base sm:text-lg">
72-
{productsHeroDesc(lang)}
73-
</p>
74-
</div>
75-
</section>
76-
);
77-
}
78-
79-
function ProductCommercial({ lang }: { lang: SupportedLanguage }) {
80-
const projects = getCommercialProduct(lang);
81-
82-
return (
83-
<GridItemsContainer id="commercial-product">
84-
<GridItems
85-
items={projects}
86-
columns={{ base: 1, sm: 2, lg: 3 }}
87-
cardClassName="rounded"
88-
lang={lang}
89-
/>
90-
</GridItemsContainer>
91-
);
92-
}
93-
94-
function OpenSourceProducts({ lang }: { lang: SupportedLanguage }) {
95-
const projects = getOpenSource(lang);
96-
97-
return (
98-
<GridItemsContainer id="open-source">
99-
<GridItems
100-
items={projects}
101-
columns={{ base: 1, sm: 2, lg: 3 }}
102-
cardClassName="rounded"
103-
lang={lang}
104-
/>
105-
</GridItemsContainer>
106-
);
107-
}

app/[lang]/(hyperjump)/services/page.tsx

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import type { Metadata } from "next";
12
import Link from "next/link";
23
import Image from "next/image";
34

5+
import { Hero } from "@/app/components/hero";
46
import { Button } from "@/components/ui/button";
57
import data from "@/data.json";
8+
import { dynamicOpengraph } from "@/lib/default-metadata";
69
import { cn } from "@/lib/utils";
710
import {
811
supportedLanguages,
@@ -19,8 +22,6 @@ import {
1922

2023
import { Clients } from "../components/clients";
2124
import { serviceBySlug, services, ServiceSlug } from "../data";
22-
import { Metadata } from "next";
23-
import { dynamicOpengraph } from "@/lib/default-metadata";
2425

2526
export async function generateMetadata(props: {
2627
params: Promise<{ lang: SupportedLanguage }>;
@@ -58,7 +59,10 @@ export default async function Services({ params }: ServicesProps) {
5859

5960
return (
6061
<main className="bg-white">
61-
<Hero lang={lang} />
62+
<Hero
63+
subtitle={servicesHeroDesc(lang)}
64+
title={servicesHeroHeading(lang)}
65+
/>
6266
<div className="xxl:max-w-7xl mx-auto flex w-full max-w-6xl flex-wrap items-center justify-center px-4 pb-15 text-center md:px-20 xl:px-0">
6367
<section className="space-y-16">
6468
{services(lang).map(({ slug }, index) => (
@@ -112,7 +116,7 @@ function Service({ lang, isReverseImagePosition = false, slug }: ServiceProps) {
112116
return (
113117
<div
114118
className={cn(
115-
"flex flex-col items-center gap-6 border-b border-gray-200 pb-7 md:flex-row md:pb-14",
119+
"flex flex-col items-start gap-6 border-b border-gray-200 pb-7 md:flex-row md:pb-14",
116120
isReverseImagePosition && "md:flex-row-reverse"
117121
)}>
118122
<div className="relative w-full xl:w-1/2">
@@ -174,18 +178,3 @@ function Service({ lang, isReverseImagePosition = false, slug }: ServiceProps) {
174178
</div>
175179
);
176180
}
177-
178-
function Hero({ lang }: { lang: SupportedLanguage }) {
179-
return (
180-
<section
181-
id="hero"
182-
className="bg-services-hero text-hyperjump-black relative h-[415px] w-full px-4 text-center">
183-
<div className="mx-auto flex h-full max-w-3xl flex-col items-center justify-center pt-16">
184-
<h1 className="text-hyperjump-black mb-4 text-4xl font-medium md:text-[40px]">
185-
{servicesHeroHeading(lang)}
186-
</h1>
187-
<p className="text-hyperjump-gray text-lg">{servicesHeroDesc(lang)}</p>
188-
</div>
189-
</section>
190-
);
191-
}

app/components/hero.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
type HeroProps = { subtitle: string; title: string };
2+
3+
export function Hero({ subtitle, title }: HeroProps) {
4+
return (
5+
<section
6+
id="hero"
7+
className="bg-services-hero text-hyperjump-black relative w-full px-4 py-10 text-center md:py-16">
8+
<div className="mx-auto flex h-full max-w-3xl flex-col items-center justify-center pt-12">
9+
<div
10+
className="text-hyperjump-black mb-4 text-3xl font-medium sm:text-4xl md:text-[40px]"
11+
dangerouslySetInnerHTML={{
12+
__html: title
13+
}}
14+
/>
15+
<p className="text-hyperjump-gray text-base sm:text-lg">{subtitle}</p>
16+
</div>
17+
</section>
18+
);
19+
}

app/llms.txt/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ We offer expert technology solutions to help businesses scale, enhance efficienc
3030
3131
Discover how we successfully transform challenges into opportunities with real-world solutions that drive lasting impact and business growth.
3232
33-
- [Transforming a Fisheries Tech Team into a Scalable Product Engine](https://hyperjump.tech/case-studies/erp-fisheries): A junior but passionate tech team. Zero products in production. High impact at stake. We embedded deeply with their team to introduce structure, build confidence, and ship a functional MVP within 3 months. Through rigorous agile practices and full-system rollouts, we helped evolve a fragile tech org into a reliable product engine.
34-
- [Elevating a Media-Tech Engineering Team from Feature Factory to Innovation Powerhouse](https://hyperjump.tech/case-studies/ctoaas-media): When rapid growth outpaced engineering maturity, this team needed more than features, they needed transformation. We restructured their agile practices, automated DevOps, established measurable KPIs, and helped them move from task execution to true product ownership and experimentation.
33+
- [Transforming a fisheries tech team into a scalable product engine](https://hyperjump.tech/case-studies/erp-fisheries): A junior but passionate tech team. Zero products in production. High impact at stake. We embedded deeply with their team to introduce structure, build confidence, and ship a functional MVP within 3 months. Through rigorous agile practices and full-system rollouts, we helped evolve a fragile tech org into a reliable product engine.
34+
- [Elevating a media-tech engineering team from feature factory to innovation powerhouse](https://hyperjump.tech/case-studies/ctoaas-media): When rapid growth outpaced engineering maturity, this team needed more than features, they needed transformation. We restructured their agile practices, automated DevOps, established measurable KPIs, and helped them move from task execution to true product ownership and experimentation.
3535
3636
## Open source product
3737

e2e/homepage.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ test.describe("Homepage", () => {
114114
await expect(caseHeading).toBeVisible();
115115
await expect(page.getByText("Discover how we successfully")).toBeVisible();
116116

117-
await expect(page.getByText("Transforming a Fisheries Tech")).toBeVisible();
118-
await expect(page.getByText("Elevating a Media-Tech")).toBeVisible();
117+
await expect(page.getByText("Transforming a fisheries tech")).toBeVisible();
118+
await expect(page.getByText("Elevating a media-tech")).toBeVisible();
119119
});
120120

121121
test("FAQ Section: should toggle FAQ items correctly on click", async ({

locales/en/ai.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"desc": "Your vision. Our AI solutions. Unstoppable results"
55
},
66
"description": "Design, develop, and deploy purpose-built AI agents that save time, cut costs, and scale operations. Without technical overwhelm.",
7-
"bestFor": ["Enterprises", "Startups", "Process automation"],
7+
"bestFor": ["Enterprises", "startups", "process automation"],
88
"what_is": {
99
"desc": "Build smart, autonomous agents tailored to your domain — without hiring a full AI team.",
1010
"highlight": "Not every business needs to build full AI infrastructure from scratch. With <span class=\"font-bold\">Inference AI</span>, you gain access to design, build, and maintain AI agents that reason, act, and adapt — all without needing an in-house AI team."
@@ -20,7 +20,7 @@
2020
"what_we_deliver": {
2121
"desc": "We partner with your team to automate and build AI agents that scale with your business. From planning to post-implementation, we deliver hands-on support every step of the way.",
2222
"card_0": {
23-
"title": "Integration & Orchestration",
23+
"title": "Integration & orchestration",
2424
"text": "Plug the agent into your systems:",
2525
"items": {
2626
"0": "Connect to APIs, databases, internal tools",
@@ -29,7 +29,7 @@
2929
}
3030
},
3131
"card_1": {
32-
"title": "Training, Fine-Tuning & Prompt Engineering",
32+
"title": "Training, fine-Tuning & prompt Engineering",
3333
"text": "We tailor the agent's behavior to your domain:",
3434
"items": {
3535
"0": "Fine-tune models or use adapters",
@@ -38,7 +38,7 @@
3838
}
3939
},
4040
"card_2": {
41-
"title": "Safety, Monitoring & Guardrails",
41+
"title": "Safety, monitoring & guardrails",
4242
"text": "Ensure reliable, safe operation:",
4343
"items": {
4444
"0": "Input validation, fallback logic, human-in-the-loop",
@@ -47,7 +47,7 @@
4747
}
4848
},
4949
"card_3": {
50-
"title": "Deployment & Operations",
50+
"title": "Deployment & operations",
5151
"text": "We make sure your ERP delivers value:",
5252
"items": {
5353
"0": "Stabilization support",
@@ -84,10 +84,10 @@
8484
"what_you_get": {
8585
"desc": "We deliver a working custom AI agent tailored to your domain that adapts to your workflow and grows with your business.",
8686
"items": {
87-
"0": "Integration & Orchestration",
88-
"1": "Training, Fine-Tuning & Prompt Engineering",
89-
"2": "Safety, Monitoring & Guardrails",
90-
"3": "Deployment & Maintenance"
87+
"0": "Integration & orchestration",
88+
"1": "Training, fine-Tuning & prompt Engineering",
89+
"2": "Safety, monitoring & guardrails",
90+
"3": "Deployment & maintenance"
9191
}
9292
},
9393
"why_us": {

locales/en/case-study.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
{
22
"hero": {
3-
"heading": "From Chaos to Clarity: Real Stories of <span class=\"text-[#3276F5]\">Engineering Transformation</span>",
3+
"heading": "From chaos to clarity: real stories of <span class=\"text-[#3276F5]\">engineering transformation</span>",
44
"desc": "At Hyperjump, we don't just improve engineering teams. We help reshape how tech organizations think, operate, and grow. Explore how we've partnered with fast-growing companies to unlock their full potential through hands-on leadership, scalable systems, and deep technical coaching."
55
},
6-
"title": "From Chaos to Clarity: Real Stories of Engineering Transformation",
6+
"title": "From chaos to clarity: real stories of engineering transformation",
77
"cta": {
88
"heading": "Not sure where to start?",
99
"desc": "Let's talk about your tech goals and point you in the right direction.",
1010
"label": "Talk to us"
1111
},
12-
"explore": "Explore Our Case Studies",
13-
"button": "Read Case Study",
14-
"more": "More Case Studies",
12+
"explore": "Explore our case studies",
13+
"button": "Read case study",
14+
"more": "More case studies",
1515
"erp_fisheries": {
16-
"title": "Transforming a Fisheries Tech Team into a Scalable Product Engine",
16+
"title": "Transforming a fisheries tech team into a scalable product engine",
1717
"desc": "A junior but passionate tech team. Zero products in production. High impact at stake. We embedded deeply with their team to introduce structure, build confidence, and ship a functional MVP within 3 months. Through rigorous agile practices and full-system rollouts, we helped evolve a fragile tech org into a reliable product engine.",
1818
"category": "CTO as a Service"
1919
},
2020
"ctoaas_media": {
21-
"title": "Elevating a Media-Tech Engineering Team from Feature Factory to Innovation Powerhouse",
21+
"title": "Elevating a media-tech engineering team from feature factory to innovation powerhouse",
2222
"desc": "When rapid growth outpaced engineering maturity, this team needed more than features, they needed transformation. We restructured their agile practices, automated DevOps, established measurable KPIs, and helped them move from task execution to true product ownership and experimentation.",
2323
"category": "CTO as a Service"
2424
}

0 commit comments

Comments
 (0)