api integrate of start-a-project form , captcha pending
This commit is contained in:
51
assets/Group1597880681.tsx
Normal file
51
assets/Group1597880681.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
// High-quality placeholder images for the group icons
|
||||||
|
const logoImage1 =
|
||||||
|
"https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=175&h=305&fit=crop&auto=format";
|
||||||
|
const logoImage2 =
|
||||||
|
"https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=175&h=305&fit=crop&auto=format";
|
||||||
|
const logoImage3 =
|
||||||
|
"https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=175&h=305&fit=crop&auto=format";
|
||||||
|
// const logoImage4 = "https://images.unsplash.com/photo-1560472355-536de3962603?w=120&h=60&fit=crop&auto=format";
|
||||||
|
// const logoImage5 = "https://images.unsplash.com/photo-1563986768609-322da13575f3?w=120&h=60&fit=crop&auto=format";
|
||||||
|
// const logoImage6 = "https://images.unsplash.com/photo-1572177812156-58036aae439c?w=120&h=60&fit=crop&auto=format";
|
||||||
|
// const logoImage7 = "https://images.unsplash.com/photo-1553484771-371a605b060b?w=120&h=60&fit=crop&auto=format";
|
||||||
|
// const logoImage8 = "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=120&h=60&fit=crop&auto=format";
|
||||||
|
// const logoImage9 = "https://images.unsplash.com/photo-1551650975-87deedd944c3?w=120&h=60&fit=crop&auto=format";
|
||||||
|
|
||||||
|
export default function Group1597880681() {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center gap-8 flex-wrap opacity-60 hover:opacity-100 transition-opacity duration-300">
|
||||||
|
{/* Client Logos Grid */}
|
||||||
|
<div className="flex justify-center items-center py-12 perspective">
|
||||||
|
{/* Left Card */}
|
||||||
|
<div className="w-65 h-110 p-2 rounded-xl bg-white/5 backdrop-blur-sm border border-white/10 hover:border-accent/30 transform custom-rotate-left hover:scale-105 transition-all duration-300">
|
||||||
|
<img
|
||||||
|
src={logoImage1}
|
||||||
|
alt="Left"
|
||||||
|
className="w-full h-full object-contain filter invert opacity-80 hover:opacity-100 transition-opacity duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Center Card */}
|
||||||
|
<div className="w-65 h-110 p-2 rounded-xl bg-white/5 backdrop-blur-sm border border-white/10 hover:border-accent/30 scale-110 shadow-xl z-10 hover:scale-115 transition-all duration-300">
|
||||||
|
<img
|
||||||
|
src={logoImage2}
|
||||||
|
alt="Center"
|
||||||
|
className="w-full h-full object-contain filter invert opacity-90 hover:opacity-100 transition-opacity duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Card */}
|
||||||
|
<div className="w-65 h-110 p-2 rounded-xl bg-white/5 backdrop-blur-sm border border-white/10 hover:border-accent/30 transform custom-rotate-right hover:scale-105 transition-all duration-300">
|
||||||
|
<img
|
||||||
|
src={logoImage3}
|
||||||
|
alt="Right"
|
||||||
|
className="w-full h-full object-contain filter invert opacity-80 hover:opacity-100 transition-opacity duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
|
import React, {
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
forwardRef,
|
||||||
|
useImperativeHandle,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
interface CustomReCaptchaProps {
|
interface CustomReCaptchaProps {
|
||||||
siteKey: string;
|
siteKey: string;
|
||||||
@@ -6,6 +11,8 @@ interface CustomReCaptchaProps {
|
|||||||
onExpired?: () => void;
|
onExpired?: () => void;
|
||||||
onError?: () => void;
|
onError?: () => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
theme?: "light" | "dark";
|
||||||
|
size?: "normal" | "compact";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReCaptchaRef {
|
export interface ReCaptchaRef {
|
||||||
@@ -16,99 +23,127 @@ export interface ReCaptchaRef {
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
grecaptcha: any;
|
grecaptcha: any;
|
||||||
|
onReCaptchaLoad?: () => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomReCaptcha = forwardRef<ReCaptchaRef, CustomReCaptchaProps>(({
|
const CustomReCaptcha = forwardRef<ReCaptchaRef, CustomReCaptchaProps>(
|
||||||
siteKey,
|
(
|
||||||
onVerify,
|
{
|
||||||
onExpired,
|
siteKey,
|
||||||
onError,
|
onVerify,
|
||||||
className = ""
|
onExpired,
|
||||||
}, ref) => {
|
onError,
|
||||||
const captchaRef = useRef<HTMLDivElement>(null);
|
className = "",
|
||||||
const widgetId = useRef<number | null>(null);
|
theme = "dark",
|
||||||
const isLoadedRef = useRef(false);
|
size = "normal",
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
reset: () => {
|
|
||||||
if (window.grecaptcha && widgetId.current !== null) {
|
|
||||||
window.grecaptcha.reset(widgetId.current);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
execute: () => {
|
ref
|
||||||
if (window.grecaptcha && widgetId.current !== null) {
|
) => {
|
||||||
window.grecaptcha.execute(widgetId.current);
|
const captchaRef = useRef<HTMLDivElement>(null);
|
||||||
}
|
const widgetId = useRef<number | null>(null);
|
||||||
}
|
const isLoadedRef = useRef(false);
|
||||||
}));
|
|
||||||
|
|
||||||
const loadReCaptcha = () => {
|
useImperativeHandle(ref, () => ({
|
||||||
if (window.grecaptcha) {
|
reset: () => {
|
||||||
renderReCaptcha();
|
if (window.grecaptcha && widgetId.current !== null) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load reCAPTCHA script
|
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = 'https://www.google.com/recaptcha/api.js?onload=onReCaptchaLoad&render=explicit';
|
|
||||||
script.async = true;
|
|
||||||
script.defer = true;
|
|
||||||
|
|
||||||
// Set up callback for when script loads
|
|
||||||
(window as any).onReCaptchaLoad = () => {
|
|
||||||
renderReCaptcha();
|
|
||||||
};
|
|
||||||
|
|
||||||
document.head.appendChild(script);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderReCaptcha = () => {
|
|
||||||
if (!captchaRef.current || isLoadedRef.current) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
widgetId.current = window.grecaptcha.render(captchaRef.current, {
|
|
||||||
sitekey: siteKey,
|
|
||||||
callback: onVerify,
|
|
||||||
'expired-callback': onExpired,
|
|
||||||
'error-callback': onError,
|
|
||||||
theme: 'dark',
|
|
||||||
size: 'normal'
|
|
||||||
});
|
|
||||||
isLoadedRef.current = true;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error rendering reCAPTCHA:', error);
|
|
||||||
if (onError) onError();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
loadReCaptcha();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
// Cleanup
|
|
||||||
if (window.grecaptcha && widgetId.current !== null) {
|
|
||||||
try {
|
|
||||||
window.grecaptcha.reset(widgetId.current);
|
window.grecaptcha.reset(widgetId.current);
|
||||||
} catch (error) {
|
|
||||||
// Ignore cleanup errors
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
execute: () => {
|
||||||
|
if (window.grecaptcha && widgetId.current !== null) {
|
||||||
|
window.grecaptcha.execute(widgetId.current);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const loadReCaptcha = () => {
|
||||||
|
if (window.grecaptcha) {
|
||||||
|
renderReCaptcha();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if script is already loading
|
||||||
|
if (
|
||||||
|
document.querySelector(
|
||||||
|
'script[src^="https://www.google.com/recaptcha/api.js"]'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// If already loading, set up a callback for when it loads
|
||||||
|
window.onReCaptchaLoad = renderReCaptcha;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load reCAPTCHA script
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src =
|
||||||
|
"https://www.google.com/recaptcha/api.js?onload=onReCaptchaLoad&render=explicit";
|
||||||
|
script.async = true;
|
||||||
|
script.defer = true;
|
||||||
|
|
||||||
|
// Set up callback for when script loads
|
||||||
|
window.onReCaptchaLoad = () => {
|
||||||
|
renderReCaptcha();
|
||||||
|
window.onReCaptchaLoad = undefined; // Clean up
|
||||||
|
};
|
||||||
|
|
||||||
|
script.onerror = () => {
|
||||||
|
console.error("Failed to load reCAPTCHA script");
|
||||||
|
if (onError) onError();
|
||||||
|
window.onReCaptchaLoad = undefined; // Clean up
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderReCaptcha = () => {
|
||||||
|
if (!captchaRef.current || isLoadedRef.current) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
widgetId.current = window.grecaptcha.render(captchaRef.current, {
|
||||||
|
sitekey: siteKey,
|
||||||
|
callback: onVerify,
|
||||||
|
"expired-callback": onExpired,
|
||||||
|
"error-callback": onError,
|
||||||
|
theme: theme,
|
||||||
|
size: size,
|
||||||
|
});
|
||||||
|
isLoadedRef.current = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error rendering reCAPTCHA:", error);
|
||||||
|
if (onError) onError();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Add styles to document head instead of using styled-jsx
|
useEffect(() => {
|
||||||
useEffect(() => {
|
loadReCaptcha();
|
||||||
const styleId = 'custom-recaptcha-styles';
|
|
||||||
|
|
||||||
// Check if styles are already added
|
|
||||||
if (document.getElementById(styleId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const styleElement = document.createElement('style');
|
return () => {
|
||||||
styleElement.id = styleId;
|
// Cleanup
|
||||||
styleElement.textContent = `
|
if (window.grecaptcha && widgetId.current !== null) {
|
||||||
|
try {
|
||||||
|
window.grecaptcha.reset(widgetId.current);
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore cleanup errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clean up the global callback
|
||||||
|
window.onReCaptchaLoad = undefined;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Add styles to document head instead of using styled-jsx
|
||||||
|
useEffect(() => {
|
||||||
|
const styleId = "custom-recaptcha-styles";
|
||||||
|
|
||||||
|
// Check if styles are already added
|
||||||
|
if (document.getElementById(styleId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const styleElement = document.createElement("style");
|
||||||
|
styleElement.id = styleId;
|
||||||
|
styleElement.textContent = `
|
||||||
.grecaptcha-badge {
|
.grecaptcha-badge {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
@@ -129,32 +164,35 @@ const CustomReCaptcha = forwardRef<ReCaptchaRef, CustomReCaptchaProps>(({
|
|||||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
document.head.appendChild(styleElement);
|
|
||||||
|
|
||||||
// Cleanup function to remove styles when component unmounts
|
document.head.appendChild(styleElement);
|
||||||
return () => {
|
|
||||||
const existingStyle = document.getElementById(styleId);
|
|
||||||
if (existingStyle) {
|
|
||||||
document.head.removeChild(existingStyle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
// Cleanup function to remove styles when component unmounts
|
||||||
<div className={`flex justify-center ${className}`}>
|
return () => {
|
||||||
<div
|
const existingStyle = document.getElementById(styleId);
|
||||||
className="bg-gray-800/30 border border-gray-600/50 rounded-xl p-6 shadow-lg backdrop-blur-sm"
|
if (existingStyle) {
|
||||||
style={{
|
document.head.removeChild(existingStyle);
|
||||||
'--recaptcha-border-radius': '12px'
|
}
|
||||||
} as React.CSSProperties}
|
};
|
||||||
>
|
}, []);
|
||||||
<div ref={captchaRef} />
|
|
||||||
|
return (
|
||||||
|
<div className={`flex justify-center ${className}`}>
|
||||||
|
<div
|
||||||
|
className="bg-gray-800/30 border border-gray-600/50 rounded-xl p-6 shadow-lg backdrop-blur-sm"
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
"--recaptcha-border-radius": "12px",
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div ref={captchaRef} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
CustomReCaptcha.displayName = 'CustomReCaptcha';
|
CustomReCaptcha.displayName = "CustomReCaptcha";
|
||||||
|
|
||||||
export default CustomReCaptcha;
|
export default CustomReCaptcha;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import { GridPattern } from "./GridPattern";
|
import { GridPattern } from "./GridPattern";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { Input } from "./ui/input";
|
import { Input } from "./ui/input";
|
||||||
import BlackLogo14 from "../imports/BlackLogo14";
|
import BlackLogo14 from "../assets/BlackLogo14";
|
||||||
import { navigateTo } from "../App";
|
import { navigateTo } from "../App";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { useState, useRef, useEffect, useCallback } from "react";
|
import { useState, useRef, useEffect, useCallback } from "react";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
Menu,
|
Menu,
|
||||||
X,
|
X,
|
||||||
Code,
|
Code,
|
||||||
Smartphone,
|
Smartphone,
|
||||||
Globe,
|
Globe,
|
||||||
Palette,
|
Palette,
|
||||||
Brain,
|
Brain,
|
||||||
Users,
|
Users,
|
||||||
Building2,
|
Building2,
|
||||||
Monitor,
|
Monitor,
|
||||||
ShoppingCart,
|
ShoppingCart,
|
||||||
@@ -78,21 +78,21 @@ import {
|
|||||||
ArrowRight,
|
ArrowRight,
|
||||||
Calculator,
|
Calculator,
|
||||||
Calendar,
|
Calendar,
|
||||||
FileEdit
|
FileEdit,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import BlackLogo14 from "../imports/BlackLogo14";
|
import BlackLogo14 from "../assets/BlackLogo14";
|
||||||
import { navigateTo } from "../App";
|
import { navigateTo } from "../App";
|
||||||
|
|
||||||
const navigationData = {
|
const navigationData = {
|
||||||
main_navigation: [
|
main_navigation: [
|
||||||
"Services",
|
"Services",
|
||||||
"AI & ML",
|
"AI & ML",
|
||||||
"Solutions",
|
"Solutions",
|
||||||
"Industries",
|
"Industries",
|
||||||
"Hire Talent",
|
"Hire Talent",
|
||||||
"Company",
|
"Company",
|
||||||
"Resources"
|
"Resources",
|
||||||
],
|
],
|
||||||
services: [
|
services: [
|
||||||
{
|
{
|
||||||
@@ -101,35 +101,74 @@ const navigationData = {
|
|||||||
href: "/services/mobile-app-development",
|
href: "/services/mobile-app-development",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "iOS App Development", href: "/services/ios-app-development" },
|
{ name: "iOS App Development", href: "/services/ios-app-development" },
|
||||||
{ name: "Android App Development", href: "/services/android-app-development" },
|
{
|
||||||
{ name: "Cross-Platform App Development", href: "/services/cross-platform-app-development" },
|
name: "Android App Development",
|
||||||
{ name: "Native App Development", href: "/services/native-app-development" },
|
href: "/services/android-app-development",
|
||||||
{ name: "Progressive Web Apps (PWAs)", href: "/services/pwa-development" },
|
},
|
||||||
{ name: "App Development for Wearables & Devices", href: "/services/wearable-device-development" }
|
{
|
||||||
]
|
name: "Cross-Platform App Development",
|
||||||
|
href: "/services/cross-platform-app-development",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Native App Development",
|
||||||
|
href: "/services/native-app-development",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Progressive Web Apps (PWAs)",
|
||||||
|
href: "/services/pwa-development",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "App Development for Wearables & Devices",
|
||||||
|
href: "/services/wearable-device-development",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "Web & Cloud Solutions",
|
category: "Web & Cloud Solutions",
|
||||||
icon: Globe,
|
icon: Globe,
|
||||||
href: "/web-cloud",
|
href: "/web-cloud",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "Custom Web Application Development", href: "/services/custom-web-app-development" },
|
{
|
||||||
{ name: "SaaS Product Engineering", href: "/services/saas-product-engineering" },
|
name: "Custom Web Application Development",
|
||||||
|
href: "/services/custom-web-app-development",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SaaS Product Engineering",
|
||||||
|
href: "/services/saas-product-engineering",
|
||||||
|
},
|
||||||
{ name: "eCommerce Platforms", href: "/services/ecommerce-platforms" },
|
{ name: "eCommerce Platforms", href: "/services/ecommerce-platforms" },
|
||||||
{ name: "Admin Panels & Dashboards", href: "/services/admin-panels-dashboards" },
|
{
|
||||||
{ name: "API & Backend Development", href: "/services/api-backend-development" }
|
name: "Admin Panels & Dashboards",
|
||||||
]
|
href: "/services/admin-panels-dashboards",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "API & Backend Development",
|
||||||
|
href: "/services/api-backend-development",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "Software Engineering",
|
category: "Software Engineering",
|
||||||
icon: Code2,
|
icon: Code2,
|
||||||
href: "/software-engineering",
|
href: "/software-engineering",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "Enterprise Software Solutions", href: "/services/enterprise-software-solutions" },
|
{
|
||||||
{ name: "System Architecture & DevOps", href: "/services/system-architecture-devops" },
|
name: "Enterprise Software Solutions",
|
||||||
{ name: "Third-Party Integrations", href: "/services/third-party-integrations" },
|
href: "/services/enterprise-software-solutions",
|
||||||
{ name: "Product Modernization", href: "/services/product-modernization" }
|
},
|
||||||
]
|
{
|
||||||
|
name: "System Architecture & DevOps",
|
||||||
|
href: "/services/system-architecture-devops",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Third-Party Integrations",
|
||||||
|
href: "/services/third-party-integrations",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Product Modernization",
|
||||||
|
href: "/services/product-modernization",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "Design & Experience",
|
category: "Design & Experience",
|
||||||
@@ -137,11 +176,20 @@ const navigationData = {
|
|||||||
href: "/design-experience",
|
href: "/design-experience",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "UI/UX Design", href: "/services/ui-ux-design" },
|
{ name: "UI/UX Design", href: "/services/ui-ux-design" },
|
||||||
{ name: "Clickable Prototypes", href: "/services/clickable-prototypes" },
|
{
|
||||||
{ name: "Design Thinking Workshops", href: "/services/design-thinking-workshops" },
|
name: "Clickable Prototypes",
|
||||||
{ name: "User Research & Testing", href: "/services/user-research-testing" }
|
href: "/services/clickable-prototypes",
|
||||||
]
|
},
|
||||||
}
|
{
|
||||||
|
name: "Design Thinking Workshops",
|
||||||
|
href: "/services/design-thinking-workshops",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "User Research & Testing",
|
||||||
|
href: "/services/user-research-testing",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
ai_data_intelligence: [
|
ai_data_intelligence: [
|
||||||
{
|
{
|
||||||
@@ -149,136 +197,320 @@ const navigationData = {
|
|||||||
icon: Bot,
|
icon: Bot,
|
||||||
href: "/artificial-intelligence",
|
href: "/artificial-intelligence",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "AI Strategy & Consulting", href: "/services/ai-strategy-consulting" },
|
{
|
||||||
{ name: "AI-Powered Automation & Workflows", href: "/services/ai-automation-workflows" },
|
name: "AI Strategy & Consulting",
|
||||||
{ name: "AI Integration into Digital Products", href: "/services/ai-integration-digital-products" },
|
href: "/services/ai-strategy-consulting",
|
||||||
{ name: "Gen AI Integration into Digital Products", href: "/services/gen-ai-integration-digital-products" },
|
},
|
||||||
{ name: "AI Chatbots & Virtual Assistants", href: "/services/ai-chatbots-virtual-assistants" },
|
{
|
||||||
{ name: "AI Model Deployment & Maintenance", href: "/services/ai-model-deployment-mlops" }
|
name: "AI-Powered Automation & Workflows",
|
||||||
]
|
href: "/services/ai-automation-workflows",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AI Integration into Digital Products",
|
||||||
|
href: "/services/ai-integration-digital-products",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Gen AI Integration into Digital Products",
|
||||||
|
href: "/services/gen-ai-integration-digital-products",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AI Chatbots & Virtual Assistants",
|
||||||
|
href: "/services/ai-chatbots-virtual-assistants",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AI Model Deployment & Maintenance",
|
||||||
|
href: "/services/ai-model-deployment-mlops",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
category: "Machine Learning Solutions",
|
category: "Machine Learning Solutions",
|
||||||
icon: Brain,
|
icon: Brain,
|
||||||
href: "/machine-learning",
|
href: "/machine-learning",
|
||||||
sub_services: [
|
sub_services: [
|
||||||
{ name: "Custom ML Model Development", href: "/services/custom-ml-model-development" },
|
{
|
||||||
{ name: "Predictive Analytics & Forecasting", href: "/services/predictive-analytics-forecasting" },
|
name: "Custom ML Model Development",
|
||||||
{ name: "Computer Vision Applications", href: "/services/computer-vision-applications" },
|
href: "/services/custom-ml-model-development",
|
||||||
{ name: "NLP & Text Analytics", href: "/services/nlp-text-analytics" },
|
},
|
||||||
{ name: "Recommendation Engines", href: "/services/recommendation-engines" }
|
{
|
||||||
]
|
name: "Predictive Analytics & Forecasting",
|
||||||
}
|
href: "/services/predictive-analytics-forecasting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Computer Vision Applications",
|
||||||
|
href: "/services/computer-vision-applications",
|
||||||
|
},
|
||||||
|
{ name: "NLP & Text Analytics", href: "/services/nlp-text-analytics" },
|
||||||
|
{
|
||||||
|
name: "Recommendation Engines",
|
||||||
|
href: "/services/recommendation-engines",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
solutions: [
|
solutions: [
|
||||||
{ text: "Digital Product Development", icon: Rocket, href: "/solutions/digital-product-development" },
|
{
|
||||||
{ text: "MVP & Startup Launch Packages", icon: Zap, href: "/solutions/mvp-startup-launch-packages" },
|
text: "Digital Product Development",
|
||||||
{ text: "Legacy System Rebuilds", icon: RefreshCw, href: "/solutions/legacy-system-rebuilds" },
|
icon: Rocket,
|
||||||
{ text: "Dedicated Offshore Development Centers (ODC)", icon: Building2, href: "/solutions/dedicated-offshore-odc" },
|
href: "/solutions/digital-product-development",
|
||||||
{ text: "Business Process Automation", icon: Cog, href: "/solutions/business-process-automation" },
|
},
|
||||||
{ text: "Compliance-Ready Systems (HIPAA, GDPR, etc.)", icon: Shield, href: "/solutions/compliance-ready-systems" }
|
{
|
||||||
|
text: "MVP & Startup Launch Packages",
|
||||||
|
icon: Zap,
|
||||||
|
href: "/solutions/mvp-startup-launch-packages",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Legacy System Rebuilds",
|
||||||
|
icon: RefreshCw,
|
||||||
|
href: "/solutions/legacy-system-rebuilds",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Dedicated Offshore Development Centers (ODC)",
|
||||||
|
icon: Building2,
|
||||||
|
href: "/solutions/dedicated-offshore-odc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Business Process Automation",
|
||||||
|
icon: Cog,
|
||||||
|
href: "/solutions/business-process-automation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Compliance-Ready Systems (HIPAA, GDPR, etc.)",
|
||||||
|
icon: Shield,
|
||||||
|
href: "/solutions/compliance-ready-systems",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
industries: [
|
industries: [
|
||||||
{
|
{
|
||||||
group: "Financial Services",
|
group: "Financial Services",
|
||||||
icon: DollarSign,
|
icon: DollarSign,
|
||||||
items: [
|
items: [
|
||||||
{ name: "FinTech & Banking Apps", href: "/industries/fintech-banking-apps" },
|
{
|
||||||
{ name: "WealthTech Platforms", href: "/industries/financial-services/wealthtech-platforms" },
|
name: "FinTech & Banking Apps",
|
||||||
{ name: "Real Estate Tech", href: "/industries/financial-services/real-estate-tech" }
|
href: "/industries/fintech-banking-apps",
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
name: "WealthTech Platforms",
|
||||||
|
href: "/industries/financial-services/wealthtech-platforms",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Real Estate Tech",
|
||||||
|
href: "/industries/financial-services/real-estate-tech",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Healthcare & Wellness",
|
group: "Healthcare & Wellness",
|
||||||
icon: Stethoscope,
|
icon: Stethoscope,
|
||||||
items: [
|
items: [
|
||||||
{ name: "HealthTech Applications", href: "/industries/healthcare/healthtech-applications" },
|
{
|
||||||
{ name: "Medical Compliance Solutions", href: "/industries/healthcare/medical-compliance-solutions" },
|
name: "HealthTech Applications",
|
||||||
{ name: "Fitness & Wellness Platforms", href: "/industries/healthcare/fitness-wellness-platforms" }
|
href: "/industries/healthcare/healthtech-applications",
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
name: "Medical Compliance Solutions",
|
||||||
|
href: "/industries/healthcare/medical-compliance-solutions",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fitness & Wellness Platforms",
|
||||||
|
href: "/industries/healthcare/fitness-wellness-platforms",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Learning & Education",
|
group: "Learning & Education",
|
||||||
icon: GraduationCap,
|
icon: GraduationCap,
|
||||||
items: [
|
items: [
|
||||||
{ name: "EdTech Platforms", href: "/industries/education/edtech-platforms" },
|
{
|
||||||
{ name: "Virtual Classrooms & LMS", href: "/industries/education/virtual-classrooms-lms" },
|
name: "EdTech Platforms",
|
||||||
{ name: "Microlearning Apps", href: "/industries/education/microlearning-apps" }
|
href: "/industries/education/edtech-platforms",
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
name: "Virtual Classrooms & LMS",
|
||||||
|
href: "/industries/education/virtual-classrooms-lms",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Microlearning Apps",
|
||||||
|
href: "/industries/education/microlearning-apps",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Commerce & Consumer",
|
group: "Commerce & Consumer",
|
||||||
icon: ShoppingBag,
|
icon: ShoppingBag,
|
||||||
items: [
|
items: [
|
||||||
{ name: "eCommerce & Marketplaces", href: "/industries/commerce/ecommerce-marketplaces" },
|
{
|
||||||
{ name: "Food Ordering & Delivery", href: "/industries/commerce/food-ordering-delivery" },
|
name: "eCommerce & Marketplaces",
|
||||||
{ name: "Travel & Booking Systems", href: "/industries/commerce/travel-booking-systems" },
|
href: "/industries/commerce/ecommerce-marketplaces",
|
||||||
{ name: "Event & Ticketing Solutions", href: "/industries/commerce/event-ticketing-solutions" }
|
},
|
||||||
]
|
{
|
||||||
|
name: "Food Ordering & Delivery",
|
||||||
|
href: "/industries/commerce/food-ordering-delivery",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel & Booking Systems",
|
||||||
|
href: "/industries/commerce/travel-booking-systems",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Event & Ticketing Solutions",
|
||||||
|
href: "/industries/commerce/event-ticketing-solutions",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Media & Community",
|
group: "Media & Community",
|
||||||
icon: Gamepad2,
|
icon: Gamepad2,
|
||||||
items: [
|
items: [
|
||||||
{ name: "OTT & Streaming Apps", href: "/industries/media/ott-streaming-apps" },
|
{
|
||||||
{ name: "Social Platforms & Networks", href: "/industries/media/social-platforms-networks" },
|
name: "OTT & Streaming Apps",
|
||||||
{ name: "Sports & Fan Engagement", href: "/industries/media/sports-fan-engagement" }
|
href: "/industries/media/ott-streaming-apps",
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
name: "Social Platforms & Networks",
|
||||||
|
href: "/industries/media/social-platforms-networks",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sports & Fan Engagement",
|
||||||
|
href: "/industries/media/sports-fan-engagement",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Mobility & Logistics",
|
group: "Mobility & Logistics",
|
||||||
icon: Truck,
|
icon: Truck,
|
||||||
items: [
|
items: [
|
||||||
{ name: "Transportation Apps", href: "/industries/mobility/transportation-apps" },
|
{
|
||||||
{ name: "On-Demand Services", href: "/industries/mobility/on-demand-services" },
|
name: "Transportation Apps",
|
||||||
{ name: "Supply Chain & Fleet Management", href: "/industries/mobility/supply-chain-fleet-management" }
|
href: "/industries/mobility/transportation-apps",
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
name: "On-Demand Services",
|
||||||
|
href: "/industries/mobility/on-demand-services",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Supply Chain & Fleet Management",
|
||||||
|
href: "/industries/mobility/supply-chain-fleet-management",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: "Industrial & Emerging Tech",
|
group: "Industrial & Emerging Tech",
|
||||||
icon: Factory,
|
icon: Factory,
|
||||||
items: [
|
items: [
|
||||||
{ name: "Manufacturing Automation", href: "/industries/industrial/manufacturing-automation" },
|
{
|
||||||
{ name: "AgriTech Platforms", href: "/industries/industrial/agritech-platforms" },
|
name: "Manufacturing Automation",
|
||||||
{ name: "Oil & Gas Monitoring Systems", href: "/industries/industrial/oil-gas-monitoring-systems" }
|
href: "/industries/industrial/manufacturing-automation",
|
||||||
]
|
},
|
||||||
}
|
{
|
||||||
|
name: "AgriTech Platforms",
|
||||||
|
href: "/industries/industrial/agritech-platforms",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Oil & Gas Monitoring Systems",
|
||||||
|
href: "/industries/industrial/oil-gas-monitoring-systems",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
hire_talent: [
|
hire_talent: [
|
||||||
{ text: "Hire Mobile App Developers", icon: Smartphone, href: "/hire-talent/mobile-app-developers" },
|
{
|
||||||
{ text: "Hire Full Stack Developers", icon: Code, href: "/hire-talent/full-stack-developers" },
|
text: "Hire Mobile App Developers",
|
||||||
{ text: "Hire Frontend Developers", icon: Monitor, href: "/hire-talent/frontend-developers" },
|
icon: Smartphone,
|
||||||
{ text: "Hire Backend Developers", icon: Database, href: "/hire-talent/backend-developers" },
|
href: "/hire-talent/mobile-app-developers",
|
||||||
{ text: "Hire UI/UX Designers", icon: Palette, href: "/hire-talent/ui-ux-designers" },
|
},
|
||||||
{ text: "Hire QA Engineers", icon: TestTube, href: "/hire-talent/qa-engineers" },
|
{
|
||||||
{ text: "Dedicated Development Teams", icon: Users, href: "/dedicated-development-teams" },
|
text: "Hire Full Stack Developers",
|
||||||
|
icon: Code,
|
||||||
|
href: "/hire-talent/full-stack-developers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hire Frontend Developers",
|
||||||
|
icon: Monitor,
|
||||||
|
href: "/hire-talent/frontend-developers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hire Backend Developers",
|
||||||
|
icon: Database,
|
||||||
|
href: "/hire-talent/backend-developers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hire UI/UX Designers",
|
||||||
|
icon: Palette,
|
||||||
|
href: "/hire-talent/ui-ux-designers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hire QA Engineers",
|
||||||
|
icon: TestTube,
|
||||||
|
href: "/hire-talent/qa-engineers",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Dedicated Development Teams",
|
||||||
|
icon: Users,
|
||||||
|
href: "/dedicated-development-teams",
|
||||||
|
},
|
||||||
{ text: "Engagement Models", icon: Settings, href: "/engagement-models" },
|
{ text: "Engagement Models", icon: Settings, href: "/engagement-models" },
|
||||||
{ text: "Team Augmentation Services", icon: Zap, href: "/team-augmentation-services" }
|
{
|
||||||
|
text: "Team Augmentation Services",
|
||||||
|
icon: Zap,
|
||||||
|
href: "/team-augmentation-services",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
company: [
|
company: [
|
||||||
{ text: "About WDI", icon: Info, href: "/company/about-wdi" },
|
{ text: "About WDI", icon: Info, href: "/company/about-wdi" },
|
||||||
{ text: "Our History", icon: Clock, href: "/company/our-history" },
|
{ text: "Our History", icon: Clock, href: "/company/our-history" },
|
||||||
{ text: "Leadership Team", icon: Users2, href: "/company/leadership-team" },
|
{ text: "Leadership Team", icon: Users2, href: "/company/leadership-team" },
|
||||||
{ text: "Awards & Certifications", icon: Award, href: "/company/awards-certifications" },
|
{
|
||||||
|
text: "Awards & Certifications",
|
||||||
|
icon: Award,
|
||||||
|
href: "/company/awards-certifications",
|
||||||
|
},
|
||||||
{ text: "Careers", icon: Briefcase, href: "/company/careers" },
|
{ text: "Careers", icon: Briefcase, href: "/company/careers" },
|
||||||
{ text: "Culture & Values", icon: Heart, href: "/company/culture-values" },
|
{ text: "Culture & Values", icon: Heart, href: "/company/culture-values" },
|
||||||
{ text: "Press & Media", icon: Newspaper, href: "/company/press-media" }
|
{ text: "Press & Media", icon: Newspaper, href: "/company/press-media" },
|
||||||
],
|
],
|
||||||
resources: [
|
resources: [
|
||||||
{ text: "Articles", icon: BookOpen, href: "/resources/blog" },
|
{ text: "Articles", icon: BookOpen, href: "/resources/blog" },
|
||||||
{ text: "Case Studies", icon: FileText, href: "/case-studies" },
|
{ text: "Case Studies", icon: FileText, href: "/case-studies" },
|
||||||
{ text: "Client Testimonials", icon: Star, href: "/resources/client-testimonials" },
|
{
|
||||||
{ text: "Whitepapers & Insights", icon: FileCheck, href: "/resources/whitepapers-insights" },
|
text: "Client Testimonials",
|
||||||
{ text: "FAQs", icon: HelpCircle, href: "/resources/faqs" }
|
icon: Star,
|
||||||
|
href: "/resources/client-testimonials",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Whitepapers & Insights",
|
||||||
|
icon: FileCheck,
|
||||||
|
href: "/resources/whitepapers-insights",
|
||||||
|
},
|
||||||
|
{ text: "FAQs", icon: HelpCircle, href: "/resources/faqs" },
|
||||||
],
|
],
|
||||||
contact: [
|
contact: [
|
||||||
{ text: "Contact Form", icon: Mail, href: "/contact" },
|
{ text: "Contact Form", icon: Mail, href: "/contact" },
|
||||||
{ text: "Request a Proposal", icon: FileCheck, href: "/contact/request-a-proposal" },
|
{
|
||||||
{ text: "Schedule a Discovery Call", icon: Phone, href: "/contact/schedule-a-discovery-call" },
|
text: "Request a Proposal",
|
||||||
{ text: "Office Locations", icon: MapPin, href: "/contact/office-locations" },
|
icon: FileCheck,
|
||||||
{ text: "Client Support", icon: Headphones, href: "/contact/client-support" },
|
href: "/contact/request-a-proposal",
|
||||||
{ text: "Send your CV to HR", icon: UserPlus, href: "/contact/send-your-cv" }
|
},
|
||||||
]
|
{
|
||||||
|
text: "Schedule a Discovery Call",
|
||||||
|
icon: Phone,
|
||||||
|
href: "/contact/schedule-a-discovery-call",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Office Locations",
|
||||||
|
icon: MapPin,
|
||||||
|
href: "/contact/office-locations",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Client Support",
|
||||||
|
icon: Headphones,
|
||||||
|
href: "/contact/client-support",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Send your CV to HR",
|
||||||
|
icon: UserPlus,
|
||||||
|
href: "/contact/send-your-cv",
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// CTA configurations for each mega menu type - UPDATED ALL TO LINK TO START A PROJECT PAGE
|
// CTA configurations for each mega menu type - UPDATED ALL TO LINK TO START A PROJECT PAGE
|
||||||
@@ -288,57 +520,57 @@ const megaMenuCTAs = {
|
|||||||
subtitle: "Get a custom quote for your project",
|
subtitle: "Get a custom quote for your project",
|
||||||
buttonText: "Get Started",
|
buttonText: "Get Started",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Calculator
|
icon: Calculator,
|
||||||
},
|
},
|
||||||
"AI & ML": {
|
"AI & ML": {
|
||||||
title: "AI Strategy Session",
|
title: "AI Strategy Session",
|
||||||
subtitle: "Discover AI opportunities for your business",
|
subtitle: "Discover AI opportunities for your business",
|
||||||
buttonText: "Book Session",
|
buttonText: "Book Session",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Bot
|
icon: Bot,
|
||||||
},
|
},
|
||||||
Solutions: {
|
Solutions: {
|
||||||
title: "Solution Consultation",
|
title: "Solution Consultation",
|
||||||
subtitle: "Find the perfect solution for your business",
|
subtitle: "Find the perfect solution for your business",
|
||||||
buttonText: "Consult Now",
|
buttonText: "Consult Now",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Lightbulb
|
icon: Lightbulb,
|
||||||
},
|
},
|
||||||
Industries: {
|
Industries: {
|
||||||
title: "Industry Expertise",
|
title: "Industry Expertise",
|
||||||
subtitle: "Learn how we transform your industry",
|
subtitle: "Learn how we transform your industry",
|
||||||
buttonText: "Explore",
|
buttonText: "Explore",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Building2
|
icon: Building2,
|
||||||
},
|
},
|
||||||
"Hire Talent": {
|
"Hire Talent": {
|
||||||
title: "Team Assessment",
|
title: "Team Assessment",
|
||||||
subtitle: "Get matched with the right talent",
|
subtitle: "Get matched with the right talent",
|
||||||
buttonText: "Start Hiring",
|
buttonText: "Start Hiring",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Users
|
icon: Users,
|
||||||
},
|
},
|
||||||
Company: {
|
Company: {
|
||||||
title: "Schedule a Call",
|
title: "Schedule a Call",
|
||||||
subtitle: "Let's discuss your project requirements",
|
subtitle: "Let's discuss your project requirements",
|
||||||
buttonText: "Book Call",
|
buttonText: "Book Call",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Calendar
|
icon: Calendar,
|
||||||
},
|
},
|
||||||
Resources: {
|
Resources: {
|
||||||
title: "Free Consultation",
|
title: "Free Consultation",
|
||||||
subtitle: "Get expert insights for your project",
|
subtitle: "Get expert insights for your project",
|
||||||
buttonText: "Get Started",
|
buttonText: "Get Started",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: FileEdit
|
icon: FileEdit,
|
||||||
},
|
},
|
||||||
Contact: {
|
Contact: {
|
||||||
title: "Start Your Project",
|
title: "Start Your Project",
|
||||||
subtitle: "Ready to bring your idea to life?",
|
subtitle: "Ready to bring your idea to life?",
|
||||||
buttonText: "Get Started",
|
buttonText: "Get Started",
|
||||||
href: "/start-a-project",
|
href: "/start-a-project",
|
||||||
icon: Rocket
|
icon: Rocket,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Horizontal CTA Component matching reference design
|
// Horizontal CTA Component matching reference design
|
||||||
@@ -356,7 +588,9 @@ const MegaMenuCTA = ({ type }: { type: string }) => {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h3 className="text-white font-semibold text-lg mb-1">{cta.title}</h3>
|
<h3 className="text-white font-semibold text-lg mb-1">{cta.title}</h3>
|
||||||
<p className="text-gray-400 text-sm leading-relaxed">{cta.subtitle}</p>
|
<p className="text-gray-400 text-sm leading-relaxed">
|
||||||
|
{cta.subtitle}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-6">
|
<div className="ml-6">
|
||||||
<Button
|
<Button
|
||||||
@@ -380,7 +614,13 @@ interface MegaMenuProps {
|
|||||||
timeoutRef?: React.MutableRefObject<NodeJS.Timeout | undefined>;
|
timeoutRef?: React.MutableRefObject<NodeJS.Timeout | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenuProps) => {
|
const MegaMenu = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
onCancelClose,
|
||||||
|
type,
|
||||||
|
timeoutRef,
|
||||||
|
}: MegaMenuProps) => {
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
const navigate = (path: string) => {
|
const navigate = (path: string) => {
|
||||||
@@ -399,7 +639,7 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
<div className="w-10 h-10 rounded-xl bg-[#E5195E]/20 flex items-center justify-center">
|
<div className="w-10 h-10 rounded-xl bg-[#E5195E]/20 flex items-center justify-center">
|
||||||
<Icon className="w-5 h-5 text-[#E5195E]" />
|
<Icon className="w-5 h-5 text-[#E5195E]" />
|
||||||
</div>
|
</div>
|
||||||
<h4
|
<h4
|
||||||
className="font-semibold text-white text-sm cursor-pointer hover:text-[#E5195E] transition-colors"
|
className="font-semibold text-white text-sm cursor-pointer hover:text-[#E5195E] transition-colors"
|
||||||
onClick={() => service.href && navigate(service.href)}
|
onClick={() => service.href && navigate(service.href)}
|
||||||
>
|
>
|
||||||
@@ -409,8 +649,8 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
<ul className="space-y-3">
|
<ul className="space-y-3">
|
||||||
{service.sub_services.map((subService) => (
|
{service.sub_services.map((subService) => (
|
||||||
<li key={subService.name}>
|
<li key={subService.name}>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -443,7 +683,7 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
<div className="w-10 h-10 rounded-xl bg-[#E5195E]/20 flex items-center justify-center">
|
<div className="w-10 h-10 rounded-xl bg-[#E5195E]/20 flex items-center justify-center">
|
||||||
<Icon className="w-5 h-5 text-[#E5195E]" />
|
<Icon className="w-5 h-5 text-[#E5195E]" />
|
||||||
</div>
|
</div>
|
||||||
<h4
|
<h4
|
||||||
className="font-semibold text-white text-lg cursor-pointer hover:text-[#E5195E] transition-colors"
|
className="font-semibold text-white text-lg cursor-pointer hover:text-[#E5195E] transition-colors"
|
||||||
onClick={() => category.href && navigate(category.href)}
|
onClick={() => category.href && navigate(category.href)}
|
||||||
>
|
>
|
||||||
@@ -453,8 +693,8 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
<ul className="space-y-3">
|
<ul className="space-y-3">
|
||||||
{category.sub_services.map((service) => (
|
{category.sub_services.map((service) => (
|
||||||
<li key={service.name}>
|
<li key={service.name}>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -482,9 +722,9 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
{navigationData.solutions.map((solution) => {
|
{navigationData.solutions.map((solution) => {
|
||||||
const Icon = solution.icon;
|
const Icon = solution.icon;
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={solution.text}
|
key={solution.text}
|
||||||
href="#"
|
href="#"
|
||||||
className="flex items-center gap-4 text-[#CCCCCC] hover:text-white transition-all duration-200 p-4 rounded-lg hover:bg-white/5 group"
|
className="flex items-center gap-4 text-[#CCCCCC] hover:text-white transition-all duration-200 p-4 rounded-lg hover:bg-white/5 group"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -523,8 +763,8 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{industry.items.map((item) => (
|
{industry.items.map((item) => (
|
||||||
<li key={item.name}>
|
<li key={item.name}>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
className="text-[#CCCCCC] hover:text-white text-sm transition-colors duration-200 block py-1 hover:translate-x-1 transform"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -552,9 +792,9 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
const Icon = item.icon;
|
const Icon = item.icon;
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={item.text}
|
key={item.text}
|
||||||
href="#"
|
href="#"
|
||||||
className="flex items-center gap-4 text-[#CCCCCC] hover:text-white transition-all duration-200 p-4 rounded-lg hover:bg-white/5 group"
|
className="flex items-center gap-4 text-[#CCCCCC] hover:text-white transition-all duration-200 p-4 rounded-lg hover:bg-white/5 group"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -577,22 +817,22 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
|
|
||||||
const getMenuContent = () => {
|
const getMenuContent = () => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'Services':
|
case "Services":
|
||||||
return renderServicesMenu();
|
return renderServicesMenu();
|
||||||
case 'AI & ML':
|
case "AI & ML":
|
||||||
return renderAIMenu();
|
return renderAIMenu();
|
||||||
case 'Solutions':
|
case "Solutions":
|
||||||
return renderSolutionsMenu();
|
return renderSolutionsMenu();
|
||||||
case 'Industries':
|
case "Industries":
|
||||||
return renderIndustriesMenu();
|
return renderIndustriesMenu();
|
||||||
case 'Hire Talent':
|
case "Hire Talent":
|
||||||
return renderGenericMenu(navigationData.hire_talent, 'Hire Talent');
|
return renderGenericMenu(navigationData.hire_talent, "Hire Talent");
|
||||||
case 'Company':
|
case "Company":
|
||||||
return renderGenericMenu(navigationData.company, 'Company');
|
return renderGenericMenu(navigationData.company, "Company");
|
||||||
case 'Resources':
|
case "Resources":
|
||||||
return renderGenericMenu(navigationData.resources, 'Resources');
|
return renderGenericMenu(navigationData.resources, "Resources");
|
||||||
case 'Contact':
|
case "Contact":
|
||||||
return renderGenericMenu(navigationData.contact, 'Contact');
|
return renderGenericMenu(navigationData.contact, "Contact");
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -605,19 +845,19 @@ const MegaMenu = ({ isOpen, onClose, onCancelClose, type, timeoutRef }: MegaMenu
|
|||||||
exit={{ opacity: 0, y: -20 }}
|
exit={{ opacity: 0, y: -20 }}
|
||||||
transition={{ duration: 0.2 }}
|
transition={{ duration: 0.2 }}
|
||||||
className="absolute top-full left-0 w-full bg-[#121212] backdrop-blur-xl border-t border-white/10 shadow-xl z-50 nav-mega-menu"
|
className="absolute top-full left-0 w-full bg-[#121212] backdrop-blur-xl border-t border-white/10 shadow-xl z-50 nav-mega-menu"
|
||||||
style={{ minHeight: '400px' }}
|
style={{ minHeight: "400px" }}
|
||||||
onMouseEnter={onCancelClose}
|
onMouseEnter={onCancelClose}
|
||||||
onMouseLeave={onClose}
|
onMouseLeave={onClose}
|
||||||
>
|
>
|
||||||
<div className="absolute inset-0 bg-gradient-to-b from-[#121212] to-[#0E0E0E] opacity-95" />
|
<div className="absolute inset-0 bg-gradient-to-b from-[#121212] to-[#0E0E0E] opacity-95" />
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-5"
|
className="absolute inset-0 opacity-5"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `radial-gradient(circle at 1px 1px, rgba(255,255,255,0.1) 1px, transparent 0)`,
|
backgroundImage: `radial-gradient(circle at 1px 1px, rgba(255,255,255,0.1) 1px, transparent 0)`,
|
||||||
backgroundSize: '20px 20px'
|
backgroundSize: "20px 20px",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="relative z-10 container mx-auto px-6 lg:px-8 py-12">
|
<div className="relative z-10 container mx-auto px-6 lg:px-8 py-12">
|
||||||
{getMenuContent()}
|
{getMenuContent()}
|
||||||
</div>
|
</div>
|
||||||
@@ -639,7 +879,17 @@ export const Navigation = () => {
|
|||||||
if (timeoutRef.current) {
|
if (timeoutRef.current) {
|
||||||
clearTimeout(timeoutRef.current);
|
clearTimeout(timeoutRef.current);
|
||||||
}
|
}
|
||||||
if (['Services', 'AI & ML', 'Solutions', 'Industries', 'Hire Talent', 'Company', 'Resources'].includes(item)) {
|
if (
|
||||||
|
[
|
||||||
|
"Services",
|
||||||
|
"AI & ML",
|
||||||
|
"Solutions",
|
||||||
|
"Industries",
|
||||||
|
"Hire Talent",
|
||||||
|
"Company",
|
||||||
|
"Resources",
|
||||||
|
].includes(item)
|
||||||
|
) {
|
||||||
setActiveMenu(item);
|
setActiveMenu(item);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
@@ -656,21 +906,36 @@ export const Navigation = () => {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleNavItemMouseEnter = useCallback((item: string) => {
|
const handleNavItemMouseEnter = useCallback(
|
||||||
cancelClose();
|
(item: string) => {
|
||||||
openMenu(item);
|
cancelClose();
|
||||||
}, [cancelClose, openMenu]);
|
openMenu(item);
|
||||||
|
},
|
||||||
|
[cancelClose, openMenu]
|
||||||
|
);
|
||||||
|
|
||||||
const handleNavItemMouseLeave = useCallback(() => {
|
const handleNavItemMouseLeave = useCallback(() => {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
}, [closeMenu]);
|
}, [closeMenu]);
|
||||||
|
|
||||||
const handleNavMouseLeave = useCallback((e: React.MouseEvent) => {
|
// const handleNavMouseLeave = useCallback((e: React.MouseEvent) => {
|
||||||
const relatedTarget = e.relatedTarget as Element;
|
// const relatedTarget = e.relatedTarget as Element;
|
||||||
if (!navRef.current?.contains(relatedTarget)) {
|
// if (!navRef.current?.contains(relatedTarget)) {
|
||||||
closeMenu();
|
// closeMenu();
|
||||||
}
|
// }
|
||||||
}, [closeMenu]);
|
// }, [closeMenu]);
|
||||||
|
const handleNavMouseLeave = useCallback(
|
||||||
|
(e: React.MouseEvent) => {
|
||||||
|
const relatedTarget = e.relatedTarget;
|
||||||
|
if (
|
||||||
|
relatedTarget instanceof Node &&
|
||||||
|
!navRef.current?.contains(relatedTarget)
|
||||||
|
) {
|
||||||
|
closeMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[closeMenu]
|
||||||
|
);
|
||||||
|
|
||||||
const handleNavMouseEnter = useCallback(() => {
|
const handleNavMouseEnter = useCallback(() => {
|
||||||
cancelClose();
|
cancelClose();
|
||||||
@@ -685,35 +950,43 @@ export const Navigation = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const hasDropdown = (item: string) => {
|
const hasDropdown = (item: string) => {
|
||||||
return ['Services', 'AI & ML', 'Solutions', 'Industries', 'Hire Talent', 'Company', 'Resources'].includes(item);
|
return [
|
||||||
|
"Services",
|
||||||
|
"AI & ML",
|
||||||
|
"Solutions",
|
||||||
|
"Industries",
|
||||||
|
"Hire Talent",
|
||||||
|
"Company",
|
||||||
|
"Resources",
|
||||||
|
].includes(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to get main category page route for navigation items
|
// Function to get main category page route for navigation items
|
||||||
const getMainCategoryRoute = (item: string) => {
|
const getMainCategoryRoute = (item: string) => {
|
||||||
switch (item) {
|
switch (item) {
|
||||||
case 'Services':
|
case "Services":
|
||||||
return '/services';
|
return "/services";
|
||||||
case 'Company':
|
case "Company":
|
||||||
return '/company';
|
return "/company";
|
||||||
case 'Resources':
|
case "Resources":
|
||||||
return '/resources';
|
return "/resources";
|
||||||
case 'Contact':
|
case "Contact":
|
||||||
return '/contact';
|
return "/contact";
|
||||||
case 'Hire Talent':
|
case "Hire Talent":
|
||||||
return '/hire-talent';
|
return "/hire-talent";
|
||||||
case 'AI & ML':
|
case "AI & ML":
|
||||||
return '/artificial-intelligence';
|
return "/artificial-intelligence";
|
||||||
case 'Solutions':
|
case "Solutions":
|
||||||
return '/solutions/digital-product-development'; // Default to first solution
|
return "/solutions/digital-product-development"; // Default to first solution
|
||||||
case 'Industries':
|
case "Industries":
|
||||||
return '/industries/fintech-banking-apps'; // Default to first industry
|
return "/industries/fintech-banking-apps"; // Default to first industry
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
ref={navRef}
|
ref={navRef}
|
||||||
className="fixed top-0 left-0 right-0 z-50 bg-[#0E0E0E]/90 backdrop-blur-lg border-b border-white/10"
|
className="fixed top-0 left-0 right-0 z-50 bg-[#0E0E0E]/90 backdrop-blur-lg border-b border-white/10"
|
||||||
onMouseLeave={handleNavMouseLeave}
|
onMouseLeave={handleNavMouseLeave}
|
||||||
@@ -722,12 +995,12 @@ export const Navigation = () => {
|
|||||||
<div className="container mx-auto px-6 lg:px-8">
|
<div className="container mx-auto px-6 lg:px-8">
|
||||||
<div className="flex items-center justify-between h-20">
|
<div className="flex items-center justify-between h-20">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="flex items-center"
|
className="flex items-center"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
navigate('/');
|
navigate("/");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="w-10 h-10">
|
<div className="w-10 h-10">
|
||||||
@@ -745,7 +1018,7 @@ export const Navigation = () => {
|
|||||||
onMouseLeave={handleNavItemMouseLeave}
|
onMouseLeave={handleNavItemMouseLeave}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={`#${item.toLowerCase().replace(/\s+/g, '-')}`}
|
href={`#${item.toLowerCase().replace(/\s+/g, "-")}`}
|
||||||
className="flex items-center gap-1 text-[#CCCCCC] hover:text-white transition-colors duration-200 py-2 font-medium text-sm xl:text-base whitespace-nowrap"
|
className="flex items-center gap-1 text-[#CCCCCC] hover:text-white transition-colors duration-200 py-2 font-medium text-sm xl:text-base whitespace-nowrap"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -757,7 +1030,11 @@ export const Navigation = () => {
|
|||||||
>
|
>
|
||||||
{item}
|
{item}
|
||||||
{hasDropdown(item) && (
|
{hasDropdown(item) && (
|
||||||
<ChevronDown className={`w-4 h-4 transition-transform duration-200 ${activeMenu === item ? 'rotate-180' : ''}`} />
|
<ChevronDown
|
||||||
|
className={`w-4 h-4 transition-transform duration-200 ${
|
||||||
|
activeMenu === item ? "rotate-180" : ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -765,8 +1042,8 @@ export const Navigation = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-4">
|
||||||
<Button
|
<Button
|
||||||
onClick={() => navigate('/start-a-project')}
|
onClick={() => navigate("/start-a-project")}
|
||||||
className="hidden lg:flex"
|
className="hidden lg:flex"
|
||||||
>
|
>
|
||||||
Get Started
|
Get Started
|
||||||
@@ -777,7 +1054,11 @@ export const Navigation = () => {
|
|||||||
className="lg:hidden text-[#CCCCCC] hover:text-white transition-colors"
|
className="lg:hidden text-[#CCCCCC] hover:text-white transition-colors"
|
||||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||||
>
|
>
|
||||||
{isMobileMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
{isMobileMenuOpen ? (
|
||||||
|
<X className="w-6 h-6" />
|
||||||
|
) : (
|
||||||
|
<Menu className="w-6 h-6" />
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -824,9 +1105,9 @@ export const Navigation = () => {
|
|||||||
{item}
|
{item}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate('/start-a-project');
|
navigate("/start-a-project");
|
||||||
setIsMobileMenuOpen(false);
|
setIsMobileMenuOpen(false);
|
||||||
}}
|
}}
|
||||||
className="w-full mt-4"
|
className="w-full mt-4"
|
||||||
@@ -840,4 +1121,4 @@ export const Navigation = () => {
|
|||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
|
|
||||||
// High-quality placeholder images for the group icons
|
|
||||||
const logoImage1 = "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage2 = "https://images.unsplash.com/photo-1599305445671-ac291c95aaa9?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage3 = "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage4 = "https://images.unsplash.com/photo-1560472355-536de3962603?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage5 = "https://images.unsplash.com/photo-1563986768609-322da13575f3?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage6 = "https://images.unsplash.com/photo-1572177812156-58036aae439c?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage7 = "https://images.unsplash.com/photo-1553484771-371a605b060b?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage8 = "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=120&h=60&fit=crop&auto=format";
|
|
||||||
const logoImage9 = "https://images.unsplash.com/photo-1551650975-87deedd944c3?w=120&h=60&fit=crop&auto=format";
|
|
||||||
|
|
||||||
export default function Group1597880681() {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center justify-center gap-8 flex-wrap opacity-60 hover:opacity-100 transition-opacity duration-300">
|
|
||||||
{/* Client Logos Grid */}
|
|
||||||
<div className="grid grid-cols-3 md:grid-cols-5 lg:grid-cols-9 gap-6 items-center">
|
|
||||||
{[
|
|
||||||
{ src: logoImage1, alt: "Client Logo 1" },
|
|
||||||
{ src: logoImage2, alt: "Client Logo 2" },
|
|
||||||
{ src: logoImage3, alt: "Client Logo 3" },
|
|
||||||
{ src: logoImage4, alt: "Client Logo 4" },
|
|
||||||
{ src: logoImage5, alt: "Client Logo 5" },
|
|
||||||
{ src: logoImage6, alt: "Client Logo 6" },
|
|
||||||
{ src: logoImage7, alt: "Client Logo 7" },
|
|
||||||
{ src: logoImage8, alt: "Client Logo 8" },
|
|
||||||
{ src: logoImage9, alt: "Client Logo 9" }
|
|
||||||
].map((logo, index) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="w-24 h-12 flex items-center justify-center p-2 rounded-lg bg-white/5 backdrop-blur-sm border border-white/10 hover:border-accent/30 transition-all duration-300 hover:scale-105"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={logo.src}
|
|
||||||
alt={logo.alt}
|
|
||||||
className="max-w-full max-h-full object-contain filter brightness-0 invert opacity-70 hover:opacity-100 transition-opacity duration-300"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
63
index.html
63
index.html
@@ -1,33 +1,36 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en" class="dark">
|
<html lang="en" class="dark">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
<head>
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<title>WDI - Web Development & AI Solutions</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="description" content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
<title>WDI - Web Development & AI Solutions</title>
|
||||||
|
<meta name="description"
|
||||||
<!-- Preload Google Fonts -->
|
content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<!-- Preload Google Fonts -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<!-- SEO Meta Tags -->
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<meta property="og:title" content="WDI - Web Development & AI Solutions" />
|
|
||||||
<meta property="og:description" content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
<!-- SEO Meta Tags -->
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:title" content="WDI - Web Development & AI Solutions" />
|
||||||
<meta property="og:url" content="https://wdi.com" />
|
<meta property="og:description"
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
||||||
<meta name="twitter:title" content="WDI - Web Development & AI Solutions" />
|
<meta property="og:type" content="website" />
|
||||||
<meta name="twitter:description" content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
<meta property="og:url" content="https://wdi.com" />
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<!-- Favicon -->
|
<meta name="twitter:title" content="WDI - Web Development & AI Solutions" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<meta name="twitter:description"
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
content="Leading web development and AI solutions provider. Custom software development, mobile apps, and digital transformation services." />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
||||||
<link rel="manifest" href="/site.webmanifest">
|
<!-- Favicon -->
|
||||||
</head>
|
<link rel="shortcut icon" href="https://www.wdipl.com/public/img/favIcon.webp" type="image/x-icon" />
|
||||||
<body>
|
</head>
|
||||||
<div id="root"></div>
|
|
||||||
<script type="module" src="/main.tsx"></script>
|
<body>
|
||||||
</body>
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
11
main.tsx
11
main.tsx
@@ -2,9 +2,14 @@ import { StrictMode } from 'react'
|
|||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
import './styles/globals.css'
|
import './styles/globals.css'
|
||||||
|
import { Provider } from 'react-redux'
|
||||||
|
import store from './src/store/Store.tsx'
|
||||||
|
import { BrowserRouter } from 'react-router-dom'
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<Provider store={store}>
|
||||||
<App />
|
<BrowserRouter>
|
||||||
</StrictMode>,
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
</Provider>,
|
||||||
)
|
)
|
||||||
195
package-lock.json
generated
195
package-lock.json
generated
@@ -33,6 +33,7 @@
|
|||||||
"@radix-ui/react-toggle": "^1.1.9",
|
"@radix-ui/react-toggle": "^1.1.9",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.10",
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
||||||
"@radix-ui/react-tooltip": "^1.2.7",
|
"@radix-ui/react-tooltip": "^1.2.7",
|
||||||
|
"@reduxjs/toolkit": "^2.8.2",
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -48,8 +49,10 @@
|
|||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hook-form": "^7.55.0",
|
"react-hook-form": "^7.55.0",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-resizable-panels": "^2.1.9",
|
"react-resizable-panels": "^2.1.9",
|
||||||
"react-responsive-masonry": "^2.7.1",
|
"react-responsive-masonry": "^2.7.1",
|
||||||
|
"react-router-dom": "^7.6.3",
|
||||||
"react-slick": "^0.30.3",
|
"react-slick": "^0.30.3",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
@@ -63,6 +66,7 @@
|
|||||||
"@types/node": "^24.0.13",
|
"@types/node": "^24.0.13",
|
||||||
"@types/react": "^18.3.23",
|
"@types/react": "^18.3.23",
|
||||||
"@types/react-dom": "^18.3.7",
|
"@types/react-dom": "^18.3.7",
|
||||||
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-slick": "^0.23.13",
|
"@types/react-slick": "^0.23.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
"@typescript-eslint/parser": "^6.21.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
@@ -2389,6 +2393,32 @@
|
|||||||
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@reduxjs/toolkit": {
|
||||||
|
"version": "2.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz",
|
||||||
|
"integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@standard-schema/spec": "^1.0.0",
|
||||||
|
"@standard-schema/utils": "^0.3.0",
|
||||||
|
"immer": "^10.0.3",
|
||||||
|
"redux": "^5.0.1",
|
||||||
|
"redux-thunk": "^3.1.0",
|
||||||
|
"reselect": "^5.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||||
|
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rolldown/pluginutils": {
|
"node_modules/@rolldown/pluginutils": {
|
||||||
"version": "1.0.0-beta.19",
|
"version": "1.0.0-beta.19",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz",
|
||||||
@@ -2656,6 +2686,18 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@standard-schema/spec": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@standard-schema/utils": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@tailwindcss/node": {
|
"node_modules/@tailwindcss/node": {
|
||||||
"version": "4.1.11",
|
"version": "4.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
|
||||||
@@ -3074,6 +3116,13 @@
|
|||||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/history": {
|
||||||
|
"version": "4.7.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
|
||||||
|
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.15",
|
"version": "7.0.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||||
@@ -3119,6 +3168,29 @@
|
|||||||
"@types/react": "^18.0.0"
|
"@types/react": "^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-router": {
|
||||||
|
"version": "5.1.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz",
|
||||||
|
"integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/react-router-dom": {
|
||||||
|
"version": "5.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
|
||||||
|
"integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/history": "^4.7.11",
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-router": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react-slick": {
|
"node_modules/@types/react-slick": {
|
||||||
"version": "0.23.13",
|
"version": "0.23.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.13.tgz",
|
||||||
@@ -3136,6 +3208,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/use-sync-external-store": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
|
||||||
@@ -3959,6 +4037,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/create-require": {
|
"node_modules/create-require": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
@@ -4199,6 +4286,15 @@
|
|||||||
"redux": "^4.2.0"
|
"redux": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dnd-core/node_modules/redux": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/doctrine": {
|
"node_modules/doctrine": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||||
@@ -4894,6 +4990,16 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
@@ -5912,6 +6018,29 @@
|
|||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-redux": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/use-sync-external-store": "^0.0.6",
|
||||||
|
"use-sync-external-store": "^1.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^18.2.25 || ^19",
|
||||||
|
"react": "^18.0 || ^19",
|
||||||
|
"redux": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.17.0",
|
"version": "0.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
||||||
@@ -5985,6 +6114,44 @@
|
|||||||
"integrity": "sha512-Q+u+nOH87PzjqGFd2PgTcmLpHPZnCmUPREHYoNBc8dwJv6fi51p9U6hqwG8g/T8MN86HrFjrU+uQU6yvETU7cA==",
|
"integrity": "sha512-Q+u+nOH87PzjqGFd2PgTcmLpHPZnCmUPREHYoNBc8dwJv6fi51p9U6hqwG8g/T8MN86HrFjrU+uQU6yvETU7cA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "7.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.3.tgz",
|
||||||
|
"integrity": "sha512-zf45LZp5skDC6I3jDLXQUu0u26jtuP4lEGbc7BbdyxenBN1vJSTA18czM2D+h5qyMBuMrD+9uB+mU37HIoKGRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "^1.0.1",
|
||||||
|
"set-cookie-parser": "^2.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "7.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.3.tgz",
|
||||||
|
"integrity": "sha512-DiWJm9qdUAmiJrVWaeJdu4TKu13+iB/8IEi0EW/XgaHCjW/vWGrwzup0GVvaMteuZjKnh5bEvJP/K0MDnzawHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"react-router": "7.6.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-slick": {
|
"node_modules/react-slick": {
|
||||||
"version": "0.30.3",
|
"version": "0.30.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.3.tgz",
|
||||||
@@ -6094,14 +6261,26 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/redux": {
|
"node_modules/redux": {
|
||||||
"version": "4.2.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||||
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
|
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/redux-thunk": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"peerDependencies": {
|
||||||
"@babel/runtime": "^7.9.2"
|
"redux": "^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/reselect": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/resize-observer-polyfill": {
|
"node_modules/resize-observer-polyfill": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||||
@@ -6231,6 +6410,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-cookie-parser": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"@radix-ui/react-toggle": "^1.1.9",
|
"@radix-ui/react-toggle": "^1.1.9",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.10",
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
||||||
"@radix-ui/react-tooltip": "^1.2.7",
|
"@radix-ui/react-tooltip": "^1.2.7",
|
||||||
|
"@reduxjs/toolkit": "^2.8.2",
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -50,8 +51,10 @@
|
|||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hook-form": "^7.55.0",
|
"react-hook-form": "^7.55.0",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-resizable-panels": "^2.1.9",
|
"react-resizable-panels": "^2.1.9",
|
||||||
"react-responsive-masonry": "^2.7.1",
|
"react-responsive-masonry": "^2.7.1",
|
||||||
|
"react-router-dom": "^7.6.3",
|
||||||
"react-slick": "^0.30.3",
|
"react-slick": "^0.30.3",
|
||||||
"recharts": "^2.15.4",
|
"recharts": "^2.15.4",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
@@ -65,6 +68,7 @@
|
|||||||
"@types/node": "^24.0.13",
|
"@types/node": "^24.0.13",
|
||||||
"@types/react": "^18.3.23",
|
"@types/react": "^18.3.23",
|
||||||
"@types/react-dom": "^18.3.7",
|
"@types/react-dom": "^18.3.7",
|
||||||
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-slick": "^0.23.13",
|
"@types/react-slick": "^0.23.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
"@typescript-eslint/parser": "^6.21.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import { Badge } from "../components/ui/badge";
|
|||||||
import { Button } from "../components/ui/button";
|
import { Button } from "../components/ui/button";
|
||||||
import { Card, CardContent } from "../components/ui/card";
|
import { Card, CardContent } from "../components/ui/card";
|
||||||
import { ShimmerButton } from "../components/ui/shimmer-button";
|
import { ShimmerButton } from "../components/ui/shimmer-button";
|
||||||
import Group1597880681 from "../imports/Group1597880681";
|
import Group1597880681 from "../assets/Group1597880681";
|
||||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||||
|
|
||||||
// Enhanced Hero Section with compact mockup and integrated stats
|
// Enhanced Hero Section with compact mockup and integrated stats
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
15
src/services/baseQuery.ts
Normal file
15
src/services/baseQuery.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||||
|
|
||||||
|
const rawBaseQuery = fetchBaseQuery({
|
||||||
|
baseUrl: 'https://wdiplcms.betadelivery.com',
|
||||||
|
});
|
||||||
|
|
||||||
|
const baseQueryWithReauth = async (args: any, api: any, extraOptions: any) => {
|
||||||
|
const result = await rawBaseQuery(args, api, extraOptions);
|
||||||
|
|
||||||
|
// Optional: reauthentication logic if result.error?.status === 401
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default baseQueryWithReauth;
|
||||||
37
src/services/storeContactUs.ts
Normal file
37
src/services/storeContactUs.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// storeContactUs.service.ts
|
||||||
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
|
import baseQueryWithReauth from "./baseQuery";
|
||||||
|
|
||||||
|
export type ContactUsFormData = {
|
||||||
|
t_id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
country: string;
|
||||||
|
phone_number: string;
|
||||||
|
service: string;
|
||||||
|
budget: string;
|
||||||
|
message: string;
|
||||||
|
development_stage: string;
|
||||||
|
startTime: string;
|
||||||
|
nda_signing: string | boolean;
|
||||||
|
from_page: string;
|
||||||
|
ip?: string;
|
||||||
|
user_agent?: string;
|
||||||
|
contact_us_attachment?: File;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const storeContactUs = createApi({
|
||||||
|
reducerPath: "storeContactUs",
|
||||||
|
baseQuery: baseQueryWithReauth,
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
storeContactUs: builder.mutation<void, FormData>({
|
||||||
|
query: (formData) => ({
|
||||||
|
url: "/api/store-contact-us-data",
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { useStoreContactUsMutation } = storeContactUs;
|
||||||
16
src/store/Store.tsx
Normal file
16
src/store/Store.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// store.ts
|
||||||
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
|
import { setupListeners } from '@reduxjs/toolkit/query';
|
||||||
|
import { storeContactUs } from '../services/storeContactUs';
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
[storeContactUs.reducerPath]: storeContactUs.reducer,
|
||||||
|
},
|
||||||
|
middleware: (getDefaultMiddleware) =>
|
||||||
|
getDefaultMiddleware().concat(storeContactUs.middleware),
|
||||||
|
});
|
||||||
|
|
||||||
|
setupListeners(store.dispatch);
|
||||||
|
|
||||||
|
export default store;
|
||||||
Reference in New Issue
Block a user