main layout

This commit is contained in:
pradeepkumar
2026-01-11 22:09:41 +05:30
parent 500c8b6e5d
commit 0c7239d7a8
22 changed files with 1847 additions and 369 deletions

View File

@@ -0,0 +1,68 @@
'use client';
import { AgentCard } from '../ui/AgentCard';
// Sample featured agents data
const featuredAgents = [
{
id: '1',
name: 'Andrew Collins',
title: 'Rental & Investment Consultant',
location: 'New York',
rating: 4.8,
reviewCount: 124,
experience: '8+ years in the real estate industry',
expertise: ['Residential', 'Commercial', 'Investment'],
imageUrl: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '2',
name: 'Dempsi',
title: 'Real Estate & Investment Consultant',
location: 'Atlanta',
rating: 4.9,
reviewCount: 98,
experience: '5+ years in the real estate industry',
expertise: ['Luxury Homes', 'First-time Buyers'],
imageUrl: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '3',
name: 'Daniel',
title: 'Rental & Investment Consultant',
location: 'San Diego',
rating: 4.7,
reviewCount: 156,
experience: '7 years in the real estate industry',
expertise: ['Property Management', 'Rentals'],
imageUrl: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=400&h=400&fit=crop',
isVerified: true,
},
];
export function FeaturedAgents() {
return (
<section className="py-16 md:py-24 bg-[#f5f9f8]">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{featuredAgents.map((agent) => (
<AgentCard
key={agent.id}
name={agent.name}
title={agent.title}
location={agent.location}
rating={agent.rating}
reviewCount={agent.reviewCount}
experience={agent.experience}
expertise={agent.expertise}
imageUrl={agent.imageUrl}
isVerified={agent.isVerified}
/>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,78 @@
'use client';
const features = [
{
icon: (
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
),
title: 'Hire Quickly',
description: 'Connect with experienced local real estate agents who match your needs and preferences. Get answers quickly and move forward on your property decisions.',
},
{
icon: (
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
),
title: 'Verified Agents',
description: 'All agents are carefully vetted and background checked to ensure that you work with professionals who meet quality and reliability standards.',
},
{
icon: (
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />
</svg>
),
title: 'Top Rated',
description: 'Find highly rated agents based on positive client feedback. Their credentials and contributions have made them standout performers in the industry.',
},
{
icon: (
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
),
title: 'Trusted by Thousands',
description: 'Thousands of buyers, sellers, and investors have relied on our platform. Our professionals help people navigate property tax-free gift exchanges.',
},
];
export function FeaturesSection() {
return (
<section className="py-16 md:py-24 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-[#00293d] mb-4">
Find Trusted Real Estate Professionals On Demand
</h2>
<p className="text-gray-600 max-w-2xl mx-auto">
Quickly connect with the right agents exactly when you need them.
</p>
</div>
{/* Features Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{features.map((feature, index) => (
<div
key={index}
className="text-center p-6 rounded-xl hover:bg-[#f5f9f8] transition-colors"
>
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#c4d9d4]/30 text-[#00293d] mb-4">
{feature.icon}
</div>
<h3 className="text-xl font-bold text-[#00293d] mb-3">
{feature.title}
</h3>
<p className="text-gray-600 text-sm leading-relaxed">
{feature.description}
</p>
</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,153 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { Button } from '../ui/Button';
const propertyTypes = [
{ value: 'residential', label: 'Residential' },
{ value: 'commercial', label: 'Commercial' },
{ value: 'luxury', label: 'Luxury Homes' },
{ value: 'rentals', label: 'Rentals' },
];
const categories = [
{ value: 'buying', label: 'Buying Agent' },
{ value: 'selling', label: 'Selling Agent' },
{ value: 'investment', label: 'Investment' },
{ value: 'property-management', label: 'Property Management' },
];
export function HeroSection() {
const router = useRouter();
const [searchParams, setSearchParams] = useState({
type: '',
name: '',
location: '',
category: '',
});
const handleSearch = () => {
const params = new URLSearchParams();
if (searchParams.type) params.set('type', searchParams.type);
if (searchParams.name) params.set('name', searchParams.name);
if (searchParams.location) params.set('location', searchParams.location);
if (searchParams.category) params.set('category', searchParams.category);
router.push(`/agents?${params.toString()}`);
};
return (
<section className="relative bg-gradient-to-b from-[#e8f0ee] to-[#f5f9f8] overflow-hidden">
{/* Background Pattern */}
<div className="absolute inset-0 opacity-10">
<svg className="w-full h-full" viewBox="0 0 1440 600" fill="none">
{/* City Skyline Pattern */}
<rect x="100" y="400" width="60" height="200" fill="#00293d"/>
<rect x="180" y="350" width="80" height="250" fill="#00293d"/>
<rect x="280" y="380" width="50" height="220" fill="#00293d"/>
<rect x="350" y="300" width="100" height="300" fill="#00293d"/>
<rect x="470" y="420" width="40" height="180" fill="#00293d"/>
<rect x="900" y="380" width="70" height="220" fill="#00293d"/>
<rect x="990" y="320" width="90" height="280" fill="#00293d"/>
<rect x="1100" y="400" width="60" height="200" fill="#00293d"/>
<rect x="1180" y="350" width="80" height="250" fill="#00293d"/>
<rect x="1280" y="420" width="50" height="180" fill="#00293d"/>
</svg>
</div>
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 md:py-24">
{/* Headline */}
<div className="text-center mb-10">
<h1 className="text-3xl md:text-4xl lg:text-5xl font-bold text-[#00293d] mb-4 leading-tight">
&ldquo;Discover verified, top-rated real estate professionals to guide your buying, selling, or investing journey.&rdquo;
</h1>
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
Discover verified, top-rated real estate professionals
</p>
</div>
{/* Search Form */}
<div className="bg-white rounded-2xl shadow-xl p-6 md:p-8 max-w-5xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
{/* Type Select */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Types</label>
<select
value={searchParams.type}
onChange={(e) => setSearchParams({ ...searchParams, type: e.target.value })}
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all bg-white"
>
<option value="">Professionals</option>
{propertyTypes.map((type) => (
<option key={type.value} value={type.value}>{type.label}</option>
))}
</select>
</div>
{/* Name Input */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Name or Nickname</label>
<input
type="text"
placeholder="Name or Nickname"
value={searchParams.name}
onChange={(e) => setSearchParams({ ...searchParams, name: e.target.value })}
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all"
/>
</div>
{/* Location Input */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Location</label>
<input
type="text"
placeholder="Location"
value={searchParams.location}
onChange={(e) => setSearchParams({ ...searchParams, location: e.target.value })}
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all"
/>
</div>
{/* Category Select */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Categories</label>
<select
value={searchParams.category}
onChange={(e) => setSearchParams({ ...searchParams, category: e.target.value })}
className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all bg-white"
>
<option value="">Select Category</option>
{categories.map((cat) => (
<option key={cat.value} value={cat.value}>{cat.label}</option>
))}
</select>
</div>
</div>
{/* Quick Links */}
<div className="flex flex-wrap gap-2 mb-6">
<button className="text-sm text-[#00293d] hover:text-[#f5a623] transition-colors">
Professionals
</button>
<span className="text-gray-300">|</span>
<button className="text-sm text-[#00293d] hover:text-[#f5a623] transition-colors">
Lenders
</button>
</div>
{/* Search Button */}
<div className="flex justify-center">
<Button variant="primary" size="lg" onClick={handleSearch}>
See All Agents
</Button>
</div>
{/* Helper Text */}
<p className="text-center text-gray-500 text-sm mt-4">
Connect with trusted local agents to explore homes, compare options, and make smarter decisions.
</p>
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,105 @@
'use client';
const testimonials = [
{
id: '1',
rating: 5,
title: 'I have been working with Lorem...',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nulla lorem. Fusce dui diam, auctor nec ligula vel. Congue pharetra leo. Praesent scelerisque diam, sed lacinia mauris commodo in. Fusce dui diam, auctor nec.',
author: 'Caren Robert',
role: 'Chief Operations Officer',
},
{
id: '2',
rating: 5,
title: 'I have been working with Lorem...',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nulla lorem. Fusce dui diam, auctor nec ligula vel. Congue pharetra leo. Praesent scelerisque diam, sed lacinia mauris commodo in. Fusce dui diam, auctor nec.',
author: 'Caren Robert',
role: 'Chief Operations Officer',
},
{
id: '3',
rating: 5,
title: 'I have been working with Lorem...',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nulla lorem. Fusce dui diam, auctor nec ligula vel. Congue pharetra leo. Praesent scelerisque diam, sed lacinia mauris commodo in. Fusce dui diam, auctor nec.',
author: 'Caren Robert',
role: 'Chief Operations Officer',
},
];
function StarRating({ rating }: { rating: number }) {
return (
<div className="flex gap-1">
{[...Array(5)].map((_, i) => (
<svg
key={i}
className={`w-5 h-5 ${i < rating ? 'text-[#f5a623]' : 'text-gray-300'}`}
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg>
))}
</div>
);
}
export function TestimonialsSection() {
return (
<section className="py-16 md:py-24 bg-[#f5f9f8]">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-[#00293d] mb-4">
Our Clients&apos; Trust Is Our Foundation
</h2>
<p className="text-gray-600 max-w-2xl mx-auto mb-6">
We help buyers, sellers, and investors close successful real estate deals with confidence in every transaction.
</p>
<p className="text-gray-600">
Clients rate our real estate services an average of 4.8 on average, based on recent client reviews.
</p>
</div>
{/* Rating Summary */}
<div className="flex justify-center items-center gap-8 mb-12">
<div className="flex items-center gap-2">
<span className="text-3xl font-bold text-[#00293d]">4.8 / 5 Stars</span>
</div>
<div className="flex items-center gap-2">
<span className="text-gray-600">1,200+ Happy Clients</span>
</div>
</div>
{/* Testimonials Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{testimonials.map((testimonial) => (
<div
key={testimonial.id}
className="bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-shadow"
>
{/* Rating */}
<div className="mb-4">
<StarRating rating={testimonial.rating} />
</div>
{/* Title */}
<h3 className="font-bold text-[#00293d] mb-3">{testimonial.title}</h3>
{/* Content */}
<p className="text-gray-600 text-sm mb-6 leading-relaxed">
{testimonial.content}
</p>
{/* Author */}
<div className="border-t pt-4">
<p className="font-semibold text-[#00293d]">{testimonial.author}</p>
<p className="text-sm text-gray-500">{testimonial.role}</p>
</div>
</div>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,169 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { AgentCard } from '../ui/AgentCard';
import { Button } from '../ui/Button';
// Sample agents data for tabs
const agentsData = [
{
id: '1',
name: 'Arjun Mehta',
title: 'Professional/General Agent',
location: 'San Francisco, CA',
rating: 4.9,
reviewCount: 87,
experience: '6+ years in the real estate industry',
expertise: ['Residential', 'Luxury', 'Commercial'],
imageUrl: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '2',
name: 'Arjun Mehta',
title: 'Top-tier Real Agent',
location: 'San Francisco, CA',
rating: 4.8,
reviewCount: 65,
experience: '8+ years in the real estate industry',
expertise: ['Investment', 'Commercial', 'Property Management'],
imageUrl: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '3',
name: 'Arjun Mehta',
title: 'Verified Real Agent',
location: 'San Francisco, CA',
rating: 4.7,
reviewCount: 42,
experience: '6+ years in the real estate industry',
expertise: ['Residential', 'First-time Buyers', 'Rentals'],
imageUrl: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=400&h=400&fit=crop',
isVerified: true,
},
];
const lendersData = [
{
id: '4',
name: 'Sarah Johnson',
title: 'Mortgage Specialist',
location: 'Los Angeles, CA',
rating: 4.9,
reviewCount: 112,
experience: '10+ years in mortgage lending',
expertise: ['FHA Loans', 'Conventional', 'VA Loans'],
imageUrl: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '5',
name: 'Michael Chen',
title: 'Senior Loan Officer',
location: 'Seattle, WA',
rating: 4.8,
reviewCount: 89,
experience: '7+ years in lending',
expertise: ['Jumbo Loans', 'Refinancing', 'Investment'],
imageUrl: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=400&h=400&fit=crop',
isVerified: true,
},
{
id: '6',
name: 'Emily Davis',
title: 'Home Loan Advisor',
location: 'Austin, TX',
rating: 4.7,
reviewCount: 76,
experience: '5+ years in mortgage industry',
expertise: ['First-time Buyers', 'FHA', 'USDA Loans'],
imageUrl: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=400&h=400&fit=crop',
isVerified: true,
},
];
export function TopProfessionals() {
const [activeTab, setActiveTab] = useState<'agents' | 'lenders'>('agents');
const displayData = activeTab === 'agents' ? agentsData : lendersData;
return (
<section className="py-16 md:py-24 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="text-center mb-10">
<h2 className="text-3xl md:text-4xl font-bold text-[#00293d] mb-4">
&ldquo;Meet top real estate professionals&rdquo;
</h2>
</div>
{/* Tabs */}
<div className="flex justify-center gap-4 mb-10">
<button
onClick={() => setActiveTab('agents')}
className={`px-8 py-3 rounded-full font-medium transition-all ${
activeTab === 'agents'
? 'bg-[#00293d] text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
Agents
</button>
<button
onClick={() => setActiveTab('lenders')}
className={`px-8 py-3 rounded-full font-medium transition-all ${
activeTab === 'lenders'
? 'bg-[#00293d] text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
Lenders
</button>
</div>
{/* Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-10">
{displayData.map((professional) => (
<AgentCard
key={professional.id}
name={professional.name}
title={professional.title}
location={professional.location}
rating={professional.rating}
reviewCount={professional.reviewCount}
experience={professional.experience}
expertise={professional.expertise}
imageUrl={professional.imageUrl}
isVerified={professional.isVerified}
/>
))}
{/* Browse Experts CTA Card */}
<div className="bg-[#f5a623]/10 rounded-2xl p-8 flex flex-col items-center justify-center text-center">
<p className="text-[#00293d] font-medium mb-2">
Discover 6,000+ Top Real Estate Agents in Our Network
</p>
<Link href="/agents">
<Button variant="primary" size="md">
Browse Experts
</Button>
</Link>
</div>
</div>
{/* Pagination Dots */}
<div className="flex justify-center gap-2">
{[0, 1, 2, 3].map((dot) => (
<button
key={dot}
className={`w-2 h-2 rounded-full transition-all ${
dot === 0 ? 'bg-[#f5a623] w-8' : 'bg-gray-300 hover:bg-gray-400'
}`}
/>
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,131 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { signOut } from 'next-auth/react';
interface AgentHeaderProps {
userName?: string | null;
userEmail?: string | null;
}
const navLinks = [
{ label: 'Education', href: '/education' },
{ label: 'About Us', href: '/about' },
{ label: "FAQ's", href: '/faq' },
];
export function AgentHeader({ userName, userEmail }: AgentHeaderProps) {
const [showProfileMenu, setShowProfileMenu] = useState(false);
return (
<header className="bg-[#648188] rounded-[20px] px-8">
<div className="flex justify-between items-center h-[70px]">
{/* Logo */}
<Link href="/agent/dashboard">
<Image
src="/assets/logo.svg"
alt="RE-QuestN"
width={150}
height={40}
className="h-10 w-auto"
/>
</Link>
{/* Navigation */}
<nav className="hidden md:flex items-center gap-8 ml-auto mr-8">
{navLinks.map((link) => (
<Link
key={link.href}
href={link.href}
className="font-bold text-[#00293d] text-base hover:text-[#e58625] transition-colors"
>
{link.label}
</Link>
))}
</nav>
{/* Right Side Icons */}
<div className="flex items-center gap-3">
{/* Notification Bell */}
<button className="relative p-1 hover:opacity-80 transition-opacity">
<Image
src="/assets/notification-icon.svg"
alt="Notifications"
width={18}
height={21}
/>
{/* Notification Dot */}
<span className="absolute top-0 right-0 w-1.5 h-1.5 bg-red-500 rounded-full"></span>
</button>
{/* Profile Icon with Dropdown */}
<div className="relative">
<button
onClick={() => setShowProfileMenu(!showProfileMenu)}
className="w-6 h-6 rounded-full overflow-hidden hover:opacity-80 transition-opacity"
>
<Image
src="/assets/profile-icon.svg"
alt="Profile"
width={24}
height={24}
className="w-full h-full"
/>
</button>
{/* Profile Dropdown Menu */}
{showProfileMenu && (
<div className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg py-2 z-50">
<div className="px-4 py-2 border-b border-gray-100">
<p className="text-sm font-medium text-[#00293d]">
{userName || 'Agent'}
</p>
<p className="text-xs text-gray-500">{userEmail}</p>
</div>
<Link
href="/agent/dashboard"
className="block px-4 py-2 text-sm text-[#00293d] hover:bg-gray-50"
onClick={() => setShowProfileMenu(false)}
>
Dashboard
</Link>
<Link
href="/agent/settings"
className="block px-4 py-2 text-sm text-[#00293d] hover:bg-gray-50"
onClick={() => setShowProfileMenu(false)}
>
Settings
</Link>
<button
onClick={() => signOut({ callbackUrl: '/login' })}
className="w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-50"
>
Sign Out
</button>
</div>
)}
</div>
{/* Mobile Menu Button */}
<button className="md:hidden p-2 hover:opacity-80 transition-opacity">
<svg
className="w-6 h-6 text-[#00293d]"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
</div>
</div>
</header>
);
}

View File

@@ -0,0 +1,220 @@
'use client';
import Link from 'next/link';
import Image from 'next/image';
const footerLinks = {
services: {
title: 'Services',
links: [
{ label: 'Neighborhood Guides', href: '/neighborhood-guides' },
{ label: 'Home Loan & EMI Calculator', href: '/calculator' },
],
},
serviceProviders: {
title: 'Service Providers',
links: [
{ label: 'Agent', href: '/agents' },
{ label: 'Lenders', href: '/lenders' },
],
},
resources: {
title: 'Resources',
links: [
{ label: "Buyer's Guide", href: '/buyers-guide' },
{ label: "Seller's Guide", href: '/sellers-guide' },
{ label: 'FAQs', href: '/faq' },
{ label: 'Blogs', href: '/blogs' },
{ label: 'Legal & Documentation Help', href: '/legal-help' },
],
},
aboutContact: {
title: 'About & Contact',
links: [
{ label: 'About Our Agency', href: '/about' },
{ label: 'Our Agents', href: '/agents' },
{ label: 'Testimonials', href: '/testimonials' },
{ label: 'Careers', href: '/careers' },
{ label: 'Contact Us', href: '/contact' },
{ label: 'Privacy Policy', href: '/privacy-policy' },
{ label: 'Terms & Conditions', href: '/terms' },
],
},
};
const socialLinks = [
{
name: 'LinkedIn',
href: '#',
icon: (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg>
),
bgColor: 'bg-[#0077b5]',
},
{
name: 'Instagram',
href: '#',
icon: (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
</svg>
),
bgColor: 'bg-gradient-to-br from-[#f09433] via-[#e6683c] to-[#bc1888]',
},
{
name: 'Facebook',
href: '#',
icon: (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" />
</svg>
),
bgColor: 'bg-[#1877f2]',
},
{
name: 'Twitter',
href: '#',
icon: (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z" />
</svg>
),
bgColor: 'bg-[#1da1f2]',
},
];
export function Footer() {
return (
<footer className="bg-[#8fa9a8] text-[#00293d]">
{/* Main Footer Content */}
<div className="max-w-7xl mx-auto px-6 py-12">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8 lg:gap-12">
{/* Services */}
<div>
<h3 className="font-bold text-[#e58625] text-sm mb-4 pb-2 border-b-2 border-[#e58625] inline-block">
{footerLinks.services.title}
</h3>
<ul className="space-y-3">
{footerLinks.services.links.map((link) => (
<li key={link.href}>
<Link
href={link.href}
className="text-sm hover:text-[#e58625] transition-colors"
>
{link.label}
</Link>
</li>
))}
</ul>
</div>
{/* Service Providers */}
<div>
<h3 className="font-bold text-[#e58625] text-sm mb-4 pb-2 border-b-2 border-[#e58625] inline-block">
{footerLinks.serviceProviders.title}
</h3>
<ul className="space-y-3">
{footerLinks.serviceProviders.links.map((link) => (
<li key={link.href}>
<Link
href={link.href}
className="text-sm hover:text-[#e58625] transition-colors"
>
{link.label}
</Link>
</li>
))}
</ul>
</div>
{/* Resources */}
<div>
<h3 className="font-bold text-[#e58625] text-sm mb-4 pb-2 border-b-2 border-[#e58625] inline-block">
{footerLinks.resources.title}
</h3>
<ul className="space-y-3">
{footerLinks.resources.links.map((link) => (
<li key={link.href}>
<Link
href={link.href}
className="text-sm hover:text-[#e58625] transition-colors"
>
{link.label}
</Link>
</li>
))}
</ul>
</div>
{/* About & Contact */}
<div>
<h3 className="font-bold text-[#e58625] text-sm mb-4 pb-2 border-b-2 border-[#e58625] inline-block">
{footerLinks.aboutContact.title}
</h3>
<ul className="space-y-3">
{footerLinks.aboutContact.links.map((link) => (
<li key={link.href}>
<Link
href={link.href}
className="text-sm hover:text-[#e58625] transition-colors"
>
{link.label}
</Link>
</li>
))}
</ul>
</div>
</div>
</div>
{/* Logo and Social Section */}
<div className="border-t border-[#00293d]/20">
<div className="max-w-7xl mx-auto px-6 py-6">
<div className="flex flex-col md:flex-row items-center justify-between gap-6">
{/* Logo and Tagline */}
<div className="flex items-center gap-4">
<Image
src="/assets/logo.svg"
alt="RE-Quest"
width={150}
height={40}
className="h-10 w-auto"
/>
<span className="text-sm text-[#00293d]">
"Your Trusted Real Estate Partner"
</span>
</div>
{/* Social Links */}
<div className="flex items-center gap-3">
{socialLinks.map((social) => (
<a
key={social.name}
href={social.href}
className={`w-7 h-7 ${social.bgColor} rounded flex items-center justify-center text-white hover:opacity-80 transition-opacity`}
aria-label={social.name}
>
{social.icon}
</a>
))}
</div>
</div>
</div>
</div>
{/* Copyright Section */}
<div className="border-t border-[#00293d]/20">
<div className="max-w-7xl mx-auto px-6 py-4">
<div className="flex flex-col md:flex-row items-center justify-between gap-4 text-sm">
<p>Copyright © 2025 Your Agency Name. All rights reserved.</p>
<Link href="/privacy-policy" className="hover:text-[#e58625] transition-colors">
Privacy Policy
</Link>
</div>
</div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,82 @@
'use client';
import Link from 'next/link';
import Image from 'next/image';
import { useSession } from 'next-auth/react';
import { Button } from '../ui/Button';
export function Header() {
const { data: session } = useSession();
return (
<header className="bg-[#00293d] text-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-20">
{/* Logo */}
<Link href="/" className="flex items-center gap-2">
<Image
src="/assets/logo-white.svg"
alt="RE-Quest"
width={150}
height={40}
className="h-10 w-auto"
/>
</Link>
{/* Navigation */}
<nav className="hidden md:flex items-center gap-8">
<Link href="/education" className="hover:text-[#f5a623] transition-colors">
Education
</Link>
<Link href="/about" className="hover:text-[#f5a623] transition-colors">
About Us
</Link>
<Link href="/faq" className="hover:text-[#f5a623] transition-colors">
FAQ&apos;s
</Link>
</nav>
{/* Right Side */}
<div className="flex items-center gap-4">
{session ? (
<>
{/* Notification Bell */}
<button className="p-2 hover:bg-white/10 rounded-full transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
{/* Profile */}
<Link href="/user/userprofile" className="p-2 hover:bg-white/10 rounded-full transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
</Link>
</>
) : (
<div className="flex items-center gap-3">
<Link href="/login">
<Button variant="outline" size="sm" className="border-white text-white hover:bg-white hover:text-[#00293d]">
Login
</Button>
</Link>
<Link href="/register">
<Button variant="primary" size="sm">
Sign Up
</Button>
</Link>
</div>
)}
{/* Mobile Menu Button */}
<button className="md:hidden p-2 hover:bg-white/10 rounded-lg transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
</div>
</div>
</header>
);
}

View File

@@ -0,0 +1,104 @@
'use client';
import Image from 'next/image';
interface AgentCardProps {
name: string;
title: string;
location: string;
rating?: number;
reviewCount?: number;
experience: string;
expertise: string[];
imageUrl: string;
isVerified?: boolean;
isFeatured?: boolean;
}
export function AgentCard({
name,
title,
location,
rating,
reviewCount,
experience,
expertise,
imageUrl,
isVerified = false,
isFeatured = false,
}: AgentCardProps) {
return (
<div className={`bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow ${isFeatured ? 'border-2 border-[#f5a623]' : ''}`}>
{/* Image */}
<div className="relative h-64 bg-gray-100">
<Image
src={imageUrl}
alt={name}
fill
className="object-cover"
/>
{isVerified && (
<div className="absolute top-3 left-3 bg-[#00293d] text-white text-xs px-2 py-1 rounded-full flex items-center gap-1">
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
Verified Agent
</div>
)}
</div>
{/* Content */}
<div className="p-5">
<h3 className="font-bold text-lg text-[#00293d]">{name}</h3>
<p className="text-gray-600 text-sm mb-2">{title}</p>
{/* Location */}
<div className="flex items-center gap-1 text-gray-500 text-sm mb-3">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
{location}
</div>
{/* Rating */}
{rating && (
<div className="flex items-center gap-2 mb-3">
<div className="flex">
{[...Array(5)].map((_, i) => (
<svg
key={i}
className={`w-4 h-4 ${i < Math.floor(rating) ? 'text-[#f5a623]' : 'text-gray-300'}`}
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg>
))}
</div>
{reviewCount && (
<span className="text-sm text-gray-500">({reviewCount} reviews)</span>
)}
</div>
)}
{/* Expertise Tags */}
<div className="flex flex-wrap gap-2 mb-3">
{expertise.slice(0, 3).map((tag) => (
<span
key={tag}
className="bg-[#c4d9d4]/30 text-[#00293d] text-xs px-2 py-1 rounded-full"
>
{tag}
</span>
))}
</div>
{/* Experience */}
<p className="text-sm text-gray-600">
<span className="font-medium">Experience:</span> {experience}
</p>
</div>
</div>
);
}

View File

@@ -0,0 +1,40 @@
'use client';
import { ButtonHTMLAttributes, ReactNode } from 'react';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline';
size?: 'sm' | 'md' | 'lg';
children: ReactNode;
}
export function Button({
variant = 'primary',
size = 'md',
children,
className = '',
...props
}: ButtonProps) {
const baseStyles = 'font-medium rounded-lg transition-all duration-200 inline-flex items-center justify-center';
const variants = {
primary: 'bg-[#f5a623] text-white hover:bg-[#e09620] active:bg-[#c98a1c]',
secondary: 'bg-[#00293d] text-white hover:bg-[#003a57] active:bg-[#001f2e]',
outline: 'border-2 border-[#00293d] text-[#00293d] hover:bg-[#00293d] hover:text-white',
};
const sizes = {
sm: 'px-4 py-2 text-sm',
md: 'px-6 py-3 text-base',
lg: 'px-8 py-4 text-lg',
};
return (
<button
className={`${baseStyles} ${variants[variant]} ${sizes[size]} ${className}`}
{...props}
>
{children}
</button>
);
}

View File

@@ -0,0 +1,29 @@
'use client';
import { InputHTMLAttributes, ReactNode } from 'react';
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
icon?: ReactNode;
}
export function Input({ label, icon, className = '', ...props }: InputProps) {
return (
<div className="flex flex-col gap-1">
{label && (
<label className="text-sm font-medium text-[#00293d]">{label}</label>
)}
<div className="relative">
{icon && (
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">
{icon}
</span>
)}
<input
className={`w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all ${icon ? 'pl-10' : ''} ${className}`}
{...props}
/>
</div>
</div>
);
}

View File

@@ -0,0 +1,43 @@
'use client';
import { SelectHTMLAttributes } from 'react';
interface SelectOption {
value: string;
label: string;
}
interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
label?: string;
options: SelectOption[];
placeholder?: string;
}
export function Select({
label,
options,
placeholder = 'Select...',
className = '',
...props
}: SelectProps) {
return (
<div className="flex flex-col gap-1">
{label && (
<label className="text-sm font-medium text-[#00293d]">{label}</label>
)}
<select
className={`w-full px-4 py-3 rounded-lg border border-gray-200 focus:border-[#00293d] focus:ring-2 focus:ring-[#00293d]/20 outline-none transition-all bg-white appearance-none cursor-pointer ${className}`}
{...props}
>
<option value="" disabled>
{placeholder}
</option>
{options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
);
}