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,3 @@
<svg width="24" height="28" viewBox="0 0 24 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 22.6667V24H0V22.6667L2.66667 20V12C2.66667 7.86667 5.37333 4.22667 9.33333 3.05333V2.66667C9.33333 1.95942 9.61429 1.28115 10.1144 0.781049C10.6145 0.280952 11.2928 0 12 0C12.7072 0 13.3855 0.280952 13.8856 0.781049C14.3857 1.28115 14.6667 1.95942 14.6667 2.66667V3.05333C18.6267 4.22667 21.3333 7.86667 21.3333 12V20L24 22.6667ZM14.6667 25.3333C14.6667 26.0406 14.3857 26.7189 13.8856 27.219C13.3855 27.7191 12.7072 28 12 28C11.2928 28 10.6145 27.7191 10.1144 27.219C9.61429 26.7189 9.33333 26.0406 9.33333 25.3333" fill="#E58625"/>
</svg>

After

Width:  |  Height:  |  Size: 650 B

View File

@@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.3385 12.0052C21.3385 13.4197 20.7766 14.7763 19.7764 15.7764C18.7763 16.7766 17.4197 17.3385 16.0052 17.3385C14.5907 17.3385 13.2342 16.7766 12.234 15.7764C11.2338 14.7763 10.6719 13.4197 10.6719 12.0052C10.6719 10.5907 11.2338 9.23417 12.234 8.23397C13.2342 7.23378 14.5907 6.67188 16.0052 6.67188C17.4197 6.67188 18.7763 7.23378 19.7764 8.23397C20.7766 9.23417 21.3385 10.5907 21.3385 12.0052ZM18.6719 12.0052C18.6719 12.7125 18.3909 13.3907 17.8908 13.8908C17.3907 14.3909 16.7125 14.6719 16.0052 14.6719C15.298 14.6719 14.6197 14.3909 14.1196 13.8908C13.6195 13.3907 13.3385 12.7125 13.3385 12.0052C13.3385 11.298 13.6195 10.6197 14.1196 10.1196C14.6197 9.61949 15.298 9.33854 16.0052 9.33854C16.7125 9.33854 17.3907 9.61949 17.8908 10.1196C18.3909 10.6197 18.6719 11.298 18.6719 12.0052Z" fill="#E58625"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.0026 1.33594C7.90261 1.33594 1.33594 7.90261 1.33594 16.0026C1.33594 24.1026 7.90261 30.6693 16.0026 30.6693C24.1026 30.6693 30.6693 24.1026 30.6693 16.0026C30.6693 7.90261 24.1026 1.33594 16.0026 1.33594ZM4.0026 16.0026C4.0026 18.7893 4.95327 21.3546 6.5466 23.3919C7.66586 21.9228 9.10948 20.7321 10.7648 19.9129C12.4201 19.0937 14.2423 18.6681 16.0893 18.6693C17.9124 18.6671 19.712 19.0814 21.3508 19.8804C22.9895 20.6795 24.4242 21.8422 25.5453 23.2799C26.7005 21.7647 27.4784 19.9962 27.8145 18.1207C28.1505 16.2452 28.0352 14.3167 27.4779 12.4946C26.9207 10.6725 25.9376 9.00934 24.6099 7.64265C23.2823 6.27597 21.6483 5.24508 19.8431 4.63528C18.038 4.02548 16.1135 3.8543 14.2291 4.1359C12.3446 4.4175 10.5543 5.14379 9.0063 6.25468C7.45827 7.36556 6.19702 8.8291 5.32691 10.5242C4.4568 12.2193 4.00285 14.0972 4.0026 16.0026ZM16.0026 28.0026C13.2478 28.0071 10.5761 27.0594 8.43994 25.3199C9.29969 24.0888 10.4442 23.0835 11.776 22.3899C13.1079 21.6962 14.5876 21.3346 16.0893 21.3359C17.5722 21.3346 19.034 21.6872 20.3533 22.3644C21.6725 23.0415 22.8112 24.0237 23.6746 25.2293C21.5219 27.0253 18.8061 28.007 16.0026 28.0026Z" fill="#E58625"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,146 +1,502 @@
'use client'; 'use client';
import { useSession } from 'next-auth/react'; import { useSession } from 'next-auth/react';
import Image from 'next/image';
import { useState } from 'react';
// Mock agent data - in production, this would come from API
const agentData = {
name: 'Brian Neeland',
isVerified: true,
title: 'Licensed Real Estate Agent',
location: 'Colorado',
memberSince: 'March 2020',
bio: 'Brian brings eight years of hands-on experience helping clients confidently buy, sell, and invest in real estate. He combines strong analytical skills with deep market knowledge to identify the right opportunities and guide clients through every step of the process. With a data-driven approach and clear communication, Brian ensures smooth transactions and informed decisions tailored to each client\'s goals.',
expertise: ['Buyers', 'Sellers', 'Divorce', 'Luxury', 'Retirement', 'Historical', 'condo', 'Rural', 'FHA', 'Conventional', 'USDA', 'Retirement'],
email: 'brian@gmail.com',
phone: '+91*******7493',
profileImage: '/assets/agent-placeholder.jpg',
experience: {
years: '10+ years',
contracts: '10+ Contracts',
licensingAreas: ['Colorado Springs', 'Monument', 'Falcon', 'Castle Rock', 'Fountain', 'Momentum'],
expertiseYears: [
{ area: 'Colorado', years: '10 yrs' },
{ area: 'Falcon', years: '10 yrs' },
{ area: 'Colorado', years: '10 yrs' },
{ area: 'Colorado', years: '10 yrs' },
],
certifications: [
{ name: 'Certified Residential Specialist (CRS)', org: 'RESIDENTIAL REAL ESTATE COUNCIL' },
{ name: 'Certified Residential Specialist (CRS)', org: 'RESIDENTIAL REAL ESTATE COUNCIL' },
],
},
availability: {
type: 'Full-time',
days: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
},
preferredWorkEnvironment: 'Preferred work environment includes on-site property visits, in-depth market research, client consultations, property tours, and active involvement in negotiations to ensure the best outcomes',
testimonialHighlight: "The most amazing experience I've had as a real estate professional is helping a family secure their dream home and seeing their happiness when they received the keys.",
specialization: {
types: ['Buyers', 'Sellers', 'First time Buyers', 'First time Sellers', 'Divorce'],
loanTypes: ['Conventional', 'FHA', 'VA', 'USDA'],
propertyTypes: ['SFR', 'Town home', 'Rural', 'Luxury', 'Condo'],
hobbies: ['Boating', 'Horses', 'RV', 'Automotive', 'Aviation'],
pricePoints: ['Under $100K', '$100K $300K', '$300K $500K', '$500K $1M', '$1M and above'],
},
testimonials: [
{
id: 1,
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisleget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc.',
author: 'Kennedy Kenney',
role: 'Chief Operations Officer',
rating: 5,
},
{
id: 2,
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisleget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc.',
author: 'Kennedy Kenney',
role: 'Chief Operations Officer',
rating: 5,
},
{
id: 3,
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean commodo ligula eget dolor. Sed dignissim, nisleget tincidunt vulputate, lacus justo bibendum ipsum, vitae tempus risus lorem at nunc.',
author: 'Kennedy Kenney',
role: 'Chief Operations Officer',
rating: 5,
},
],
};
// Star Rating Component
function StarRating({ rating }: { rating: number }) {
return (
<div className="flex gap-0.5">
{[1, 2, 3, 4, 5].map((star) => (
<svg
key={star}
className={`w-4 h-4 ${star <= rating ? 'text-[#e58625]' : '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>
);
}
// Tag Component
function Tag({ children, variant = 'default' }: { children: React.ReactNode; variant?: 'default' | 'light' | 'orange' }) {
return (
<span
className={`inline-flex items-center px-3 py-1 rounded-full text-sm border ${
variant === 'light'
? 'border-[#00293d]/30 text-[#00293d] bg-transparent'
: variant === 'orange'
? 'border-[#e58625] text-[#e58625] bg-transparent'
: 'border-[#00293d] text-[#00293d] bg-transparent'
}`}
>
{children}
</span>
);
}
// Specialization Card Component
function SpecializationCard({
title,
items,
icon,
}: {
title: string;
items: string[];
icon: React.ReactNode;
}) {
return (
<div className="bg-white rounded-[20px] p-6 text-center shadow-sm">
<div className="flex justify-center mb-3 text-[#e58625]">{icon}</div>
<h4 className="font-bold text-[#00293d] text-sm mb-4">{title}</h4>
<div className="space-y-1">
{items.map((item, idx) => (
<p key={idx} className="text-[#00293d] text-sm">
{item}
</p>
))}
</div>
<button className="mt-4 inline-flex items-center gap-1 text-[#e58625] text-xs font-medium hover:opacity-80 transition-opacity">
Show More
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
</div>
);
}
// Info Card Component
function InfoCard({
title,
content,
icon,
}: {
title: string;
content: React.ReactNode;
icon: React.ReactNode;
}) {
return (
<div className="bg-white rounded-[20px] border border-gray-200 p-6 text-center">
<div className="flex justify-center mb-3 text-[#e58625]">{icon}</div>
{title && <h4 className="font-semibold text-[#00293d] text-sm mb-3">{title}</h4>}
<div className="text-[#00293d] text-sm">{content}</div>
</div>
);
}
export default function AgentDashboard() { export default function AgentDashboard() {
const { data: session } = useSession(); const { data: session } = useSession();
return ( return (
<div className="space-y-6"> <div className="space-y-6">
{/* Welcome Section */} {/* Main Profile Section with Left Sidebar */}
<div className="bg-white rounded-[20px] shadow-lg p-8"> <div className="flex flex-col lg:flex-row gap-6">
<h1 className="text-3xl font-bold text-[#00293d] mb-2"> {/* Left Sidebar - Status & Contact */}
Welcome back, {session?.user?.name?.split(' ')[0] || 'Agent'}! <div className="w-full lg:w-[180px] flex-shrink-0 space-y-4">
{/* Profile Image */}
<div className="relative">
<div className="w-[140px] h-[140px] rounded-[20px] bg-[#8fa9a8] overflow-hidden mx-auto lg:mx-0">
<div className="w-full h-full bg-gradient-to-br from-[#8fa9a8] to-[#6b8a89] flex items-center justify-center">
<svg className="w-20 h-20 text-white/50" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
</svg>
</div>
</div>
<button className="absolute bottom-2 right-2 lg:right-auto lg:left-[110px] bg-white rounded-lg p-1.5 shadow-md hover:bg-gray-50 transition-colors">
<svg className="w-4 h-4 text-[#00293d]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>
</button>
</div>
{/* Status Buttons */}
<div className="space-y-2">
<div className="flex items-center gap-2">
<div className="flex items-center gap-1.5">
<span className="w-2 h-2 bg-green-500 rounded-full" />
<span className="text-sm text-[#00293d]">Available.</span>
</div>
<button className="px-4 py-1.5 bg-[#5ba4a4] text-white text-sm rounded-full hover:bg-[#4a9393] transition-colors">
Connect
</button>
</div>
<div className="flex items-center gap-2">
<div className="flex items-center gap-1.5">
<span className="w-2 h-2 bg-white border border-gray-400 rounded-full" />
<span className="text-sm text-[#00293d]">Unavailable.</span>
</div>
<button className="px-4 py-1.5 bg-[#5ba4a4] text-white text-sm rounded-full hover:bg-[#4a9393] transition-colors">
Connect
</button>
</div>
</div>
{/* Contact Info */}
<div className="space-y-2 pt-2">
<div className="flex items-center gap-2 text-sm">
<span className="font-bold text-[#00293d]">Email:</span>
<span className="text-[#00293d]">*****brian@gmail.com</span>
</div>
<div className="flex items-center gap-2 text-sm">
<span className="font-bold text-[#00293d]">Ph.No:</span>
<span className="text-[#00293d]">{agentData.phone}</span>
<button className="p-1 hover:bg-gray-100 rounded">
<svg className="w-4 h-4 text-[#00293d]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>
</button>
</div>
</div>
</div>
{/* Right Content - Profile Info */}
<div className="flex-1">
{/* Profile Header Card */}
<div className="bg-white rounded-[20px] border border-gray-200 p-6">
{/* Name and Actions Row */}
<div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-4">
<div>
{/* Name and Verification */}
<div className="flex items-center gap-2 mb-1">
<h1 className="text-xl font-bold text-[#00293d]">
<span className="font-bold">{agentData.name.split(' ')[0]}</span>{' '}
<span className="font-normal">{agentData.name.split(' ')[1]}</span>
</h1> </h1>
<p className="text-[#00293d]/70"> {agentData.isVerified && (
Here's an overview of your real estate business today. <span className="text-[#e58625] text-sm font-medium flex items-center gap-1">
</p> (Verified Expert)
</div> <svg className="w-4 h-4 text-[#5ba4a4]" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div className="bg-white rounded-[20px] shadow-lg p-6">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-[#00293d] rounded-full flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg> </svg>
</div> </span>
</div> )}
<p className="text-2xl font-bold text-[#00293d]">12</p> <button className="p-1 hover:bg-gray-100 rounded transition-colors">
<p className="text-sm text-[#00293d]/70">Active Listings</p> <svg className="w-4 h-4 text-[#5ba4a4]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
</div> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
<div className="bg-white rounded-[20px] shadow-lg p-6">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-[#e58625] rounded-full flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg> </svg>
</div> </button>
</div>
<p className="text-2xl font-bold text-[#00293d]">48</p>
<p className="text-sm text-[#00293d]/70">Total Clients</p>
</div> </div>
<div className="bg-white rounded-[20px] shadow-lg p-6"> {/* Title */}
<div className="flex items-center justify-between mb-4"> <p className="text-[#00293d] text-sm mb-2">{agentData.title}</p>
<div className="w-12 h-12 bg-[#5ba4a4] rounded-full flex items-center justify-center">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> {/* Location and Member Since */}
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> <div className="flex items-center gap-4 text-sm text-[#00293d]">
<span className="flex items-center gap-1 text-[#e58625] font-medium">
<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> </svg>
{agentData.location}
</span>
<span className="flex items-center gap-1">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clipRule="evenodd" />
</svg>
Member Since {agentData.memberSince}
</span>
</div> </div>
</div> </div>
<p className="text-2xl font-bold text-[#00293d]">5</p>
<p className="text-sm text-[#00293d]/70">Upcoming Appointments</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6"> {/* Action Buttons */}
<div className="flex items-center justify-between mb-4"> <div className="flex items-center gap-2">
<div className="w-12 h-12 bg-[#00293d] rounded-full flex items-center justify-center"> <button className="flex items-center gap-2 px-4 py-2 bg-[#e58625] text-white text-sm rounded-lg hover:bg-[#d47a1f] transition-colors">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg> </svg>
</div> Message
</div>
<p className="text-2xl font-bold text-[#00293d]">8</p>
<p className="text-sm text-[#00293d]/70">Unread Messages</p>
</div>
</div>
{/* Quick Actions */}
<div className="bg-white rounded-[20px] shadow-lg p-8">
<h2 className="text-xl font-bold text-[#00293d] mb-6">Quick Actions</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<button className="flex items-center gap-3 p-4 bg-[#f0f5fc] rounded-lg hover:bg-[#e0e8f5] transition-colors">
<div className="w-10 h-10 bg-[#00293d] rounded-full flex items-center justify-center">
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
</svg>
</div>
<span className="font-medium text-[#00293d]">Add New Property</span>
</button> </button>
<button className="flex items-center gap-2 px-4 py-2 bg-[#e58625] text-white text-sm rounded-lg hover:bg-[#d47a1f] transition-colors">
<button className="flex items-center gap-3 p-4 bg-[#f0f5fc] rounded-lg hover:bg-[#e0e8f5] transition-colors"> <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div className="w-10 h-10 bg-[#e58625] rounded-full flex items-center justify-center"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
</svg> </svg>
</div> Requests
<span className="font-medium text-[#00293d]">Add New Client</span>
</button>
<button className="flex items-center gap-3 p-4 bg-[#f0f5fc] rounded-lg hover:bg-[#e0e8f5] transition-colors">
<div className="w-10 h-10 bg-[#5ba4a4] rounded-full flex items-center justify-center">
<svg className="w-5 h-5 text-white" 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>
</div>
<span className="font-medium text-[#00293d]">Schedule Appointment</span>
</button> </button>
</div> </div>
</div> </div>
{/* Recent Activity */} {/* Bio */}
<div className="bg-white rounded-[20px] shadow-lg p-8"> <p className="text-[#00293d] text-sm leading-relaxed mb-4">{agentData.bio}</p>
<h2 className="text-xl font-bold text-[#00293d] mb-6">Recent Activity</h2>
<div className="space-y-4"> {/* Expertise Tags */}
<div className="flex items-center gap-4 p-4 bg-[#f0f5fc] rounded-lg"> <div>
<div className="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center"> <p className="font-bold text-[#00293d] text-sm mb-2">Expertise:</p>
<svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <div className="flex flex-wrap gap-2">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /> {agentData.expertise.map((tag, idx) => (
</svg> <Tag key={idx}>{tag}</Tag>
))}
</div>
</div>
</div> </div>
<div className="flex-1">
<p className="font-medium text-[#00293d]">New inquiry for 123 Main Street</p>
<p className="text-sm text-[#00293d]/70">2 hours ago</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-4 p-4 bg-[#f0f5fc] rounded-lg"> {/* Experience Section */}
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center"> <div className="bg-white rounded-[20px] border border-gray-200 p-6">
<svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <h2 className="text-xl font-bold text-[#00293d] mb-6">Experience</h2>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> <div className="flex flex-col lg:flex-row gap-8">
</svg> {/* Left Column */}
<div className="flex-1 space-y-6">
<div>
<p className="font-bold text-[#00293d] text-sm mb-2">Years in Experience</p>
<ul className="list-disc list-inside text-[#00293d] text-sm">
<li>{agentData.experience.years}</li>
</ul>
</div>
<div>
<p className="font-bold text-[#00293d] text-sm mb-2">Number of contract coised</p>
<ul className="list-disc list-inside text-[#00293d] text-sm">
<li>{agentData.experience.contracts}</li>
</ul>
</div>
<div>
<p className="font-bold text-[#00293d] text-sm mb-3">Licensing &amp; Areas</p>
<div className="flex flex-wrap gap-2">
{agentData.experience.licensingAreas.slice(0, 5).map((area, idx) => (
<Tag key={idx} variant="light">
{area}
</Tag>
))}
{agentData.experience.licensingAreas.length > 5 && (
<span className="text-[#e58625] text-sm cursor-pointer">+{agentData.experience.licensingAreas.length - 5} More</span>
)}
</div> </div>
<div className="flex-1">
<p className="font-medium text-[#00293d]">Appointment scheduled with John Doe</p>
<p className="text-sm text-[#00293d]/70">5 hours ago</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-4 p-4 bg-[#f0f5fc] rounded-lg"> {/* Divider */}
<div className="w-10 h-10 bg-orange-100 rounded-full flex items-center justify-center"> <div className="hidden lg:block w-px bg-gray-200" />
<svg className="w-5 h-5 text-orange-600" 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" /> {/* Right Column */}
<div className="flex-1 space-y-6">
<div>
<p className="font-bold text-[#00293d] text-sm mb-3">Areas in expertise &amp; Years</p>
<div className="flex flex-wrap gap-2">
{agentData.experience.expertiseYears.slice(0, 3).map((item, idx) => (
<Tag key={idx} variant="orange">
{item.area} {item.years}
</Tag>
))}
{agentData.experience.expertiseYears.length > 3 && (
<span className="text-[#e58625] text-sm cursor-pointer">+{agentData.experience.expertiseYears.length - 3}More</span>
)}
</div>
</div>
<div>
<p className="font-bold text-[#00293d] text-sm mb-3">Certifications</p>
<ul className="space-y-3">
{agentData.experience.certifications.map((cert, idx) => (
<li key={idx} className="text-[#00293d] text-sm">
<span> {cert.name}</span>
<p className="text-[#5ba4a4] text-xs ml-3">{cert.org}</p>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
{/* Info Cards Section */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<InfoCard
title="Availability"
icon={
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
}
content={
<div>
<p className="font-semibold mb-2">{agentData.availability.type}</p>
<div className="space-y-1">
{agentData.availability.days.map((day) => (
<p key={day}>{day}</p>
))}
</div>
</div>
}
/>
<InfoCard
title="Preferred work environment"
icon={
<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} 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={1.5} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
}
content={<p className="text-sm leading-relaxed">{agentData.preferredWorkEnvironment}</p>}
/>
<InfoCard
title=""
icon={
<svg className="w-8 h-8" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" />
</svg>
}
content={<p className="text-sm leading-relaxed italic">&ldquo;{agentData.testimonialHighlight}&rdquo;</p>}
/>
</div>
{/* Specialization Section - Light Gray Background */}
<div className="bg-[#e8e8e8] rounded-[20px] p-8">
<div className="text-center mb-8">
<h2 className="text-xl font-bold text-[#00293d]">Specialization</h2>
<p className="text-[#00293d]/70 text-sm">Area Of Expertise and Focus</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<SpecializationCard
title="Specialization"
items={agentData.specialization.types}
icon={
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
</svg>
}
/>
<SpecializationCard
title="Loan Type"
items={agentData.specialization.loanTypes}
icon={
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" />
</svg>
}
/>
<SpecializationCard
title="Property Type"
items={agentData.specialization.propertyTypes}
icon={
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z" />
<path d="M7 12h2v5H7zm4-3h2v8h-2zm4-3h2v11h-2z" />
</svg>
}
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-2xl mx-auto">
<SpecializationCard
title="Hobbies & Interests"
items={agentData.specialization.hobbies}
icon={
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
</svg>
}
/>
<SpecializationCard
title="Price Point"
items={agentData.specialization.pricePoints}
icon={
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M11.8 10.9c-2.27-.59-3-1.2-3-2.15 0-1.09 1.01-1.85 2.7-1.85 1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-1.94.42-3.5 1.68-3.5 3.61 0 2.31 1.91 3.46 4.7 4.13 2.5.6 3 1.48 3 2.41 0 .69-.49 1.79-2.7 1.79-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c1.95-.37 3.5-1.5 3.5-3.55 0-2.84-2.43-3.81-4.7-4.4z" />
</svg>
}
/>
</div>
</div>
{/* Testimonials Section */}
<div className="bg-white rounded-[20px] border border-gray-200 p-8">
<h2 className="text-xl font-bold text-[#00293d] text-center mb-2">Testimonials</h2>
<p className="text-[#00293d]/70 text-sm text-center mb-8">
Clients rate our real estate services 4.9 out of 5 on average, based on recent client reviews.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{agentData.testimonials.map((testimonial) => (
<div key={testimonial.id} className="p-4">
<div className="flex items-start gap-3 mb-4">
<div className="w-8 h-8 rounded-full bg-[#e58625]/20 flex items-center justify-center flex-shrink-0">
<span className="text-[#e58625] text-lg font-serif">&ldquo;</span>
</div>
<p className="font-bold text-[#00293d] text-sm">I have been working with Lorem .</p>
</div>
<p className="text-[#00293d]/70 text-sm mb-4 leading-relaxed">{testimonial.text}</p>
<div className="flex items-center gap-3 pt-4 border-t border-gray-100">
<div className="w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center overflow-hidden">
<svg className="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
</svg> </svg>
</div> </div>
<div className="flex-1"> <div className="flex-1">
<p className="font-medium text-[#00293d]">Property price updated: 456 Oak Avenue</p> <StarRating rating={testimonial.rating} />
<p className="text-sm text-[#00293d]/70">Yesterday</p> <p className="font-bold text-[#00293d] text-sm">{testimonial.author}</p>
<p className="text-[#00293d]/50 text-xs">{testimonial.role}</p>
</div> </div>
</div> </div>
</div> </div>
))}
</div>
</div> </div>
</div> </div>
); );

View File

@@ -1,52 +1,10 @@
'use client'; 'use client';
import { useSession, signOut } from 'next-auth/react'; import { useSession } from 'next-auth/react';
import { useRouter, usePathname } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useEffect } from 'react'; import { useEffect } from 'react';
import Link from 'next/link'; import { Footer } from '@/components/layout/Footer';
import { AgentHeader } from '@/components/layout/AgentHeader';
const agentNavItems = [
{ href: '/agent/dashboard', label: 'Dashboard', icon: 'home' },
{ href: '/agent/properties', label: 'My Properties', icon: 'building' },
{ href: '/agent/clients', label: 'Clients', icon: 'users' },
{ href: '/agent/appointments', label: 'Appointments', icon: 'calendar' },
{ href: '/agent/messages', label: 'Messages', icon: 'message' },
{ href: '/agent/settings', label: 'Settings', icon: 'settings' },
];
const icons: Record<string, JSX.Element> = {
home: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
),
building: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg>
),
users: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
),
calendar: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
),
message: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
),
settings: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
),
};
export default function AgentLayout({ export default function AgentLayout({
children, children,
@@ -55,7 +13,6 @@ export default function AgentLayout({
}) { }) {
const { data: session, status } = useSession(); const { data: session, status } = useSession();
const router = useRouter(); const router = useRouter();
const pathname = usePathname();
useEffect(() => { useEffect(() => {
if (status === 'loading') return; if (status === 'loading') return;
@@ -68,72 +25,38 @@ export default function AgentLayout({
// Redirect non-agents to user dashboard // Redirect non-agents to user dashboard
const userRole = (session.user as any)?.role; const userRole = (session.user as any)?.role;
if (userRole !== 'AGENT') { if (userRole !== 'AGENT') {
router.replace('/user/dashboard'); router.replace('/user/userprofile');
} }
}, [session, status, router]); }, [session, status, router]);
if (status === 'loading' || !session) { if (status === 'loading' || !session) {
return ( return (
<div className="min-h-screen bg-gradient-to-b from-[#c4d9d4] to-[#f0f5fc] flex items-center justify-center"> <div className="min-h-screen bg-white flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d]"></div> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d]"></div>
</div> </div>
); );
} }
return ( return (
<div className="min-h-screen bg-gradient-to-b from-[#c4d9d4] to-[#f0f5fc]"> <div className="min-h-screen bg-white flex flex-col">
{/* Header */} {/* Main Content Area */}
<header className="bg-white/80 backdrop-blur-sm shadow-sm fixed top-0 left-0 right-0 z-50"> <main className="flex-1">
<div className="px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
<div className="flex justify-between items-center h-16"> {/* Header Bar */}
<Link href="/agent/dashboard"> <AgentHeader
<img src="/assets/logo.svg" alt="RE-QuestN" className="h-8" /> userName={session?.user?.name}
</Link> userEmail={session?.user?.email}
<div className="flex items-center gap-4"> />
<span className="text-sm text-[#00293d]">
{session?.user?.name || session?.user?.email}
</span>
<span className="px-2 py-1 bg-[#e58625]/10 text-[#e58625] text-xs font-medium rounded">
Agent
</span>
<button
onClick={() => signOut({ callbackUrl: '/login' })}
className="px-4 py-2 bg-[#e58625] hover:bg-[#d47a1f] text-white text-sm font-medium rounded-lg transition-colors"
>
Sign Out
</button>
</div>
</div>
</div>
</header>
<div className="flex pt-16"> {/* Page Content */}
{/* Sidebar */} <div className="mt-6">
<aside className="w-64 bg-white/80 backdrop-blur-sm shadow-sm min-h-[calc(100vh-4rem)] fixed left-0 top-16"> {children}
<nav className="p-4 space-y-1">
{agentNavItems.map((item) => {
const isActive = pathname === item.href;
return (
<Link
key={item.href}
href={item.href}
className={`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${
isActive
? 'bg-[#00293d] text-white'
: 'text-[#00293d] hover:bg-[#f0f5fc]'
}`}
>
{icons[item.icon]}
<span className="font-medium">{item.label}</span>
</Link>
);
})}
</nav>
</aside>
{/* Main Content */}
<main className="flex-1 ml-64 p-6">{children}</main>
</div> </div>
</div> </div>
</main>
{/* Footer */}
<Footer />
</div>
); );
} }

View File

@@ -2,11 +2,11 @@
import { useSession, signOut } from 'next-auth/react'; import { useSession, signOut } from 'next-auth/react';
import { useRouter, usePathname } from 'next/navigation'; import { useRouter, usePathname } from 'next/navigation';
import { useEffect } from 'react'; import { useEffect, ReactElement } from 'react';
import Link from 'next/link'; import Link from 'next/link';
const userNavItems = [ const userNavItems = [
{ href: '/user/dashboard', label: 'Dashboard', icon: 'home' }, { href: '/user/userprofile', label: 'Dashboard', icon: 'home' },
{ href: '/user/properties', label: 'Browse Properties', icon: 'building' }, { href: '/user/properties', label: 'Browse Properties', icon: 'building' },
{ href: '/user/favorites', label: 'Favorites', icon: 'heart' }, { href: '/user/favorites', label: 'Favorites', icon: 'heart' },
{ href: '/user/inquiries', label: 'My Inquiries', icon: 'message' }, { href: '/user/inquiries', label: 'My Inquiries', icon: 'message' },
@@ -14,7 +14,7 @@ const userNavItems = [
{ href: '/user/settings', label: 'Settings', icon: 'settings' }, { href: '/user/settings', label: 'Settings', icon: 'settings' },
]; ];
const icons: Record<string, JSX.Element> = { const icons: Record<string, ReactElement> = {
home: ( home: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
@@ -86,7 +86,7 @@ export default function UserLayout({
<header className="bg-white/80 backdrop-blur-sm shadow-sm fixed top-0 left-0 right-0 z-50"> <header className="bg-white/80 backdrop-blur-sm shadow-sm fixed top-0 left-0 right-0 z-50">
<div className="px-4 sm:px-6 lg:px-8"> <div className="px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16"> <div className="flex justify-between items-center h-16">
<Link href="/user/dashboard"> <Link href="/user/userprofile">
<img src="/assets/logo.svg" alt="RE-QuestN" className="h-8" /> <img src="/assets/logo.svg" alt="RE-QuestN" className="h-8" />
</Link> </Link>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">

View File

@@ -1,115 +0,0 @@
'use client';
import { useSession } from 'next-auth/react';
export default function UserDashboard() {
const { data: session } = useSession();
return (
<div className="space-y-6">
{/* Welcome Section */}
<div className="bg-white rounded-[20px] shadow-lg p-8">
<h1 className="text-3xl font-bold text-[#00293d] mb-2">
Welcome, {session?.user?.name?.split(' ')[0] || 'User'}!
</h1>
<p className="text-[#00293d]/70">
Your real estate journey starts here. Explore properties, connect with agents, and find your dream home.
</p>
</div>
{/* Quick Actions */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="bg-white rounded-[20px] shadow-lg p-6 hover:shadow-xl transition-shadow cursor-pointer">
<div className="w-12 h-12 bg-[#00293d] rounded-full flex items-center justify-center mb-4">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<h3 className="text-lg font-semibold text-[#00293d] mb-2">Search Properties</h3>
<p className="text-sm text-[#00293d]/70">Find your perfect home from thousands of listings</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6 hover:shadow-xl transition-shadow cursor-pointer">
<div className="w-12 h-12 bg-[#e58625] rounded-full flex items-center justify-center mb-4">
<svg className="w-6 h-6 text-white" 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>
</div>
<h3 className="text-lg font-semibold text-[#00293d] mb-2">Find Agents</h3>
<p className="text-sm text-[#00293d]/70">Connect with top real estate professionals</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6 hover:shadow-xl transition-shadow cursor-pointer">
<div className="w-12 h-12 bg-[#5ba4a4] rounded-full flex items-center justify-center mb-4">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
</svg>
</div>
<h3 className="text-lg font-semibold text-[#00293d] mb-2">Saved Favorites</h3>
<p className="text-sm text-[#00293d]/70">View your saved properties and searches</p>
</div>
</div>
{/* Stats */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
<div className="bg-white rounded-[20px] shadow-lg p-6">
<p className="text-3xl font-bold text-[#00293d]">0</p>
<p className="text-sm text-[#00293d]/70">Saved Properties</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6">
<p className="text-3xl font-bold text-[#00293d]">0</p>
<p className="text-sm text-[#00293d]/70">Active Inquiries</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6">
<p className="text-3xl font-bold text-[#00293d]">0</p>
<p className="text-sm text-[#00293d]/70">Scheduled Tours</p>
</div>
<div className="bg-white rounded-[20px] shadow-lg p-6">
<p className="text-3xl font-bold text-[#00293d]">0</p>
<p className="text-sm text-[#00293d]/70">Messages</p>
</div>
</div>
{/* Featured Properties */}
<div className="bg-white rounded-[20px] shadow-lg p-8">
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-[#00293d]">Featured Properties</h2>
<button className="text-[#e58625] hover:text-[#d47a1f] font-medium text-sm">
View All
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{/* Property Card Placeholder */}
<div className="bg-[#f0f5fc] rounded-[20px] p-6 text-center">
<div className="w-16 h-16 bg-[#00293d]/10 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-[#00293d]/40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg>
</div>
<p className="text-[#00293d]/70 text-sm">No featured properties yet</p>
<button className="mt-4 text-[#e58625] hover:text-[#d47a1f] font-medium text-sm">
Browse Properties
</button>
</div>
</div>
</div>
{/* Recent Activity */}
<div className="bg-white rounded-[20px] shadow-lg p-8">
<h2 className="text-xl font-bold text-[#00293d] mb-6">Recent Activity</h2>
<div className="text-center py-8">
<div className="w-16 h-16 bg-[#f0f5fc] rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-[#00293d]/40" 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>
</div>
<p className="text-[#00293d]/70">No recent activity</p>
<p className="text-sm text-[#00293d]/50 mt-2">
Start exploring properties to see your activity here
</p>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,19 @@
'use client';
import { HeroSection } from '@/components/home/HeroSection';
import { FeaturesSection } from '@/components/home/FeaturesSection';
import { FeaturedAgents } from '@/components/home/FeaturedAgents';
import { TopProfessionals } from '@/components/home/TopProfessionals';
import { TestimonialsSection } from '@/components/home/TestimonialsSection';
export default function UserDashboard() {
return (
<div className="-m-6">
<HeroSection />
<FeaturesSection />
<FeaturedAgents />
<TopProfessionals />
<TestimonialsSection />
</div>
);
}

View File

@@ -1,26 +1,95 @@
@import "tailwindcss"; @import "tailwindcss";
:root { :root {
--background: #ffffff; /* RE-Quest Design Tokens */
--foreground: #171717; --color-primary-dark: #00293d;
--color-primary-light: #c4d9d4;
--color-accent-orange: #f5a623;
--color-accent-orange-hover: #e09620;
--color-background: #ffffff;
--color-background-alt: #f5f9f8;
--color-foreground: #171717;
--color-text-gray: #666666;
--color-text-muted: #9ca3af;
--color-border: #e5e7eb;
/* Spacing */
--spacing-section: 6rem;
--spacing-section-sm: 4rem;
/* Border Radius */
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
--radius-xl: 1.5rem;
--radius-2xl: 2rem;
--radius-full: 9999px;
/* Shadows */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
} }
@theme inline { @theme inline {
--color-background: var(--background); --color-background: var(--color-background);
--color-foreground: var(--foreground); --color-foreground: var(--color-foreground);
--font-sans: var(--font-geist-sans); --font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono); --font-mono: var(--font-geist-mono);
} }
@media (prefers-color-scheme: dark) { /* Disable dark mode for consistent branding */
:root { body {
--background: #0a0a0a; background: var(--color-background);
--foreground: #ededed; color: var(--color-foreground);
font-family: Arial, Helvetica, sans-serif;
}
/* Custom utilities */
.section-padding {
padding-top: var(--spacing-section-sm);
padding-bottom: var(--spacing-section-sm);
}
@media (min-width: 768px) {
.section-padding {
padding-top: var(--spacing-section);
padding-bottom: var(--spacing-section);
} }
} }
body { /* Gradient backgrounds */
background: var(--background); .gradient-hero {
color: var(--foreground); background: linear-gradient(to bottom, #e8f0ee, #f5f9f8);
font-family: Arial, Helvetica, sans-serif; }
/* Card hover effects */
.card-hover {
transition: all 0.3s ease;
}
.card-hover:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-xl);
}
/* Focus states */
.focus-ring {
outline: none;
}
.focus-ring:focus {
box-shadow: 0 0 0 2px var(--color-background), 0 0 0 4px var(--color-primary-dark);
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Selection styling */
::selection {
background-color: var(--color-primary-light);
color: var(--color-primary-dark);
} }

View File

@@ -22,7 +22,7 @@ export default function Home() {
if (userRole === 'AGENT') { if (userRole === 'AGENT') {
router.replace('/agent/dashboard'); router.replace('/agent/dashboard');
} else { } else {
router.replace('/user/dashboard'); router.replace('/user/userprofile');
} }
}, [session, status, router]); }, [session, status, router]);
@@ -32,7 +32,7 @@ export default function Home() {
<div className="text-center"> <div className="text-center">
<img <img
src="/assets/logo.svg" src="/assets/logo.svg"
alt="RE-QuestN" alt="RE-Quest"
className="h-10 mx-auto mb-4" className="h-10 mx-auto mb-4"
/> />
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d] mx-auto"></div> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d] mx-auto"></div>

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>
);
}

View File

@@ -28,11 +28,8 @@ export default auth((req) => {
// Redirect logged-in users away from public routes (login, signup) // Redirect logged-in users away from public routes (login, signup)
if (isLoggedIn && isPublicRoute) { if (isLoggedIn && isPublicRoute) {
// Redirect to appropriate dashboard based on role // Redirect to home page instead of dashboard
if (userRole === "AGENT") { return NextResponse.redirect(new URL("/", nextUrl.origin));
return NextResponse.redirect(new URL("/agent/dashboard", nextUrl.origin));
}
return NextResponse.redirect(new URL("/user/dashboard", nextUrl.origin));
} }
// Redirect non-logged-in users to login page for protected routes // Redirect non-logged-in users to login page for protected routes
@@ -46,7 +43,7 @@ export default auth((req) => {
if (isLoggedIn) { if (isLoggedIn) {
// Prevent regular users from accessing agent routes // Prevent regular users from accessing agent routes
if (isAgentRoute && userRole !== "AGENT") { if (isAgentRoute && userRole !== "AGENT") {
return NextResponse.redirect(new URL("/user/dashboard", nextUrl.origin)); return NextResponse.redirect(new URL("/user/userprofile", nextUrl.origin));
} }
// Prevent agents from accessing user routes // Prevent agents from accessing user routes