Skip to content

Commit b8dbed1

Browse files
authored
Merge pull request #66 from Manishhhsys/feat/replace_contact_us_with_cal
[FEAT] Replace "Contact Us" email with meeting booking form(Cal)
2 parents 2cf3ac5 + eccfe94 commit b8dbed1

File tree

3 files changed

+112
-29
lines changed

3 files changed

+112
-29
lines changed

components/Navbar.tsx

Lines changed: 80 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
import React, { useState, useEffect } from "react";
44
import Link from "next/link";
5-
import { Menu, X, Slack } from "lucide-react";
5+
import { Menu, X, Slack, Plus } from "lucide-react";
66
import Logo from "./Logo";
77
import ThemeToggle from "./ThemeToggle";
88
import GitHubStarButton from "./GitHubStarsButton";
9+
import { getCalApi } from "@calcom/embed-react";
10+
import Image from "next/image";
911

10-
// constants/contact.ts
11-
export const CONTACT_EMAIL = '[email protected]';
12-
export const CONTACT_MAILTO = `mailto:${CONTACT_EMAIL}`;
1312

1413
interface NavigationItem {
1514
name: string;
@@ -21,7 +20,19 @@ const Navbar: React.FC = () => {
2120
const [isMenuOpen, setIsMenuOpen] = useState(false);
2221
const [activeSection, setActiveSection] = useState<string>("");
2322
const [scrolled, setScrolled] = useState(false);
24-
23+
const rawCalLink = process.env.NEXT_PUBLIC_CAL_DATA_LINK ?? "";
24+
const calLink = rawCalLink.trim();
25+
const isCalReady = calLink.length > 0;
26+
if(!isCalReady){
27+
console.error("NEXT_PUBLIC_CAL_DATA_LINK environment variable is not set")
28+
}
29+
const CAL_CONFIG = {
30+
theme: "light",
31+
hideEventTypeDetails: true,
32+
layout: "month_view"
33+
} as const;
34+
35+
const CAL_CONFIG_STRING = JSON.stringify(CAL_CONFIG);
2536
const navigation: NavigationItem[] = [
2637
{ name: "Features", href: "/#features" },
2738
{ name: "Integrations", href: "/#integrations" },
@@ -39,12 +50,45 @@ const Navbar: React.FC = () => {
3950
href: "https://join.slack.com/t/opsimate/shared_invite/zt-39bq3x6et-NrVCZzH7xuBGIXmOjJM7gA",
4051
external: true,
4152
};
53+
useEffect(() => {
54+
if(!isCalReady){
55+
return;
56+
}
57+
(async function () {
58+
try{
59+
const cal = await getCalApi({ "namespace": "30min" });
60+
cal("ui", { "hideEventTypeDetails": true, "layout": "month_view" });
61+
}catch(error){
62+
console.error("Failed to initialize Cal.com:", error);
63+
}
64+
})();
65+
}, [isCalReady])
4266

43-
const contactLink: NavigationItem = {
44-
name: "Contact Us",
45-
href: CONTACT_MAILTO,
46-
external: true,
47-
};
67+
// Highlight active section on scroll
68+
useEffect(() => {
69+
const sections = document.querySelectorAll("section[id]");
70+
const observer = new IntersectionObserver(
71+
(entries) => {
72+
entries.forEach((entry) => {
73+
if (entry.isIntersecting) {
74+
setActiveSection(entry.target.id);
75+
}
76+
});
77+
},
78+
{ rootMargin: "-50% 0px -50% 0px" }
79+
);
80+
81+
sections.forEach((section) => observer.observe(section));
82+
return () => sections.forEach((section) => observer.unobserve(section));
83+
}, []);
84+
85+
// Blur effect on scroll
86+
useEffect(() => {
87+
const handleScroll = () => setScrolled(window.scrollY > 20);
88+
handleScroll();
89+
window.addEventListener("scroll", handleScroll);
90+
return () => window.removeEventListener("scroll", handleScroll);
91+
}, []);
4892

4993
// Highlight active section on scroll
5094
useEffect(() => {
@@ -121,29 +165,37 @@ const Navbar: React.FC = () => {
121165
<Slack size={18} aria-hidden="true" />
122166
{slackLink.name}
123167
</Link>
124-
125168
{/* Contact Us button */}
126-
<a
127-
href={contactLink.href}
128-
className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors duration-200"
129-
>
130-
{contactLink.name}
131-
</a>
132-
169+
{
170+
isCalReady &&(
171+
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700
172+
duration-200
173+
flex items-center gap-2 flex-shrink-0
174+
transition-all group"
175+
data-cal-namespace="30min" data-cal-link={calLink} data-cal-config={CAL_CONFIG_STRING}>
176+
<div className="flex items-center gap-2 group-hover:gap-8 transition-all duration-300 relative">
177+
<Image src={'/images/logo.png'} width={28} height={28} alt="logo" className="rounded-full bg-white flex-shrink-0"></Image>
178+
<div className="flex items-center gap-0 absolute left-[28px] transform -translate-x-full opacity-0 group-hover:translate-x-0 group-hover:opacity-100 transition-all duration-300">
179+
<div className="w-5 h-5 rounded-full flex items-center justify-center text-[10px] ml-1 mr-1"><Plus width={20} height={20}></Plus></div>
180+
<div className="w-7 h-7 rounded-full dark:bg-white/10 bg-white/20 flex items-center justify-center text-[10px] ml-1 mr-1">You</div>
181+
</div>
182+
<span className="whitespace-nowrap relative block text-base font-bold ml-0 group-hover:ml-10 transition-all duration-300">Book a Call</span>
183+
</div>
184+
</button>
185+
)
186+
}
133187
<ThemeToggle />
134188
</div>
135-
136189
{/* Mobile menu button */}
137190
<div className="md:hidden">
138-
<button
191+
<button
139192
onClick={() => setIsMenuOpen(!isMenuOpen)}
140193
className="text-surface-700 dark:text-surface-300 hover:text-primary-500 dark:hover:text-primary-400 transition-colors duration-200"
141194
>
142195
{isMenuOpen ? <X size={24} /> : <Menu size={24} />}
143196
</button>
144197
</div>
145198
</div>
146-
147199
{/* Mobile Navigation */}
148200
{isMenuOpen && (
149201
<div className="md:hidden py-4 border-t border-surface-200 dark:border-surface-800">
@@ -168,13 +220,13 @@ const Navbar: React.FC = () => {
168220
))}
169221

170222
{/* Mobile Contact Us link */}
171-
<a
172-
href={contactLink.href}
173-
className="text-surface-700 dark:text-surface-300 hover:text-primary-500 dark:hover:text-primary-400 font-medium transition-colors duration-200 px-2 py-1"
174-
onClick={() => setIsMenuOpen(false)}
175-
>
176-
{contactLink.name}
177-
</a>
223+
{
224+
isCalReady && (
225+
<button className="font-medium transition-colors duration-200 px-2 py-2 md:w-[20%] w-[35%] bg-primary-600 text-white rounded-lg hover:bg-primary-700 cursor-pointer" data-cal-namespace="30min" data-cal-link={calLink} data-cal-config={CAL_CONFIG_STRING}>
226+
Book A Call
227+
</button>
228+
)
229+
}
178230
</div>
179231
</div>
180232
)}

package-lock.json

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"@calcom/embed-react": "^1.5.3",
1213
"@vercel/analytics": "^1.5.0",
1314
"front-matter": "^4.0.2",
1415
"lucide-react": "^0.294.0",
@@ -18,6 +19,7 @@
1819
"remark": "^15.0.1"
1920
},
2021
"devDependencies": {
22+
"@tailwindcss/typography": "^0.5.15",
2123
"@types/node": "^20.8.0",
2224
"@types/react": "^18.2.0",
2325
"@types/react-dom": "^18.2.0",
@@ -29,7 +31,6 @@
2931
"rehype-sanitize": "^6.0.0",
3032
"rehype-stringify": "^10.0.0",
3133
"remark-rehype": "^11.1.0",
32-
"@tailwindcss/typography": "^0.5.15",
3334
"tailwindcss": "^3.3.0",
3435
"typescript": "^5.2.0"
3536
}

0 commit comments

Comments
 (0)