diff --git a/app/(home)/components/SponsorsDesktop.tsx b/app/(home)/components/SponsorsDesktop.tsx
index 11061cf..db81c73 100644
--- a/app/(home)/components/SponsorsDesktop.tsx
+++ b/app/(home)/components/SponsorsDesktop.tsx
@@ -158,7 +158,7 @@ const SponsorsDesktop = ({ sponsors }: { sponsors: SponsorshipProps[] }) => {
{featuredSponsor.description}
- — {featuredSponsor.name}
+ - {featuredSponsor.name}
diff --git a/app/(home)/components/Testimonials.tsx b/app/(home)/components/Testimonials.tsx
new file mode 100644
index 0000000..47fd153
--- /dev/null
+++ b/app/(home)/components/Testimonials.tsx
@@ -0,0 +1,291 @@
+'use client';
+
+import { Button } from '@/components/ui/button';
+import Image from 'next/image';
+import { Container } from '@/components/ui/container';
+import Link from 'next/link';
+import { CarouselDots, type CarouselApi } from '@/components/ui/carousel';
+import { useState, useRef, useEffect } from 'react';
+import YellowStar from '@/public/assets/testimonials/yellow-star.svg';
+import WhiteStar from '@/public/assets/testimonials/white-star.svg';
+import ChatBubble from '@/public/assets/testimonials/chat-bubble.svg';
+import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
+import {
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselNext,
+ CarouselPrevious,
+} from '@/components/ui/carousel';
+
+type TestimonialProps = {
+ text: string;
+ rate: number;
+ active: boolean;
+};
+
+export function Testimonials() {
+ const dummyData = [
+ {
+ name: 'AlexByte_97',
+ date: '2 days ago',
+ comment:
+ "I've been following similar content for a while, but this one really stands out. The attention to detail and the way everything is explained so clearly make it incredibly easy to understand. Honestly, I wish more people put this level of effort into their posts. Keep it up! Looking forward to more amazing content like this! ????",
+ rate: 5,
+ profilePic: 'https://github.com/shadcn.png',
+ },
+ {
+ name: 'GamerXtreme',
+ date: '3 weeks ago',
+ comment: 'Not bad, but I expected a bit more tbh. ??',
+ rate: 3,
+ profilePic: 'https://github.com/shadcn.png',
+ },
+ {
+ name: 'TechieTasha',
+ date: '5 days ago',
+ comment: 'Super useful, definitely sharing this! ??',
+ rate: 4,
+ profilePic: 'https://github.com/shadcn.png',
+ },
+ {
+ name: 'MemeLord420',
+ date: '1 month ago',
+ comment: "Bro, this ain't it... ??",
+ rate: 2,
+ profilePic: 'https://github.com/shadcn.png',
+ },
+ {
+ name: 'NeonC0der',
+ date: '10 hours ago',
+ comment:
+ 'I appreciate the effort that went into this, but I feel like some parts could have been elaborated on a bit more. Certain sections were great, but others felt a little rushed. That being said, I still learned a lot and really enjoyed the overall message. Keep refining your style because you definitely have potential! Excited to see how your content evolves over time. ??',
+ rate: 4,
+ profilePic: 'https://github.com/shadcn.png',
+ },
+ ];
+
+ const [api, setApi] = useState();
+ const [current, setCurrent] = useState(0);
+ const [isInteracting, setIsInteracting] = useState(false);
+
+ useEffect(() => {
+ if (!api) {
+ return;
+ }
+ setCurrent(api.selectedScrollSnap());
+
+ api.on('select', () => {
+ setCurrent(api.selectedScrollSnap());
+ });
+ }, [api]);
+
+ return (
+
+
+ {/* Combined container: Ratings + Button */}
+
+ {/* Logo & Ratings */}
+
+
+
+
+
+ Ratings
+
+
+
+ {/* Star Ratings */}
+
+
4.8
+
+ {[...Array(4)].map((_, i) => (
+
+ ))}
+
+
+
5 reviews
+
+
+
+
+ {/* Button */}
+
+
+
+ Write a Review
+
+
+
+
+
+ {/* CAROUSEL */}
+
+
setIsInteracting(true)}
+ onMouseLeave={() => setIsInteracting(false)}
+ className="max-w-96 sm:w-96 lg:max-w-full lg:w-full lg:px-5 mx-auto"
+ >
+
+ {dummyData.map((data, index) => (
+
+
+
+
+
+
+ {data.name
+ .split(' ')
+ .map((word) => word[0])
+ .join('')
+ .toUpperCase()}
+
+
+
+
{data.name}
+
{data.date}
+
+
+
+ ))}
+
+ api?.scrollTo(current - 1)}
+ />
+ api?.scrollTo(current + 1)}
+ />
+
+
+
+
+
+ );
+}
+
+export function TestimonialCard({ text, rate, active }: TestimonialProps) {
+ const starRate = [];
+ const textRef = useRef(null);
+ const [isTextOverflowing, setIsTextOverflowing] = useState(false);
+
+ // Check if text is overflowing
+ useEffect(() => {
+ const checkOverflow = () => {
+ if (textRef.current) {
+ const element = textRef.current;
+ const isOverflowing =
+ element.scrollHeight > element.clientHeight ||
+ element.scrollWidth > element.clientWidth;
+ setIsTextOverflowing(isOverflowing);
+ }
+ };
+
+ checkOverflow();
+ // Re-check on window resize
+ window.addEventListener('resize', checkOverflow);
+ return () => window.removeEventListener('resize', checkOverflow);
+ }, [text]);
+
+ // Append stars
+ for (let i = 0; i < 5; i++) {
+ // If index is greater than the rating, append white star, else yellow star.
+ if (i >= rate) {
+ starRate.push(
+
+ );
+ } else {
+ starRate.push(
+
+ );
+ }
+ }
+
+ return (
+ <>
+ {/* Mobile View Display */}
+
+
{text}
+ {isTextOverflowing && (
+
+
+ Read more
+
+
+ )}
+
+
+ {/* Tablet & Laptop View Display */}
+
+
+
+ {starRate}
+
+
+ {text}
+
+ {isTextOverflowing && (
+
+
+ Read more
+
+
+ )}
+
+ >
+ );
+}
diff --git a/app/(home)/page.tsx b/app/(home)/page.tsx
index 5992684..ba6fbe0 100644
--- a/app/(home)/page.tsx
+++ b/app/(home)/page.tsx
@@ -7,6 +7,8 @@ import { Partners } from './components//Partners';
// import UpcomingEvents from './components//UpcomingEvents';
import { Sponsors } from './components/Sponsors';
+import { Testimonials } from './components/Testimonials';
+
export default function HomePage() {
return (
@@ -14,6 +16,7 @@ export default function HomePage() {
+
{/* */}
diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx
new file mode 100644
index 0000000..afb7c8a
--- /dev/null
+++ b/components/ui/avatar.tsx
@@ -0,0 +1,50 @@
+'use client';
+
+import * as React from 'react';
+import * as AvatarPrimitive from '@radix-ui/react-avatar';
+
+import { cn } from '@/lib/utils';
+
+const Avatar = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+Avatar.displayName = AvatarPrimitive.Root.displayName;
+
+const AvatarImage = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarImage.displayName = AvatarPrimitive.Image.displayName;
+
+const AvatarFallback = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
+
+export { Avatar, AvatarImage, AvatarFallback };
diff --git a/package-lock.json b/package-lock.json
index 8feab5d..ba16fd3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@gsap/react": "^2.1.2",
"@radix-ui/react-accordion": "^1.2.3",
+ "@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.6",
@@ -25,11 +26,11 @@
"gsap": "^3.12.7",
"lenis": "^1.1.22",
"lucide-react": "^0.475.0",
- "next": "14.2.21",
+ "next": "^14.2.28",
"odometer": "^0.4.8",
- "react": "^18",
+ "react": "^18.2.0",
"react-countup": "^6.5.3",
- "react-dom": "^18",
+ "react-dom": "^18.2.0",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-gradients": "^3.0.0"
@@ -348,9 +349,9 @@
}
},
"node_modules/@next/env": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.21.tgz",
- "integrity": "sha512-lXcwcJd5oR01tggjWJ6SrNNYFGuOOMB9c251wUNkjCpkoXOPkDeF/15c3mnVlBqrW4JJXb2kVxDFhC4GduJt2A==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.28.tgz",
+ "integrity": "sha512-PAmWhJfJQlP+kxZwCjrVd9QnR5x0R3u0mTXTiZDgSd4h5LdXmjxCCWbN9kq6hkZBOax8Rm3xDW5HagWyJuT37g==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
@@ -364,9 +365,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.21.tgz",
- "integrity": "sha512-HwEjcKsXtvszXz5q5Z7wCtrHeTTDSTgAbocz45PHMUjU3fBYInfvhR+ZhavDRUYLonm53aHZbB09QtJVJj8T7g==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.28.tgz",
+ "integrity": "sha512-kzGChl9setxYWpk3H6fTZXXPFFjg7urptLq5o5ZgYezCrqlemKttwMT5iFyx/p1e/JeglTwDFRtb923gTJ3R1w==",
"cpu": [
"arm64"
],
@@ -380,9 +381,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.21.tgz",
- "integrity": "sha512-TSAA2ROgNzm4FhKbTbyJOBrsREOMVdDIltZ6aZiKvCi/v0UwFmwigBGeqXDA97TFMpR3LNNpw52CbVelkoQBxA==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.28.tgz",
+ "integrity": "sha512-z6FXYHDJlFOzVEOiiJ/4NG8aLCeayZdcRSMjPDysW297Up6r22xw6Ea9AOwQqbNsth8JNgIK8EkWz2IDwaLQcw==",
"cpu": [
"x64"
],
@@ -396,9 +397,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.21.tgz",
- "integrity": "sha512-0Dqjn0pEUz3JG+AImpnMMW/m8hRtl1GQCNbO66V1yp6RswSTiKmnHf3pTX6xMdJYSemf3O4Q9ykiL0jymu0TuA==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.28.tgz",
+ "integrity": "sha512-9ARHLEQXhAilNJ7rgQX8xs9aH3yJSj888ssSjJLeldiZKR4D7N08MfMqljk77fAwZsWwsrp8ohHsMvurvv9liQ==",
"cpu": [
"arm64"
],
@@ -412,9 +413,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.21.tgz",
- "integrity": "sha512-Ggfw5qnMXldscVntwnjfaQs5GbBbjioV4B4loP+bjqNEb42fzZlAaK+ldL0jm2CTJga9LynBMhekNfV8W4+HBw==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.28.tgz",
+ "integrity": "sha512-p6gvatI1nX41KCizEe6JkF0FS/cEEF0u23vKDpl+WhPe/fCTBeGkEBh7iW2cUM0rvquPVwPWdiUR6Ebr/kQWxQ==",
"cpu": [
"arm64"
],
@@ -428,9 +429,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.21.tgz",
- "integrity": "sha512-uokj0lubN1WoSa5KKdThVPRffGyiWlm/vCc/cMkWOQHw69Qt0X1o3b2PyLLx8ANqlefILZh1EdfLRz9gVpG6tg==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.28.tgz",
+ "integrity": "sha512-nsiSnz2wO6GwMAX2o0iucONlVL7dNgKUqt/mDTATGO2NY59EO/ZKnKEr80BJFhuA5UC1KZOMblJHWZoqIJddpA==",
"cpu": [
"x64"
],
@@ -444,9 +445,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.21.tgz",
- "integrity": "sha512-iAEBPzWNbciah4+0yI4s7Pce6BIoxTQ0AGCkxn/UBuzJFkYyJt71MadYQkjPqCQCJAFQ26sYh7MOKdU+VQFgPg==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.28.tgz",
+ "integrity": "sha512-+IuGQKoI3abrXFqx7GtlvNOpeExUH1mTIqCrh1LGFf8DnlUcTmOOCApEnPJUSLrSbzOdsF2ho2KhnQoO0I1RDw==",
"cpu": [
"x64"
],
@@ -460,9 +461,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.21.tgz",
- "integrity": "sha512-plykgB3vL2hB4Z32W3ktsfqyuyGAPxqwiyrAi2Mr8LlEUhNn9VgkiAl5hODSBpzIfWweX3er1f5uNpGDygfQVQ==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.28.tgz",
+ "integrity": "sha512-l61WZ3nevt4BAnGksUVFKy2uJP5DPz2E0Ma/Oklvo3sGj9sw3q7vBWONFRgz+ICiHpW5mV+mBrkB3XEubMrKaA==",
"cpu": [
"arm64"
],
@@ -476,9 +477,9 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.21.tgz",
- "integrity": "sha512-w5bacz4Vxqrh06BjWgua3Yf7EMDb8iMcVhNrNx8KnJXt8t+Uu0Zg4JHLDL/T7DkTCEEfKXO/Er1fcfWxn2xfPA==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.28.tgz",
+ "integrity": "sha512-+Kcp1T3jHZnJ9v9VTJ/yf1t/xmtFAc/Sge4v7mVc1z+NYfYzisi8kJ9AsY8itbgq+WgEwMtOpiLLJsUy2qnXZw==",
"cpu": [
"ia32"
],
@@ -492,9 +493,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.21.tgz",
- "integrity": "sha512-sT6+llIkzpsexGYZq8cjjthRyRGe5cJVhqh12FmlbxHqna6zsDDK8UNaV7g41T6atFHCJUPeLb3uyAwrBwy0NA==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.28.tgz",
+ "integrity": "sha512-1gCmpvyhz7DkB1srRItJTnmR2UwQPAUXXIg9r0/56g3O8etGmwlX68skKXJOp9EejW3hhv7nSQUJ2raFiz4MoA==",
"cpu": [
"x64"
],
@@ -622,6 +623,134 @@
}
}
},
+ "node_modules/@radix-ui/react-avatar": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.7.tgz",
+ "integrity": "sha512-V7ODUt4mUoJTe3VUxZw6nfURxaPALVqmDQh501YmaQsk3D8AZQrOPRnfKn4H7JGDLBc0KqLhT94H79nV88ppNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.0",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-is-hydrated": "0.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.0.tgz",
+ "integrity": "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
+ "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-checkbox": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.4.tgz",
@@ -1203,6 +1332,24 @@
}
}
},
+ "node_modules/@radix-ui/react-use-is-hydrated": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz",
+ "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==",
+ "license": "MIT",
+ "dependencies": {
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
@@ -4515,12 +4662,12 @@
"license": "MIT"
},
"node_modules/next": {
- "version": "14.2.21",
- "resolved": "https://registry.npmjs.org/next/-/next-14.2.21.tgz",
- "integrity": "sha512-rZmLwucLHr3/zfDMYbJXbw0ZeoBpirxkXuvsJbk7UPorvPYZhP7vq7aHbKnU7dQNCYIimRrbB2pp3xmf+wsYUg==",
+ "version": "14.2.28",
+ "resolved": "https://registry.npmjs.org/next/-/next-14.2.28.tgz",
+ "integrity": "sha512-QLEIP/kYXynIxtcKB6vNjtWLVs3Y4Sb+EClTC/CSVzdLD1gIuItccpu/n1lhmduffI32iPGEK2cLLxxt28qgYA==",
"license": "MIT",
"dependencies": {
- "@next/env": "14.2.21",
+ "@next/env": "14.2.28",
"@swc/helpers": "0.5.5",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
@@ -4535,15 +4682,15 @@
"node": ">=18.17.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "14.2.21",
- "@next/swc-darwin-x64": "14.2.21",
- "@next/swc-linux-arm64-gnu": "14.2.21",
- "@next/swc-linux-arm64-musl": "14.2.21",
- "@next/swc-linux-x64-gnu": "14.2.21",
- "@next/swc-linux-x64-musl": "14.2.21",
- "@next/swc-win32-arm64-msvc": "14.2.21",
- "@next/swc-win32-ia32-msvc": "14.2.21",
- "@next/swc-win32-x64-msvc": "14.2.21"
+ "@next/swc-darwin-arm64": "14.2.28",
+ "@next/swc-darwin-x64": "14.2.28",
+ "@next/swc-linux-arm64-gnu": "14.2.28",
+ "@next/swc-linux-arm64-musl": "14.2.28",
+ "@next/swc-linux-x64-gnu": "14.2.28",
+ "@next/swc-linux-x64-musl": "14.2.28",
+ "@next/swc-win32-arm64-msvc": "14.2.28",
+ "@next/swc-win32-ia32-msvc": "14.2.28",
+ "@next/swc-win32-x64-msvc": "14.2.28"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -6338,6 +6485,15 @@
}
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index 5988df9..7f36515 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@gsap/react": "^2.1.2",
"@radix-ui/react-accordion": "^1.2.3",
+ "@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.6",
@@ -28,11 +29,11 @@
"gsap": "^3.12.7",
"lenis": "^1.1.22",
"lucide-react": "^0.475.0",
- "next": "14.2.21",
+ "next": "^14.2.28",
"odometer": "^0.4.8",
- "react": "^18",
+ "react": "^18.2.0",
"react-countup": "^6.5.3",
- "react-dom": "^18",
+ "react-dom": "^18.2.0",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-gradients": "^3.0.0"
diff --git a/public/assets/testimonials/chat-bubble.svg b/public/assets/testimonials/chat-bubble.svg
new file mode 100644
index 0000000..2dcf7d6
--- /dev/null
+++ b/public/assets/testimonials/chat-bubble.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/public/assets/testimonials/white-star.svg b/public/assets/testimonials/white-star.svg
new file mode 100644
index 0000000..29f5581
--- /dev/null
+++ b/public/assets/testimonials/white-star.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/assets/testimonials/yellow-star.svg b/public/assets/testimonials/yellow-star.svg
new file mode 100644
index 0000000..50debfa
--- /dev/null
+++ b/public/assets/testimonials/yellow-star.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/tsconfig.json b/tsconfig.json
index 40f87ee..37ebeb5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -24,7 +24,8 @@
"@/components/*": ["./components/*"],
"@/lib/*": ["./lib/*"],
"@/styles/*": ["./styles/*"]
- }
+ },
+ "target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]