Skip to content

Commit 50177d6

Browse files
author
raineer
committed
seo addons
1 parent da0b2f4 commit 50177d6

9 files changed

Lines changed: 653 additions & 501 deletions

File tree

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Metadata } from "next";
2+
13
import Footer from "../_components/MarketingFooter";
24
import Navigation from "../_components/MarketingNavigation";
35
import SideNavMenu from "../_components/MarketingSidenavMenu";
@@ -12,27 +14,45 @@ import PartnerReactFlow from "./_components/AiIntegrationPartnerReactFlow";
1214
import AISolutions from "./_components/AiIntegrationSolutions";
1315
import UnparallelDigitalSuccess from "./_components/AiIntegrationUnparallelDigitalSuccess";
1416

17+
export const metadata: Metadata = {
18+
title: "AI Integration Services — Codebility",
19+
description: "Integrate AI into your business with Codebility. We build custom AI solutions, automation pipelines, and intelligent web applications.",
20+
alternates: { canonical: "https://www.codebility.tech/ai-integration" },
21+
openGraph: {
22+
title: "AI Integration Services | Codebility",
23+
description: "Custom AI solutions and automation built by Codebility developers.",
24+
url: "https://www.codebility.tech/ai-integration",
25+
images: [{ url: "/og-image.jpg", width: 1200, height: 630, alt: "AI Integration by Codebility" }],
26+
},
27+
twitter: {
28+
card: "summary_large_image",
29+
title: "AI Integration Services | Codebility",
30+
description: "Custom AI solutions and automation built by Codebility developers.",
31+
images: ["/og-image.jpg"],
32+
},
33+
};
34+
1535
export const dynamic = "force-dynamic";
1636
export const revalidate = 0;
1737

1838
const AiIntegration = () => {
19-
return (
20-
<div className="bg-black-400 relative mx-auto flex min-h-screen flex-col gap-10 text-white">
21-
<HeroBackground />
22-
<Navigation />
23-
<SideNavMenu />
24-
<AISolutions />
25-
<UnparallelDigitalSuccess />
26-
<LatestTech />
27-
<MobileAppServices />
28-
<DevelopmentProcess />
29-
<DevelopmentProcessReactFLow />
30-
<Partner />
31-
<PartnerReactFlow />
32-
<NextStep />
33-
<Footer />
34-
</div>
35-
);
39+
return (
40+
<div className="bg-black-400 relative mx-auto flex min-h-screen flex-col gap-10 text-white">
41+
<HeroBackground />
42+
<Navigation />
43+
<SideNavMenu />
44+
<AISolutions />
45+
<UnparallelDigitalSuccess />
46+
<LatestTech />
47+
<MobileAppServices />
48+
<DevelopmentProcess />
49+
<DevelopmentProcessReactFLow />
50+
<Partner />
51+
<PartnerReactFlow />
52+
<NextStep />
53+
<Footer />
54+
</div>
55+
);
3656
};
3757

38-
export default AiIntegration;
58+
export default AiIntegration;
Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Metadata } from "next";
12
import React from "react";
23

34
import Container from "../_components/MarketingContainer";
@@ -6,42 +7,55 @@ import Navigation from "../_components/MarketingNavigation";
67
import SideNavMenu from "../_components/MarketingSidenavMenu";
78
import BookACallCalendlyWidgetContainer from "./_components/BookACallCalendlyWidgetContainer";
89

10+
export const metadata: Metadata = {
11+
title: "Book a Call — Schedule a Meeting with Codebility",
12+
description: "Schedule a free consultation with Codebility. Let us understand your project and propose the right development team for you.",
13+
alternates: { canonical: "https://www.codebility.tech/bookacall" },
14+
openGraph: {
15+
title: "Book a Call | Codebility",
16+
description: "Schedule a free consultation with the Codebility team.",
17+
url: "https://www.codebility.tech/bookacall",
18+
images: [{ url: "/og-image.jpg", width: 1200, height: 630, alt: "Book a Call with Codebility" }],
19+
},
20+
twitter: {
21+
card: "summary_large_image",
22+
title: "Book a Call | Codebility",
23+
description: "Schedule a free consultation with the Codebility team.",
24+
images: ["/og-image.jpg"],
25+
},
26+
};
27+
928
export const dynamic = "force-dynamic";
1029
export const revalidate = 0;
1130

