split componeent
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Tag } from './Tag';
|
||||||
|
|
||||||
|
interface ExperienceData {
|
||||||
|
years: string;
|
||||||
|
contracts: string;
|
||||||
|
licensingAreas: string[];
|
||||||
|
expertiseYears: { area: string; years: string }[];
|
||||||
|
certifications: { name: string; org: string }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExperienceSectionProps {
|
||||||
|
experience: ExperienceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExperienceSection({ experience }: ExperienceSectionProps) {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-[20px] border border-gray-200 p-6">
|
||||||
|
<h2 className="text-xl font-bold text-[#00293d] mb-6">Experience</h2>
|
||||||
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
|
{/* 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>{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>{experience.contracts}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-bold text-[#00293d] text-sm mb-3">Licensing & Areas</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{experience.licensingAreas.slice(0, 5).map((area, idx) => (
|
||||||
|
<Tag key={idx} variant="light">
|
||||||
|
{area}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
{experience.licensingAreas.length > 5 && (
|
||||||
|
<span className="text-[#e58625] text-sm cursor-pointer">
|
||||||
|
+{experience.licensingAreas.length - 5} More
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Divider */}
|
||||||
|
<div className="hidden lg:block w-px bg-gray-200" />
|
||||||
|
|
||||||
|
{/* Right Column */}
|
||||||
|
<div className="flex-1 space-y-6">
|
||||||
|
<div>
|
||||||
|
<p className="font-bold text-[#00293d] text-sm mb-3">Areas in expertise & Years</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{experience.expertiseYears.slice(0, 3).map((item, idx) => (
|
||||||
|
<Tag key={idx} variant="orange">
|
||||||
|
{item.area} – {item.years}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
{experience.expertiseYears.length > 3 && (
|
||||||
|
<span className="text-[#e58625] text-sm cursor-pointer">
|
||||||
|
+{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">
|
||||||
|
{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>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
src/app/(agent)/agent/dashboard/component/InfoCard.tsx
Normal file
17
src/app/(agent)/agent/dashboard/component/InfoCard.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
interface InfoCardProps {
|
||||||
|
title: string;
|
||||||
|
content: React.ReactNode;
|
||||||
|
icon: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InfoCard({ title, content, icon }: InfoCardProps) {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-[10px] shadow-[0px_10px_20px_0px_rgba(217,217,217,0.5)] p-6 text-center">
|
||||||
|
<div className="flex justify-center mb-3">{icon}</div>
|
||||||
|
{title && <h4 className="font-bold text-[#00293d] text-sm mb-3">{title}</h4>}
|
||||||
|
<div className="text-[#00293d] text-sm">{content}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
135
src/app/(agent)/agent/dashboard/component/ProfileHeader.tsx
Normal file
135
src/app/(agent)/agent/dashboard/component/ProfileHeader.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Button } from '@/components/ui/Button';
|
||||||
|
import { Tag } from './Tag';
|
||||||
|
|
||||||
|
interface ProfileHeaderProps {
|
||||||
|
name: string;
|
||||||
|
isVerified: boolean;
|
||||||
|
title: string;
|
||||||
|
location: string;
|
||||||
|
memberSince: string;
|
||||||
|
bio: string;
|
||||||
|
expertise: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProfileHeader({
|
||||||
|
name,
|
||||||
|
isVerified,
|
||||||
|
title,
|
||||||
|
location,
|
||||||
|
memberSince,
|
||||||
|
bio,
|
||||||
|
expertise,
|
||||||
|
}: ProfileHeaderProps) {
|
||||||
|
const [firstName, lastName] = name.split(' ');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<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-[18px] text-[#00293d] font-[family-name:var(--font-fractul)]">
|
||||||
|
<span className="font-bold">{firstName}</span>{' '}
|
||||||
|
<span className="font-normal">{lastName}</span>
|
||||||
|
</h1>
|
||||||
|
{isVerified && (
|
||||||
|
<>
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/verified-icon.svg"
|
||||||
|
alt="Verified"
|
||||||
|
width={15}
|
||||||
|
height={14}
|
||||||
|
/>
|
||||||
|
<span className="text-[14px] text-[#638559] font-medium font-serif">
|
||||||
|
(Verified Expert)
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<button className="p-1 hover:bg-gray-100 rounded transition-colors">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/edit-pencil-icon.svg"
|
||||||
|
alt="Edit name"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Title */}
|
||||||
|
<p className="text-[#00293d] text-sm mb-2">{title}</p>
|
||||||
|
|
||||||
|
{/* Location and Member Since */}
|
||||||
|
<div className="flex items-center gap-4 text-sm text-[#00293d]">
|
||||||
|
<span className="flex items-center gap-1 text-[#e58625] font-medium">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/location-icon.svg"
|
||||||
|
alt="Location"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
{location}
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-1">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/calendar-icon.svg"
|
||||||
|
alt="Calendar"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
Member Since {memberSince}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Action Buttons */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Button
|
||||||
|
variant="action"
|
||||||
|
size="sm"
|
||||||
|
leftIcon={
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/message-icon.svg"
|
||||||
|
alt="Message"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Message
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="action"
|
||||||
|
size="sm"
|
||||||
|
leftIcon={
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/clipboard-icon.svg"
|
||||||
|
alt="Requests"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Requests
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Bio */}
|
||||||
|
<p className="text-[#00293d] text-sm leading-relaxed mb-4">{bio}</p>
|
||||||
|
|
||||||
|
{/* Expertise Tags */}
|
||||||
|
<div>
|
||||||
|
<p className="font-bold text-[#00293d] text-sm mb-2">Expertise:</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{expertise.map((tag, idx) => (
|
||||||
|
<Tag key={idx}>{tag}</Tag>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
79
src/app/(agent)/agent/dashboard/component/ProfileSidebar.tsx
Normal file
79
src/app/(agent)/agent/dashboard/component/ProfileSidebar.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
interface ProfileSidebarProps {
|
||||||
|
profileImage: string;
|
||||||
|
email: string;
|
||||||
|
phone: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProfileSidebar({ profileImage, email, phone }: ProfileSidebarProps) {
|
||||||
|
return (
|
||||||
|
<div className="w-full lg:w-[180px] flex-shrink-0 space-y-4">
|
||||||
|
{/* Profile Image */}
|
||||||
|
<div className="relative mx-auto lg:mx-0">
|
||||||
|
<div className="w-[200px] h-[200px] rounded-[15px] overflow-hidden">
|
||||||
|
<Image
|
||||||
|
src={profileImage}
|
||||||
|
alt="Profile"
|
||||||
|
width={200}
|
||||||
|
height={200}
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* Edit Icon - Top Right Outside */}
|
||||||
|
<button className="absolute -top-3 -right-3 w-9 h-9 bg-white rounded-[10px] shadow-md flex items-center justify-center hover:bg-gray-50 transition-colors">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/edit-icon.svg"
|
||||||
|
alt="Edit profile"
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
</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]">{email}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2 text-sm">
|
||||||
|
<span className="font-bold text-[#00293d]">Ph.No:</span>
|
||||||
|
<span className="text-[#00293d]">{phone}</span>
|
||||||
|
<button className="p-1 hover:bg-gray-100 rounded">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/edit-pencil-icon.svg"
|
||||||
|
alt="Edit phone"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
interface SpecializationCardProps {
|
||||||
|
title: string;
|
||||||
|
items: string[];
|
||||||
|
icon: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SpecializationCard({ title, items, icon }: SpecializationCardProps) {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-[20px] p-6 text-center shadow-sm">
|
||||||
|
<div className="flex justify-center mb-3">{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
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/chevron-down-icon.svg"
|
||||||
|
alt="Show more"
|
||||||
|
width={12}
|
||||||
|
height={12}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/app/(agent)/agent/dashboard/component/StarRating.tsx
Normal file
23
src/app/(agent)/agent/dashboard/component/StarRating.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
interface StarRatingProps {
|
||||||
|
rating: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StarRating({ rating }: StarRatingProps) {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-0.5">
|
||||||
|
{[1, 2, 3, 4, 5].map((star) => (
|
||||||
|
<Image
|
||||||
|
key={star}
|
||||||
|
src={star <= rating ? '/assets/icons/star-filled-icon.svg' : '/assets/icons/star-empty-icon.svg'}
|
||||||
|
alt={star <= rating ? 'Filled star' : 'Empty star'}
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
22
src/app/(agent)/agent/dashboard/component/Tag.tsx
Normal file
22
src/app/(agent)/agent/dashboard/component/Tag.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
interface TagProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
variant?: 'default' | 'light' | 'orange';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Tag({ children, variant = 'default' }: TagProps) {
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { StarRating } from './StarRating';
|
||||||
|
|
||||||
|
interface TestimonialCardProps {
|
||||||
|
text: string;
|
||||||
|
author: string;
|
||||||
|
role: string;
|
||||||
|
rating: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TestimonialCard({ text, author, role, rating }: TestimonialCardProps) {
|
||||||
|
return (
|
||||||
|
<div 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">“</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">{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">
|
||||||
|
<Image
|
||||||
|
src="/assets/icons/user-placeholder-icon.svg"
|
||||||
|
alt="User"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<StarRating rating={rating} />
|
||||||
|
<p className="font-bold text-[#00293d] text-sm">{author}</p>
|
||||||
|
<p className="text-[#00293d]/50 text-xs">{role}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
9
src/app/(agent)/agent/dashboard/component/index.ts
Normal file
9
src/app/(agent)/agent/dashboard/component/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// Dashboard Components
|
||||||
|
export { StarRating } from './StarRating';
|
||||||
|
export { Tag } from './Tag';
|
||||||
|
export { InfoCard } from './InfoCard';
|
||||||
|
export { SpecializationCard } from './SpecializationCard';
|
||||||
|
export { ProfileSidebar } from './ProfileSidebar';
|
||||||
|
export { ProfileHeader } from './ProfileHeader';
|
||||||
|
export { ExperienceSection } from './ExperienceSection';
|
||||||
|
export { TestimonialCard } from './TestimonialCard';
|
||||||
@@ -2,8 +2,18 @@
|
|||||||
|
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useState } from 'react';
|
|
||||||
import { Button } from '@/components/ui/Button';
|
// Import components from component folder
|
||||||
|
import {
|
||||||
|
StarRating,
|
||||||
|
Tag,
|
||||||
|
InfoCard,
|
||||||
|
SpecializationCard,
|
||||||
|
ProfileSidebar,
|
||||||
|
ProfileHeader,
|
||||||
|
ExperienceSection,
|
||||||
|
TestimonialCard,
|
||||||
|
} from './component';
|
||||||
|
|
||||||
// Mock agent data - in production, this would come from API
|
// Mock agent data - in production, this would come from API
|
||||||
const agentData = {
|
const agentData = {
|
||||||
@@ -16,7 +26,7 @@ const agentData = {
|
|||||||
expertise: ['Buyers', 'Sellers', 'Divorce', 'Luxury', 'Retirement', 'Historical', 'condo', 'Rural', 'FHA', 'Conventional', 'USDA', 'Retirement'],
|
expertise: ['Buyers', 'Sellers', 'Divorce', 'Luxury', 'Retirement', 'Historical', 'condo', 'Rural', 'FHA', 'Conventional', 'USDA', 'Retirement'],
|
||||||
email: 'brian@gmail.com',
|
email: 'brian@gmail.com',
|
||||||
phone: '+91*******7493',
|
phone: '+91*******7493',
|
||||||
profileImage: '/assets/agent-placeholder.jpg',
|
profileImage: '/assets/demo_images/8f017153a7b4a239a4f0691234ef97dd55092282.jpg',
|
||||||
experience: {
|
experience: {
|
||||||
years: '10+ years',
|
years: '10+ years',
|
||||||
contracts: '10+ Contracts',
|
contracts: '10+ Contracts',
|
||||||
@@ -70,92 +80,6 @@ const agentData = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Star Rating Component
|
|
||||||
function StarRating({ rating }: { rating: number }) {
|
|
||||||
return (
|
|
||||||
<div className="flex gap-0.5">
|
|
||||||
{[1, 2, 3, 4, 5].map((star) => (
|
|
||||||
<Image
|
|
||||||
key={star}
|
|
||||||
src={star <= rating ? '/assets/icons/star-filled-icon.svg' : '/assets/icons/star-empty-icon.svg'}
|
|
||||||
alt={star <= rating ? 'Filled star' : 'Empty star'}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</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">{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
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/chevron-down-icon.svg"
|
|
||||||
alt="Show more"
|
|
||||||
width={12}
|
|
||||||
height={12}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info Card Component
|
|
||||||
function InfoCard({
|
|
||||||
title,
|
|
||||||
content,
|
|
||||||
icon,
|
|
||||||
}: {
|
|
||||||
title: string;
|
|
||||||
content: React.ReactNode;
|
|
||||||
icon: React.ReactNode;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="bg-white rounded-[10px] shadow-[0px_10px_20px_0px_rgba(217,217,217,0.5)] p-6 text-center">
|
|
||||||
<div className="flex justify-center mb-3">{icon}</div>
|
|
||||||
{title && <h4 className="font-bold 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();
|
||||||
|
|
||||||
@@ -164,249 +88,28 @@ export default function AgentDashboard() {
|
|||||||
{/* Main Profile Section with Left Sidebar */}
|
{/* Main Profile Section with Left Sidebar */}
|
||||||
<div className="flex flex-col lg:flex-row gap-6">
|
<div className="flex flex-col lg:flex-row gap-6">
|
||||||
{/* Left Sidebar - Status & Contact */}
|
{/* Left Sidebar - Status & Contact */}
|
||||||
<div className="w-full lg:w-[180px] flex-shrink-0 space-y-4">
|
<ProfileSidebar
|
||||||
{/* Profile Image */}
|
profileImage={agentData.profileImage}
|
||||||
<div className="relative mx-auto lg:mx-0">
|
email="*****brian@gmail.com"
|
||||||
{/* Profile Image */}
|
phone={agentData.phone}
|
||||||
<div className="w-[200px] h-[200px] rounded-[15px] overflow-hidden">
|
|
||||||
<Image
|
|
||||||
src="/assets/demo_images/8f017153a7b4a239a4f0691234ef97dd55092282.jpg"
|
|
||||||
alt="Profile"
|
|
||||||
width={200}
|
|
||||||
height={200}
|
|
||||||
className="w-full h-full object-cover"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
{/* Edit Icon - Top Right Outside */}
|
|
||||||
<button className="absolute -top-3 -right-3 w-9 h-9 bg-white rounded-[10px] shadow-md flex items-center justify-center hover:bg-gray-50 transition-colors">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/edit-icon.svg"
|
|
||||||
alt="Edit profile"
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</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">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/edit-pencil-icon.svg"
|
|
||||||
alt="Edit phone"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right Content - Profile Info */}
|
{/* Right Content - Profile Info */}
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
{/* Profile Header Card */}
|
<ProfileHeader
|
||||||
<div className="bg-white rounded-[20px] border border-gray-200 p-6">
|
name={agentData.name}
|
||||||
{/* Name and Actions Row */}
|
isVerified={agentData.isVerified}
|
||||||
<div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-4">
|
title={agentData.title}
|
||||||
<div>
|
location={agentData.location}
|
||||||
{/* Name and Verification */}
|
memberSince={agentData.memberSince}
|
||||||
<div className="flex items-center gap-2 mb-1">
|
bio={agentData.bio}
|
||||||
<h1 className="text-[18px] text-[#00293d]">
|
expertise={agentData.expertise}
|
||||||
<span className="font-bold">{agentData.name.split(' ')[0]}</span>{' '}
|
|
||||||
<span className="font-normal">{agentData.name.split(' ')[1]}</span>
|
|
||||||
</h1>
|
|
||||||
{agentData.isVerified && (
|
|
||||||
<>
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/verified-icon.svg"
|
|
||||||
alt="Verified"
|
|
||||||
width={15}
|
|
||||||
height={14}
|
|
||||||
/>
|
/>
|
||||||
<span className="text-[14px] text-[#638559] font-medium font-serif">
|
|
||||||
(Verified Expert)
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<button className="p-1 hover:bg-gray-100 rounded transition-colors">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/edit-pencil-icon.svg"
|
|
||||||
alt="Edit name"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Title */}
|
|
||||||
<p className="text-[#00293d] text-sm mb-2">{agentData.title}</p>
|
|
||||||
|
|
||||||
{/* Location and Member Since */}
|
|
||||||
<div className="flex items-center gap-4 text-sm text-[#00293d]">
|
|
||||||
<span className="flex items-center gap-1 text-[#e58625] font-medium">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/location-icon.svg"
|
|
||||||
alt="Location"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
{agentData.location}
|
|
||||||
</span>
|
|
||||||
<span className="flex items-center gap-1">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/calendar-icon.svg"
|
|
||||||
alt="Calendar"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
Member Since {agentData.memberSince}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Action Buttons */}
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<Button
|
|
||||||
variant="action"
|
|
||||||
size="sm"
|
|
||||||
leftIcon={
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/message-icon.svg"
|
|
||||||
alt="Message"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Message
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="action"
|
|
||||||
size="sm"
|
|
||||||
leftIcon={
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/clipboard-icon.svg"
|
|
||||||
alt="Requests"
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Requests
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Bio */}
|
|
||||||
<p className="text-[#00293d] text-sm leading-relaxed mb-4">{agentData.bio}</p>
|
|
||||||
|
|
||||||
{/* Expertise Tags */}
|
|
||||||
<div>
|
|
||||||
<p className="font-bold text-[#00293d] text-sm mb-2">Expertise:</p>
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
{agentData.expertise.map((tag, idx) => (
|
|
||||||
<Tag key={idx}>{tag}</Tag>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Experience Section */}
|
{/* Experience Section */}
|
||||||
<div className="bg-white rounded-[20px] border border-gray-200 p-6">
|
<ExperienceSection experience={agentData.experience} />
|
||||||
<h2 className="text-xl font-bold text-[#00293d] mb-6">Experience</h2>
|
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
|
||||||
{/* 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 & 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>
|
|
||||||
|
|
||||||
{/* Divider */}
|
|
||||||
<div className="hidden lg:block w-px bg-gray-200" />
|
|
||||||
|
|
||||||
{/* Right Column */}
|
|
||||||
<div className="flex-1 space-y-6">
|
|
||||||
<div>
|
|
||||||
<p className="font-bold text-[#00293d] text-sm mb-3">Areas in expertise & 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 */}
|
{/* Info Cards Section */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
@@ -537,30 +240,13 @@ export default function AgentDashboard() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
{agentData.testimonials.map((testimonial) => (
|
{agentData.testimonials.map((testimonial) => (
|
||||||
<div key={testimonial.id} className="p-4">
|
<TestimonialCard
|
||||||
<div className="flex items-start gap-3 mb-4">
|
key={testimonial.id}
|
||||||
<div className="w-8 h-8 rounded-full bg-[#e58625]/20 flex items-center justify-center flex-shrink-0">
|
text={testimonial.text}
|
||||||
<span className="text-[#e58625] text-lg font-serif">“</span>
|
author={testimonial.author}
|
||||||
</div>
|
role={testimonial.role}
|
||||||
<p className="font-bold text-[#00293d] text-sm">I have been working with Lorem .</p>
|
rating={testimonial.rating}
|
||||||
</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">
|
|
||||||
<Image
|
|
||||||
src="/assets/icons/user-placeholder-icon.svg"
|
|
||||||
alt="User"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div className="flex-1">
|
|
||||||
<StarRating rating={testimonial.rating} />
|
|
||||||
<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>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
--font-sans: var(--font-geist-sans);
|
--font-sans: var(--font-geist-sans);
|
||||||
--font-mono: var(--font-geist-mono);
|
--font-mono: var(--font-geist-mono);
|
||||||
--font-serif: var(--font-source-serif-4);
|
--font-serif: var(--font-source-serif-4);
|
||||||
|
--font-fractul: var(--font-fractul);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable dark mode for consistent branding */
|
/* Disable dark mode for consistent branding */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono, Source_Serif_4 } from "next/font/google";
|
import { Geist, Geist_Mono, Source_Serif_4, Nunito_Sans } from "next/font/google";
|
||||||
import { SessionProvider } from "@/components/providers/session-provider";
|
import { SessionProvider } from "@/components/providers/session-provider";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
@@ -19,6 +19,13 @@ const sourceSerif4 = Source_Serif_4({
|
|||||||
weight: ["400", "500", "600", "700"],
|
weight: ["400", "500", "600", "700"],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Using Nunito Sans as a close alternative to Fractul (similar geometric sans-serif style)
|
||||||
|
const nunitoSans = Nunito_Sans({
|
||||||
|
variable: "--font-fractul",
|
||||||
|
subsets: ["latin"],
|
||||||
|
weight: ["400", "500", "600", "700", "800"],
|
||||||
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Real Estate Platform",
|
title: "Real Estate Platform",
|
||||||
description: "Find your dream property with trusted agents",
|
description: "Find your dream property with trusted agents",
|
||||||
@@ -32,7 +39,7 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} ${sourceSerif4.variable} antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} ${sourceSerif4.variable} ${nunitoSans.variable} antialiased`}
|
||||||
>
|
>
|
||||||
<SessionProvider>{children}</SessionProvider>
|
<SessionProvider>{children}</SessionProvider>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user