first commit
This commit is contained in:
225
app/(public)/_homeComponents/About.tsx
Normal file
225
app/(public)/_homeComponents/About.tsx
Normal file
@@ -0,0 +1,225 @@
|
||||
import React from 'react';
|
||||
import { motion, Variants } from 'framer-motion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { ArrowRight, CheckCircle, Users, Target, Award, Sparkles } from 'lucide-react';
|
||||
import { home } from '@/services/Constants';
|
||||
|
||||
|
||||
const AboutUs: React.FC = () => {
|
||||
|
||||
const containerVariants:Variants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.2,
|
||||
delayChildren: 0.3
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const itemVariants:Variants = {
|
||||
hidden: { opacity: 0, y: 20 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.6, ease: "easeOut" }
|
||||
}
|
||||
};
|
||||
|
||||
const imageVariants:Variants = {
|
||||
hidden: { opacity: 0, scale: 0.8 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
transition: { duration: 0.8, ease: "easeOut" }
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-16 md:py-24 bg-white overflow-hidden">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||
{/* Left Side - Images */}
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
variants={containerVariants}
|
||||
className="relative"
|
||||
>
|
||||
{/* Main Large Image */}
|
||||
<motion.div
|
||||
variants={imageVariants}
|
||||
className="relative z-10 rounded-2xl overflow-hidden shadow-2xl"
|
||||
>
|
||||
<div className="aspect-[4/3] bg-gradient-to-br from-blue-100 via-purple-50 to-pink-100 flex items-center justify-center">
|
||||
<div className="text-center p-8">
|
||||
<div className="w-24 h-24 mx-auto mb-4 bg-gradient-to-br from-blue-500 to-purple-600 rounded-2xl flex items-center justify-center">
|
||||
<Users className="w-12 h-12 text-white" />
|
||||
</div>
|
||||
<p className="text-gray-600 font-medium">Team Collaboration</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Top Right Small Image */}
|
||||
<motion.div
|
||||
variants={imageVariants}
|
||||
transition={{ delay: 0.2 }}
|
||||
className="absolute -top-6 -right-6 w-32 h-32 md:w-40 md:h-40 z-20"
|
||||
>
|
||||
<div className="w-full h-full rounded-xl overflow-hidden shadow-xl bg-gradient-to-br from-orange-100 to-red-100 flex items-center justify-center border-4 border-white">
|
||||
<Sparkles className="w-12 h-12 text-orange-500" />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Bottom Left Small Image */}
|
||||
<motion.div
|
||||
variants={imageVariants}
|
||||
transition={{ delay: 0.4 }}
|
||||
className="absolute -bottom-8 -left-8 w-36 h-36 md:w-44 md:h-44 z-20"
|
||||
>
|
||||
<div className="w-full h-full rounded-2xl overflow-hidden shadow-xl bg-gradient-to-br from-green-100 to-teal-100 flex items-center justify-center border-4 border-white">
|
||||
<Award className="w-14 h-14 text-green-600" />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Bottom Right Floating Card */}
|
||||
<motion.div
|
||||
variants={imageVariants}
|
||||
transition={{ delay: 0.6 }}
|
||||
className="absolute bottom-4 right-4 z-30 bg-white rounded-xl shadow-2xl p-4 border border-gray-100"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
|
||||
<Target className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-gray-900">500K+</p>
|
||||
<p className="text-xs text-gray-500">Successful Hires</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Decorative Elements */}
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1, 1.2, 1],
|
||||
rotate: [0, 90, 0]
|
||||
}}
|
||||
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
|
||||
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-blue-100 rounded-full blur-3xl opacity-30 -z-10"
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Side - Content */}
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
variants={containerVariants}
|
||||
className="space-y-6"
|
||||
>
|
||||
<motion.div variants={itemVariants}>
|
||||
<Badge className="mb-4 px-4 py-2 bg-blue-50 text-blue-600 border-blue-200 hover:bg-blue-100">
|
||||
<Sparkles className="w-4 h-4 mr-2 inline" />
|
||||
{home.about.badge}
|
||||
</Badge>
|
||||
</motion.div>
|
||||
|
||||
<motion.h2
|
||||
variants={itemVariants}
|
||||
className="text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900 leading-tight"
|
||||
>
|
||||
{home.about.heading}
|
||||
</motion.h2>
|
||||
|
||||
<motion.h3
|
||||
variants={itemVariants}
|
||||
className="text-xl sm:text-2xl font-semibold text-blue-600"
|
||||
>
|
||||
{home.about.subheading}
|
||||
</motion.h3>
|
||||
|
||||
<motion.p
|
||||
variants={itemVariants}
|
||||
className="text-gray-600 text-lg leading-relaxed"
|
||||
>
|
||||
{home.about.description}
|
||||
</motion.p>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<motion.div
|
||||
variants={itemVariants}
|
||||
className="grid grid-cols-3 gap-4 py-6"
|
||||
>
|
||||
{home.about.stats.map((stat, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="text-center p-4 rounded-xl bg-gradient-to-br from-gray-50 to-blue-50 border border-gray-100"
|
||||
>
|
||||
<stat.icon className="w-8 h-8 mx-auto mb-2 text-blue-600" />
|
||||
<p className="text-2xl font-bold text-gray-900">{stat.value}</p>
|
||||
<p className="text-xs text-gray-600 mt-1">{stat.label}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Highlights */}
|
||||
<motion.div variants={itemVariants} className="space-y-3">
|
||||
{home.about.highlights.map((highlight, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.8 + index * 0.1 }}
|
||||
className="flex items-center gap-3"
|
||||
>
|
||||
<div className="flex-shrink-0 w-6 h-6 bg-green-100 rounded-full flex items-center justify-center">
|
||||
<CheckCircle className="w-4 h-4 text-green-600" />
|
||||
</div>
|
||||
<span className="text-gray-700">{highlight}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* CTA Button */}
|
||||
<motion.div variants={itemVariants} className="pt-4">
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white shadow-lg hover:shadow-xl transition-all duration-300"
|
||||
>
|
||||
{home.about.cta}
|
||||
<ArrowRight className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
</motion.div>
|
||||
|
||||
{/* Trust Badge */}
|
||||
<motion.div
|
||||
variants={itemVariants}
|
||||
className="flex items-center gap-2 pt-4 text-sm text-gray-500"
|
||||
>
|
||||
<div className="flex -space-x-2">
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-400 to-purple-400 border-2 border-white flex items-center justify-center text-white text-xs font-bold"
|
||||
>
|
||||
{i}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<span>Trusted by 15,000+ companies worldwide</span>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutUs;
|
||||
30
app/(public)/_homeComponents/Animated.tsx
Normal file
30
app/(public)/_homeComponents/Animated.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion, useInView } from "framer-motion";
|
||||
|
||||
|
||||
// Animated Section Wrapper
|
||||
const AnimatedSection = ({
|
||||
children,
|
||||
className = "",
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
const ref = React.useRef(null);
|
||||
const isInView = useInView(ref, { once: true, margin: "-100px" });
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
|
||||
transition={{ duration: 0.6, ease: "easeOut" }}
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AnimatedSection
|
||||
52
app/(public)/_homeComponents/Benefits.tsx
Normal file
52
app/(public)/_homeComponents/Benefits.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
|
||||
|
||||
// Benefits Section
|
||||
const Benefits = () => {
|
||||
return (
|
||||
<section
|
||||
id="solutions"
|
||||
className="py-24 bg-gradient-to-br from-purple-600 to-pink-600 text-white relative overflow-hidden"
|
||||
>
|
||||
<div className="absolute inset-0 opacity-10">
|
||||
<div className="absolute top-0 left-0 w-96 h-96 bg-white rounded-full filter blur-3xl" />
|
||||
<div className="absolute bottom-0 right-0 w-96 h-96 bg-white rounded-full filter blur-3xl" />
|
||||
</div>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 relative z-10">
|
||||
<AnimatedSection className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||
Why Choose TalentFlow?
|
||||
</h2>
|
||||
<p className="text-xl text-purple-100 max-w-3xl mx-auto">
|
||||
Experience the future of recruitment with our innovative platform
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{home.benefits.map((benefit, index) => (
|
||||
<AnimatedSection key={index}>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="text-center p-8 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 hover:bg-white/20 transition-all"
|
||||
>
|
||||
<div className="w-16 h-16 mx-auto mb-6 rounded-full bg-white/20 flex items-center justify-center">
|
||||
<div className="text-white">{benefit.icon}</div>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-3">{benefit.title}</h3>
|
||||
<p className="text-purple-100">{benefit.description}</p>
|
||||
</motion.div>
|
||||
</AnimatedSection>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Benefits
|
||||
50
app/(public)/_homeComponents/CTA.tsx
Normal file
50
app/(public)/_homeComponents/CTA.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
ArrowRight,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
|
||||
// CTA Section
|
||||
const CTA = () => {
|
||||
return (
|
||||
<section className="py-24 bg-gradient-to-r from-purple-700 to-pink-600 text-white text-center relative overflow-hidden">
|
||||
<motion.div
|
||||
className="absolute top-0 left-0 w-full h-full opacity-20"
|
||||
animate={{ scale: [1, 1.1, 1] }}
|
||||
transition={{ duration: 10, repeat: Infinity }}
|
||||
>
|
||||
<div className="absolute bg-white rounded-full w-96 h-96 blur-3xl -top-10 -left-10"></div>
|
||||
</motion.div>
|
||||
|
||||
<div className="relative z-10 max-w-4xl mx-auto px-4">
|
||||
<h2 className="text-4xl md:text-6xl font-bold mb-6">
|
||||
Ready to Transform Your Hiring?
|
||||
</h2>
|
||||
<p className="text-lg md:text-xl text-purple-100 mb-10">
|
||||
Join 10,000+ HR teams using TalentFlow to hire smarter and faster
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Button
|
||||
size="lg"
|
||||
className="px-10 py-6 text-lg bg-white text-purple-700 font-bold rounded-xl shadow-lg hover:text-white hover:shadow-2xl hover:scale-105 transition-transform"
|
||||
>
|
||||
Start Free Trial <ArrowRight className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="border-2 text-purple-700 px-10 py-6 text-lg font-bold rounded-xl hover:bg-white/10 transition-all"
|
||||
>
|
||||
Book a Demo
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default CTA
|
||||
51
app/(public)/_homeComponents/CompanySlider.tsx
Normal file
51
app/(public)/_homeComponents/CompanySlider.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
|
||||
|
||||
|
||||
// Company Logos Slider
|
||||
const CompanySlider = () => {
|
||||
return (
|
||||
<section className="py-16 bg-white">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<AnimatedSection>
|
||||
<p className="text-center text-gray-600 font-semibold mb-12">
|
||||
TRUSTED BY LEADING COMPANIES WORLDWIDE
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<div className="relative overflow-hidden">
|
||||
<motion.div
|
||||
animate={{ x: ["0%", "-50%"] }}
|
||||
transition={{
|
||||
duration: 30,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
}}
|
||||
className="flex gap-12 items-center"
|
||||
>
|
||||
{[...home.companies, ...home.companies].map(
|
||||
(company, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center gap-3 px-6 py-4 bg-gray-50 rounded-xl min-w-fit hover:bg-gray-100 transition-colors"
|
||||
>
|
||||
<span className="text-4xl">{company.logo}</span>
|
||||
<span className="text-xl font-bold text-gray-800 whitespace-nowrap">
|
||||
{company.name}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default CompanySlider
|
||||
68
app/(public)/_homeComponents/FAQ.tsx
Normal file
68
app/(public)/_homeComponents/FAQ.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
|
||||
|
||||
// FAQ Section
|
||||
const FAQ = () => {
|
||||
return (
|
||||
<section
|
||||
id="faq"
|
||||
className="py-24 bg-gradient-to-b from-white to-purple-50"
|
||||
>
|
||||
<div className="max-w-4xl mx-auto px-4">
|
||||
<AnimatedSection className="text-center mb-16">
|
||||
<span className="inline-block px-4 py-2 bg-purple-100 text-purple-700 rounded-full text-sm font-semibold mb-4">
|
||||
FAQ
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||
Frequently Asked{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
|
||||
Questions
|
||||
</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600">
|
||||
Everything you need to know about TalentFlow
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<AnimatedSection>
|
||||
<Accordion type="single" collapsible className="space-y-4">
|
||||
{home.faq.map((item, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: index * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<AccordionItem
|
||||
value={`item-${index}`}
|
||||
className="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow border-0 px-6"
|
||||
>
|
||||
<AccordionTrigger className="text-left font-semibold text-lg hover:no-underline py-6">
|
||||
{item.question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="text-gray-600 pb-6 leading-relaxed">
|
||||
{item.answer}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</motion.div>
|
||||
))}
|
||||
</Accordion>
|
||||
</AnimatedSection>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default FAQ
|
||||
63
app/(public)/_homeComponents/Features.tsx
Normal file
63
app/(public)/_homeComponents/Features.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
// Features Section
|
||||
const Features = () => {
|
||||
return (
|
||||
<section
|
||||
id="features"
|
||||
className="py-24 bg-gradient-to-b from-white to-purple-50"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<AnimatedSection className="text-center mb-16">
|
||||
<span className="inline-block px-4 py-2 bg-purple-100 text-purple-700 rounded-full text-sm font-semibold mb-4">
|
||||
POWERFUL FEATURES
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||
Everything You Need to{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
|
||||
Hire Smarter
|
||||
</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
Our comprehensive ATS platform combines cutting-edge AI with
|
||||
intuitive design to revolutionize your recruitment process.
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{home.features.map((feature, index) => (
|
||||
<AnimatedSection key={index}>
|
||||
<motion.div
|
||||
whileHover={{ y: -8, scale: 1.02 }}
|
||||
className="h-full"
|
||||
>
|
||||
<Card className="h-full border-0 shadow-xl hover:shadow-2xl transition-all duration-300 overflow-hidden group">
|
||||
<CardContent className="p-8">
|
||||
<div
|
||||
className={`w-14 h-14 rounded-xl bg-gradient-to-br ${feature.color} flex items-center justify-center mb-6 group-hover:scale-110 transition-transform`}
|
||||
>
|
||||
<div className="text-white">{feature.icon}</div>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold mb-3 text-gray-800">
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className="text-gray-600 leading-relaxed">
|
||||
{feature.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
</AnimatedSection>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Features
|
||||
91
app/(public)/_homeComponents/Footer.tsx
Normal file
91
app/(public)/_homeComponents/Footer.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Twitter,
|
||||
Linkedin,
|
||||
Github,
|
||||
Facebook,
|
||||
Instagram,
|
||||
MessageCircle,
|
||||
} from "lucide-react";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className="bg-gray-950 text-gray-300 pt-10 pb-10 relative overflow-hidden">
|
||||
{/* Glow Background */}
|
||||
<div className="absolute inset-0 opacity-5 bg-gradient-to-br from-purple-600 to-pink-600 blur-3xl" />
|
||||
|
||||
<div className="relative max-w-7xl mx-auto px-6 flex flex-wrap justify-between gap-10">
|
||||
|
||||
{/* Brand (Logo Update Section) */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.03 }}
|
||||
className="min-w-[230px] flex-1"
|
||||
>
|
||||
<div className="flex items-center mb-4 gap-3">
|
||||
|
||||
{/* White background for logo */}
|
||||
<div className="w-50 h-12 bg-white rounded-xl flex items-center justify-center shadow-lg">
|
||||
{/* Replace this image with your actual logo */}
|
||||
<img
|
||||
src="/logo.png"
|
||||
alt="Company Logo"
|
||||
className="w-50 h-12 object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm opacity-80 max-w-xs">
|
||||
Hire smarter & faster — AI screening, automation & collaborative
|
||||
recruitment tools.
|
||||
</p>
|
||||
|
||||
{/* Social Icons */}
|
||||
<div className="flex gap-4 mt-6">
|
||||
{[Facebook, Instagram, MessageCircle, Twitter, Linkedin, Github].map(
|
||||
(Icon, idx) => (
|
||||
<Icon
|
||||
key={idx}
|
||||
className="w-6 h-6 hover:text-white hover:scale-110 transition cursor-pointer"
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Footer Links */}
|
||||
{[
|
||||
["Product", ["Features", "Solutions", "Pricing", "Security"]],
|
||||
["Company", ["About Us", "Careers", "Blog", "Contact"]],
|
||||
["Support", ["FAQ", "Help Center", "Guides"]],
|
||||
].map((col, idx) => (
|
||||
<motion.div
|
||||
key={idx}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
className="min-w-[140px]"
|
||||
>
|
||||
<h4 className="font-semibold text-white text-lg mb-4">{col[0]}</h4>
|
||||
<ul className="space-y-3">
|
||||
{(col[1] as string[]).map((item, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="hover:text-white cursor-pointer text-sm opacity-80 hover:opacity-100 transition"
|
||||
>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Bottom */}
|
||||
<div className="mt-14 pt-6 border-t border-gray-700/40 text-center text-sm opacity-70">
|
||||
© {new Date().getFullYear()} — All rights reserved.
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
107
app/(public)/_homeComponents/Header.tsx
Normal file
107
app/(public)/_homeComponents/Header.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
const Header = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setScrolled(window.scrollY > 10);
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<motion.header
|
||||
initial={{ y: -80 }}
|
||||
animate={{ y: 0 }}
|
||||
className={`fixed top-0 w-full z-50 transition-all duration-300
|
||||
${scrolled ? "bg-white shadow-lg" : "bg-white md:bg-transparent"}
|
||||
`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center py-4">
|
||||
|
||||
{/* 🔥 Logo */}
|
||||
<motion.div whileHover={{ scale: 1.05 }}>
|
||||
<Link href="/">
|
||||
<img
|
||||
src="/logo.png"
|
||||
alt="Company Logo"
|
||||
className="w-36 h-auto object-contain cursor-pointer"
|
||||
/>
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
{/* 🖥️ Desktop Navigation */}
|
||||
<nav className="hidden md:flex items-center space-x-8">
|
||||
{home.navigation.map((item) => (
|
||||
<motion.div key={item.name} whileHover={{ scale: 1.05 }}>
|
||||
<Link
|
||||
href={item.href}
|
||||
className="text-gray-700 hover:text-purple-600 font-medium"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="hidden md:flex items-center space-x-4">
|
||||
<Button variant="ghost" className="font-medium">
|
||||
Sign In
|
||||
</Button>
|
||||
<Button className="bg-gradient-to-r from-purple-600 to-pink-600 text-white font-medium">
|
||||
Start Free Trial
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 📱 Mobile Menu Icon */}
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="md:hidden p-2 rounded-lg hover:bg-gray-100"
|
||||
>
|
||||
{isOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 📱 Mobile Drawer Menu */}
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: "auto" }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="md:hidden pb-6"
|
||||
>
|
||||
<div className="flex flex-col space-y-4">
|
||||
{home.navigation.map((item) => (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className="text-gray-700 hover:text-purple-600 font-medium"
|
||||
onClick={() => setIsOpen(false)}
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
<Button variant="outline" className="w-full">
|
||||
Sign In
|
||||
</Button>
|
||||
<Button className="w-full bg-gradient-to-r from-purple-600 to-pink-600">
|
||||
Start Free Trial
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</motion.header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
139
app/(public)/_homeComponents/Hero.tsx
Normal file
139
app/(public)/_homeComponents/Hero.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Check,
|
||||
ArrowRight,
|
||||
PlayCircle,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<section className="relative pt-32 pb-20 px-4 overflow-hidden bg-gradient-to-br from-purple-50 via-pink-50 to-blue-50">
|
||||
{/* Animated Background Elements */}
|
||||
<div className="absolute inset-0 overflow-hidden">
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1, 1.2, 1],
|
||||
rotate: [0, 90, 0],
|
||||
}}
|
||||
transition={{ duration: 20, repeat: Infinity }}
|
||||
className="absolute -top-20 -left-20 w-72 h-72 bg-purple-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30"
|
||||
/>
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1.2, 1, 1.2],
|
||||
rotate: [90, 0, 90],
|
||||
}}
|
||||
transition={{ duration: 25, repeat: Infinity }}
|
||||
className="absolute top-40 -right-20 w-96 h-96 bg-pink-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30"
|
||||
/>
|
||||
<motion.div
|
||||
animate={{
|
||||
scale: [1, 1.3, 1],
|
||||
rotate: [0, -90, 0],
|
||||
}}
|
||||
transition={{ duration: 30, repeat: Infinity }}
|
||||
className="absolute -bottom-20 left-1/2 w-96 h-96 bg-blue-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="max-w-7xl mx-auto relative z-10">
|
||||
<div className="text-center max-w-4xl mx-auto">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<span className="inline-block px-4 py-2 bg-purple-100 text-purple-700 rounded-full text-sm font-semibold mb-6">
|
||||
✨ AI-Powered Recruitment Platform
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.1 }}
|
||||
className="text-5xl md:text-7xl font-bold mb-6 leading-tight"
|
||||
>
|
||||
Hire Top Talent{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 via-pink-600 to-blue-600 bg-clip-text text-transparent">
|
||||
10x Faster
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-xl md:text-2xl text-gray-600 mb-10 leading-relaxed"
|
||||
>
|
||||
The world's most intelligent ATS that automates screening,
|
||||
scheduling, and hiring. Join 10,000+ companies who trust TalentFlow.
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 }}
|
||||
className="flex flex-col sm:flex-row gap-4 justify-center items-center"
|
||||
>
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white px-8 py-6 text-lg font-semibold rounded-xl shadow-xl hover:shadow-2xl transform hover:scale-105 transition-all"
|
||||
>
|
||||
Start Free Trial
|
||||
<ArrowRight className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="px-8 py-6 text-lg font-semibold rounded-xl border-2 hover:bg-gray-50"
|
||||
>
|
||||
<PlayCircle className="mr-2 w-5 h-5" />
|
||||
Watch Demo
|
||||
</Button>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6, delay: 0.4 }}
|
||||
className="mt-8 flex items-center justify-center gap-2 text-sm text-gray-600"
|
||||
>
|
||||
<Check className="w-5 h-5 text-green-500" />
|
||||
<span>No credit card required</span>
|
||||
<span className="mx-2">•</span>
|
||||
<Check className="w-5 h-5 text-green-500" />
|
||||
<span>14-day free trial</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Stats Section */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.5 }}
|
||||
className="mt-20 grid grid-cols-2 md:grid-cols-4 gap-8"
|
||||
>
|
||||
{home.stats.map((stat, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="text-center p-6 rounded-2xl bg-white/80 backdrop-blur-sm shadow-lg"
|
||||
>
|
||||
<div className="text-4xl md:text-5xl font-bold bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent mb-2">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-gray-600 font-medium">{stat.label}</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero
|
||||
74
app/(public)/_homeComponents/Pricing.tsx
Normal file
74
app/(public)/_homeComponents/Pricing.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
"use client";
|
||||
import React, { } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Check,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
|
||||
|
||||
// Pricing Section
|
||||
const Pricing = () => {
|
||||
return (
|
||||
<section
|
||||
id="pricing"
|
||||
className="py-24 bg-gradient-to-t from-purple-50 to-white"
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<AnimatedSection className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||
Simple & Transparent{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
|
||||
Pricing
|
||||
</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
Choose a plan that fits your hiring scale
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-10">
|
||||
{home.plans.map((plan, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
whileHover={{ y: -10 }}
|
||||
className={`p-10 rounded-3xl shadow-xl transition-all border
|
||||
${
|
||||
plan.highlight
|
||||
? "bg-gradient-to-br from-purple-600 to-pink-600 text-white scale-105"
|
||||
: "bg-white"
|
||||
}`}
|
||||
>
|
||||
<h3 className="text-2xl font-bold mb-4">{plan.name}</h3>
|
||||
<div className="text-5xl font-bold mb-2">{plan.price}</div>
|
||||
<p className="text-sm opacity-80 mb-6">{plan.period}</p>
|
||||
<ul className="space-y-3 mb-8">
|
||||
{plan.features.map((f, i) => (
|
||||
<li key={i} className="flex items-center gap-2 text-sm">
|
||||
<Check className="w-5 h-5 text-green-400" />
|
||||
{f}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Button
|
||||
variant={plan.highlight ? "secondary" : "default"}
|
||||
className={`w-full py-6 font-semibold rounded-xl ${
|
||||
plan.highlight
|
||||
? "bg-white text-purple-600 hover:shadow-2xl"
|
||||
: "bg-gradient-to-r from-purple-600 to-pink-600 text-white"
|
||||
}`}
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pricing
|
||||
104
app/(public)/_homeComponents/Testimonials.tsx
Normal file
104
app/(public)/_homeComponents/Testimonials.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Star,
|
||||
Quote,
|
||||
} from "lucide-react";
|
||||
import AnimatedSection from "./Animated";
|
||||
import { home } from "@/services/Constants";
|
||||
|
||||
|
||||
// Testimonials Slider
|
||||
const Testimonials = () => {
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentIndex((prev) => (prev + 1) % home.testimonials.length);
|
||||
}, 5000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section id="testimonials" className="py-24 bg-white">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<AnimatedSection className="text-center mb-16">
|
||||
<span className="inline-block px-4 py-2 bg-purple-100 text-purple-700 rounded-full text-sm font-semibold mb-4">
|
||||
TESTIMONIALS
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-6">
|
||||
Loved by{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
|
||||
Hiring Teams
|
||||
</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
See what our customers have to say about their experience
|
||||
</p>
|
||||
</AnimatedSection>
|
||||
|
||||
<div className="relative max-w-5xl mx-auto">
|
||||
<div className="overflow-hidden">
|
||||
{home.testimonials.map((testimonial, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: 100 }}
|
||||
animate={{
|
||||
opacity: index === currentIndex ? 1 : 0,
|
||||
x: index === currentIndex ? 0 : 100,
|
||||
display: index === currentIndex ? "block" : "none",
|
||||
}}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="bg-gradient-to-br from-purple-50 to-pink-50 rounded-3xl p-12 shadow-xl"
|
||||
>
|
||||
<Quote className="w-12 h-12 text-purple-300 mb-6" />
|
||||
<p className="text-2xl text-gray-800 mb-8 leading-relaxed italic">
|
||||
"{testimonial.content}"
|
||||
</p>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-16 h-16 rounded-full bg-gradient-to-br from-purple-400 to-pink-400 flex items-center justify-center text-3xl">
|
||||
{testimonial.image}
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg text-gray-800">
|
||||
{testimonial.name}
|
||||
</h4>
|
||||
<p className="text-gray-600">{testimonial.role}</p>
|
||||
<p className="text-purple-600 font-semibold">
|
||||
{testimonial.company}
|
||||
</p>
|
||||
</div>
|
||||
<div className="ml-auto flex gap-1">
|
||||
{[...Array(testimonial.rating)].map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className="w-5 h-5 fill-yellow-400 text-yellow-400"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-2 mt-8">
|
||||
{home.testimonials.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setCurrentIndex(index)}
|
||||
className={`w-3 h-3 rounded-full transition-all ${
|
||||
index === currentIndex
|
||||
? "bg-purple-600 w-8"
|
||||
: "bg-gray-300 hover:bg-gray-400"
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Testimonials
|
||||
158
app/(public)/contact/_components/ContactForm.tsx
Normal file
158
app/(public)/contact/_components/ContactForm.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
"use client"
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import {
|
||||
Send,
|
||||
CheckCircle} from 'lucide-react';
|
||||
|
||||
|
||||
|
||||
// Contact Form Component
|
||||
const ContactForm: React.FC = () => {
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
message: ''
|
||||
});
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
||||
const handleSubmit = () => {
|
||||
console.log('Form submitted:', formData);
|
||||
setSubmitted(true);
|
||||
setTimeout(() => setSubmitted(false), 3000);
|
||||
};
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
setFormData({
|
||||
...formData,
|
||||
[e.target.name]: e.target.value
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-3xl mx-auto mb-20"
|
||||
>
|
||||
<Card className="bg-white border-gray-200 shadow-xl">
|
||||
<CardContent className="p-8 md:p-12">
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
Send us a message
|
||||
</h2>
|
||||
<p className="text-gray-600">
|
||||
Fill out the form below and we'll get back to you within 24 hours
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{submitted ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
className="text-center py-12"
|
||||
>
|
||||
<div className="w-20 h-20 mx-auto mb-6 bg-green-100 rounded-full flex items-center justify-center">
|
||||
<CheckCircle className="w-10 h-10 text-green-600" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-2">Thank you!</h3>
|
||||
<p className="text-gray-600">Your message has been sent successfully.</p>
|
||||
</motion.div>
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Full Name *
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
placeholder="John Doe"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Email Address *
|
||||
</label>
|
||||
<Input
|
||||
type="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
placeholder="john@example.com"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Phone Number *
|
||||
</label>
|
||||
<Input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleChange}
|
||||
placeholder="+1 (555) 000-0000"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Address
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
name="address"
|
||||
value={formData.address}
|
||||
onChange={handleChange}
|
||||
placeholder="City, Country"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Message *
|
||||
</label>
|
||||
<Textarea
|
||||
name="message"
|
||||
value={formData.message}
|
||||
onChange={handleChange}
|
||||
placeholder="Tell us how we can help you..."
|
||||
rows={6}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
size="lg"
|
||||
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white"
|
||||
>
|
||||
Send Message
|
||||
<Send className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContactForm
|
||||
46
app/(public)/contact/_components/GetInTouch.tsx
Normal file
46
app/(public)/contact/_components/GetInTouch.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client"
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { CONTACT_DATA } from '@/services/Constants';
|
||||
|
||||
|
||||
|
||||
// Get In Touch Component
|
||||
const GetInTouch: React.FC = () => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
className="bg-gray-50 rounded-3xl p-8 md:p-12 mb-20"
|
||||
>
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
{CONTACT_DATA.getInTouch.title}
|
||||
</h2>
|
||||
<p className="text-gray-600 max-w-2xl mx-auto">
|
||||
{CONTACT_DATA.getInTouch.description}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{CONTACT_DATA.getInTouch.methods.map((method, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: index * 0.1 }}
|
||||
className="text-center"
|
||||
>
|
||||
<div className={`w-16 h-16 mx-auto mb-4 bg-white rounded-2xl shadow-md flex items-center justify-center ${method.color}`}>
|
||||
<method.icon className="w-8 h-8" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">{method.title}</h3>
|
||||
<p className="text-gray-600 text-sm mb-2">{method.description}</p>
|
||||
<p className={`font-semibold ${method.color}`}>{method.contact}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default GetInTouch
|
||||
51
app/(public)/contact/_components/GlobalOffices.tsx
Normal file
51
app/(public)/contact/_components/GlobalOffices.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
"use client"
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import {MapPin} from 'lucide-react';
|
||||
import { CONTACT_DATA } from '@/services/Constants';
|
||||
|
||||
|
||||
|
||||
// Global Offices Component
|
||||
const GlobalOffices: React.FC = () => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center mb-20"
|
||||
>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
{CONTACT_DATA.offices.title}
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-12">{CONTACT_DATA.offices.description}</p>
|
||||
<div className="grid md:grid-cols-2 gap-8 max-w-4xl mx-auto">
|
||||
{CONTACT_DATA.offices.locations.map((location, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: index * 0.2 }}
|
||||
whileHover={{ y: -5 }}
|
||||
>
|
||||
<Card className="bg-white border-gray-200 hover:shadow-lg transition-all duration-300">
|
||||
<CardContent className="p-8 text-center">
|
||||
<div className="text-6xl mb-4">{location.icon}</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4">{location.city}</h3>
|
||||
<div className="flex items-start justify-center gap-2 text-gray-600">
|
||||
<MapPin className="w-5 h-5 flex-shrink-0 mt-1 text-blue-600" />
|
||||
<div>
|
||||
<p>{location.address}</p>
|
||||
<p>{location.address2}</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default GlobalOffices
|
||||
73
app/(public)/contact/_components/HappyCustomers.tsx
Normal file
73
app/(public)/contact/_components/HappyCustomers.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
"use client"
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import {
|
||||
Users,
|
||||
Star
|
||||
} from 'lucide-react';
|
||||
import { CONTACT_DATA } from '@/services/Constants';
|
||||
|
||||
|
||||
// Happy Customers Component
|
||||
const HappyCustomers: React.FC = () => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
className="bg-gradient-to-br from-purple-50 via-blue-50 to-pink-50 rounded-3xl p-8 md:p-12"
|
||||
>
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid lg:grid-cols-2 gap-8 items-center">
|
||||
<div>
|
||||
<Badge className="mb-4 px-4 py-2 bg-yellow-100 text-yellow-800 border-yellow-300">
|
||||
<Star className="w-4 h-4 mr-2 inline fill-yellow-500" />
|
||||
{CONTACT_DATA.customers.badge}
|
||||
</Badge>
|
||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold text-gray-900 mb-6">
|
||||
{CONTACT_DATA.customers.title}
|
||||
<span className="text-orange-600">{CONTACT_DATA.customers.highlight}</span>
|
||||
</h2>
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-gradient-to-r from-purple-600 to-blue-600 hover:from-purple-700 hover:to-blue-700 text-white"
|
||||
>
|
||||
Try for FREE
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<Users className="w-8 h-8 text-purple-600" />
|
||||
<div>
|
||||
<p className="text-3xl font-bold text-gray-900">{CONTACT_DATA.customers.count}</p>
|
||||
<p className="text-sm text-gray-600">{CONTACT_DATA.customers.label}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
{CONTACT_DATA.customers.logos.map((logo, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: index * 0.05 }}
|
||||
whileHover={{ scale: 1.1 }}
|
||||
>
|
||||
<div className="bg-white rounded-xl p-4 shadow-md hover:shadow-lg transition-all duration-300 flex items-center justify-center h-20">
|
||||
<span className={`font-bold text-lg ${logo.color}`}>{logo.name}</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default HappyCustomers
|
||||
31
app/(public)/contact/_components/HeroSection.tsx
Normal file
31
app/(public)/contact/_components/HeroSection.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { CONTACT_DATA } from "@/services/Constants";
|
||||
|
||||
const HeroSection: React.FC = () => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="text-center mb-16 mt-10"
|
||||
>
|
||||
<Badge className="mb-4 px-4 py-2 bg-purple-100 text-purple-700">
|
||||
{CONTACT_DATA.hero.badge}
|
||||
</Badge>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold text-gray-900 mb-6">
|
||||
{CONTACT_DATA.hero.title}{" "}
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">
|
||||
us
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl text-gray-600 mb-2 max-w-3xl mx-auto">
|
||||
{CONTACT_DATA.hero.description}
|
||||
</p>
|
||||
<p className="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
{CONTACT_DATA.hero.subtitle}
|
||||
</p>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default HeroSection;
|
||||
43
app/(public)/contact/_components/QuickActions.tsx
Normal file
43
app/(public)/contact/_components/QuickActions.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
"use client"
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { CONTACT_DATA } from '@/services/Constants';
|
||||
|
||||
// Quick Actions Component
|
||||
const QuickActions: React.FC = () => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
className="grid md:grid-cols-2 gap-8 mb-20"
|
||||
>
|
||||
{CONTACT_DATA.quickActions.map((action, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: index * 0.2 }}
|
||||
>
|
||||
<Card className="bg-white border-gray-200 hover:shadow-lg transition-all duration-300 h-full">
|
||||
<CardContent className="p-8 text-center">
|
||||
<div className={`w-16 h-16 mx-auto mb-6 bg-gradient-to-br ${action.color} rounded-2xl flex items-center justify-center`}>
|
||||
<action.icon className="w-8 h-8 text-purple-600" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-gray-900 mb-4">{action.title}</h3>
|
||||
<p className="text-gray-600 mb-6 leading-relaxed">
|
||||
{action.description}
|
||||
</p>
|
||||
<Button variant="outline" className="border-purple-300 text-purple-600 hover:bg-purple-50">
|
||||
{action.cta}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export default QuickActions
|
||||
42
app/(public)/contact/page.tsx
Normal file
42
app/(public)/contact/page.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
"use client"
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import {
|
||||
Headphones,
|
||||
LifeBuoy,
|
||||
Mail,
|
||||
MessageSquare,
|
||||
Phone,
|
||||
MapPin,
|
||||
Send,
|
||||
CheckCircle,
|
||||
Users,
|
||||
Star
|
||||
} from 'lucide-react';
|
||||
import HeroSection from './_components/HeroSection';
|
||||
import QuickActions from './_components/QuickActions';
|
||||
import GetInTouch from './_components/GetInTouch';
|
||||
import GlobalOffices from './_components/GlobalOffices';
|
||||
import ContactForm from './_components/ContactForm';
|
||||
import HappyCustomers from './_components/HappyCustomers';
|
||||
|
||||
// Main Contact Page Component
|
||||
export default function ContactUsPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-white">
|
||||
<div className="px-4 sm:px-4 lg:px-10 py-16 md:py-24">
|
||||
<HeroSection />
|
||||
<QuickActions />
|
||||
<GetInTouch />
|
||||
<GlobalOffices />
|
||||
<ContactForm />
|
||||
<HappyCustomers />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
36
app/(public)/layout.tsx
Normal file
36
app/(public)/layout.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "../globals.css";
|
||||
|
||||
|
||||
import Footer from "./_homeComponents/Footer";
|
||||
import Header from "./_homeComponents/Header";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Winixco",
|
||||
description: "ATS",
|
||||
};
|
||||
|
||||
export default function PublicLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
28
app/(public)/page.tsx
Normal file
28
app/(public)/page.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import Header from "./_homeComponents/Header";
|
||||
import Hero from "./_homeComponents/Hero";
|
||||
import CompanySlider from "./_homeComponents/CompanySlider";
|
||||
import Features from "./_homeComponents/Features";
|
||||
import Benefits from "./_homeComponents/Benefits";
|
||||
import Testimonials from "./_homeComponents/Testimonials";
|
||||
import Pricing from "./_homeComponents/Pricing";
|
||||
import FAQ from "./_homeComponents/FAQ";
|
||||
import CTA from "./_homeComponents/CTA";
|
||||
import AboutUs from "./_homeComponents/About";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="min-h-screen bg-white">
|
||||
<Hero />
|
||||
<CompanySlider />
|
||||
<Features />
|
||||
<AboutUs />
|
||||
<Benefits />
|
||||
<Testimonials />
|
||||
<Pricing />
|
||||
<FAQ />
|
||||
<CTA />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user