1231
export default function BookCallPage() {
13-
return (
14-
<div
15-
className={`bg-black-400 relative flex min-h-screen w-full flex-col items-center overflow-x-hidden overflow-y-hidden`}
16-
>
17-
<Navigation />
18-
<SideNavMenu />
19-
20-
<Container className=" relative z-10 flex w-full max-w-screen-sm flex-col gap-6 pt-10 text-white lg:mx-60 lg:max-w-screen-lg lg:flex-row lg:justify-between lg:gap-10 lg:pt-32">
21-
<div className="flex w-full flex-col gap-2 text-center lg:pt-64 lg:text-left">
22-
<h2 className="text-3xl font-bold uppercase md:text-5xl">
23-
Book a meeting!
24-
</h2>
25-
<p className="text-md lg:text-lg"></p> Schedule a meeting with our
26-
experts
27-
<p> to discuss your needs and find tailored solutions.</p>
32+
return (
33+
<div className="bg-black-400 relative flex min-h-screen w-full flex-col items-center overflow-x-hidden overflow-y-hidden">
34+
<Navigation />
35+
<SideNavMenu />
36+
<Container className="relative z-10 flex w-full max-w-screen-sm flex-col gap-6 pt-10 text-white lg:mx-60 lg:max-w-screen-lg lg:flex-row lg:justify-between lg:gap-10 lg:pt-32">
37+
<div className="flex w-full flex-col gap-2 text-center lg:pt-64 lg:text-left">
38+
<h2 className="text-3xl font-bold uppercase md:text-5xl">
39+
Book a meeting!
40+
</h2>
41+
<p className="text-md lg:text-lg"></p> Schedule a meeting with our
42+
experts
43+
<p> to discuss your needs and find tailored solutions.</p>
44+
</div>
45+
<BookACallCalendlyWidgetContainer />
46+
</Container>
47+
<div
48+
aria-hidden="true"
49+
className="pointer-events-none absolute left-1/2 top-1/4 -translate-x-1/2 -translate-y-1/2 transform overflow-hidden blur-3xl"
50+
>
51+
<div
52+
style={{
53+
clipPath: "polygon(0% 31.5%, 75.3% 19.5%, 100% 50%, 75.5% 80.5%, 0% 67.8%, 0% 50%)",
54+
}}
55+
className="relative aspect-[855/678] w-[40rem] bg-gradient-to-r from-customBlue-700 via-customBlue-800 to-customViolet-300 opacity-20 sm:w-[72.1875rem]"
56+
/>
57+
</div>
58+
<Footer />
2859
</div>
29-
30-
<BookACallCalendlyWidgetContainer />
31-
</Container>
32-
<div
33-
aria-hidden="true"
34-
className="pointer-events-none absolute left-1/2 top-1/4 -translate-x-1/2 -translate-y-1/2 transform overflow-hidden blur-3xl"
35-
>
36-
<div
37-
style={{
38-
clipPath:
39-
"polygon(0% 31.5%, 75.3% 19.5%, 100% 50%, 75.5% 80.5%, 0% 67.8%, 0% 50%)",
40-
}}
41-
className="relative aspect-[855/678] w-[40rem] bg-gradient-to-r from-customBlue-700 via-customBlue-800 to-customViolet-300 opacity-20 sm:w-[72.1875rem]"
42-
/>
43-
</div>
44-
<Footer />
45-
</div>
46-
);
47-
}
60+
);
61+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import {
5+
IconActivityLog,
6+
IconApplicant,
7+
IconHuman,
8+
} from "@/public/assets/svgs";
9+
10+
import InquiryForm from "./ContactInquiryInform";
11+
import ShortSurvey from "./ContactShortSurvey";
12+
import Appointment from "./ContactAppointment";
13+
14+
const steps = [
15+
{ label: "Inquiry Form", icon: <IconHuman /> },
16+
{ label: "Short Survey", icon: <IconApplicant /> },
17+
{ label: "Set an Appointment", icon: <IconActivityLog /> },
18+
];
19+
20+
export interface ContactFormData {
21+
// Step 1
22+
firstName: string;
23+
lastName: string;
24+
email: string;
25+
companyName: string;
26+
phoneNumber: string;
27+
industry: string;
28+
// Step 2
29+
serviceInterest: string;
30+
projectType: string;
31+
featuresNeeded: string;
32+
referralSource: string;
33+
interestLevel: number;
34+
otherRequirements: string;
35+
}
36+
37+
const ContactPage = () => {
38+
const [currentStep, setCurrentStep] = useState(0);
39+
const [formData, setFormData] = useState<ContactFormData>({
40+
firstName: "", lastName: "", email: "",
41+
companyName: "", phoneNumber: "", industry: "",
42+
serviceInterest: "", projectType: "", featuresNeeded: "",
43+
referralSource: "", interestLevel: 0, otherRequirements: "",
44+
});
45+
46+
const goNext = () => setCurrentStep((s) => Math.min(s + 1, steps.length - 1));
47+
const goBack = () => setCurrentStep((s) => Math.max(s - 1, 0));
48+
49+
const updateFormData = (data: Partial<ContactFormData>) =>
50+
setFormData((prev) => ({ ...prev, ...data }));
51+
52+
const progressWidth = `${(currentStep / (steps.length - 1)) * 100}%`;
53+
54+
return (
55+
<div className="min-h-screen w-full bg-[#030303] text-white">
56+
<div className="mx-auto flex max-w-xl flex-col items-center gap-8 px-5 py-10">
57+
58+
{/* Stepper */}
59+
<div className="relative w-full">
60+
{/* Connector: circle 1 → circle 2 */}
61+
<div
62+
className={`absolute top-5 h-[2px] transition-all duration-500 ${currentStep > 0 ? "bg-violet-600" : "bg-white/5"
63+
}`}
64+
style={{ left: "calc(16.666% + 20px)", right: "calc(33.333% + 20px)" }}
65+
/>
66+
{/* Connector: circle 2 → circle 3 */}
67+
<div
68+
className={`absolute top-5 h-[2px] transition-all duration-500 ${currentStep > 1 ? "bg-violet-600" : "bg-white/5"
69+
}`}
70+
style={{ left: "calc(50% + 20px)", right: "calc(16.666% + 20px)" }}
71+
/>
72+
73+
<div className="relative flex items-start">
74+
{steps.map((step, i) => {
75+
const isDone = i < currentStep;
76+
const isActive = i === currentStep;
77+
78+
return (
79+
<div key={i} className="relative z-10 flex flex-1 flex-col items-center gap-2">
80+
<div
81+
className={`flex h-10 w-10 items-center justify-center rounded-full border text-sm font-medium transition-all duration-300 ${isDone
82+
? "border-violet-600 bg-violet-600 text-white"
83+
: isActive
84+
? "border-violet-500 bg-violet-500 text-white ring-4 ring-violet-500/25"
85+
: "border-white/5 bg-white/5 text-white/30"
86+
}`}
87+
>
88+
{isDone ? (
89+
<svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
90+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" />
91+
</svg>
92+
) : (
93+
step.icon
94+
)}
95+
</div>
96+
<p
97+
className={`text-center text-xs transition-colors duration-300 ${isDone
98+
? "font-medium text-violet-500"
99+
: isActive
100+
? "font-semibold text-violet-400"
101+
: "font-medium text-white/30"
102+
}`}
103+
>
104+
{step.label}
105+
</p>
106+
</div>
107+
);
108+
})}
109+
</div>
110+
</div>
111+
112+
{/* Progress Bar */}
113+
<div className="h-[2px] w-full rounded-full bg-white/5">
114+
<div
115+
className="h-full rounded-full bg-violet-600 transition-all duration-500"
116+
style={{ width: progressWidth }}
117+
/>
118+
</div>
119+
120+
{/* Step Panels */}
121+
{currentStep === 0 && (
122+
<InquiryForm
123+
defaultValues={formData}
124+
onNext={(data) => { updateFormData(data); goNext(); }}
125+
/>
126+
)}
127+
{currentStep === 1 && (
128+
<ShortSurvey
129+
defaultValues={formData}
130+
onNext={(data) => { updateFormData(data); goNext(); }}
131+
onBack={goBack}
132+
/>
133+
)}
134+
{currentStep === 2 && (
135+
<Appointment
136+
formData={formData}
137+
onBack={goBack}
138+
/>
139+
)}
140+
141+
{/* Security note */}
142+
<div className="flex w-full items-center gap-2 rounded-lg border border-white/5 bg-white/5 px-4 py-3">
143+
<svg className="h-4 w-4 shrink-0 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
144+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
145+
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
146+
</svg>
147+
<p className="text-xs text-white/40">
148+
We prioritize the security of your information. Rest assured, we will ensure that your data remains safe with us.
149+
</p>
150+
</div>
151+
152+
</div>
153+
</div>
154+
);
155+
};
156+
157+
export default ContactPage;

0 commit comments

Comments
 (0)