diff --git a/src/app/(user)/user/profiles/page.tsx b/src/app/(user)/user/profiles/page.tsx index b62b908..0c67920 100644 --- a/src/app/(user)/user/profiles/page.tsx +++ b/src/app/(user)/user/profiles/page.tsx @@ -405,6 +405,7 @@ function ProfilesPageContent() { const typeFromUrl = searchParams.get('type'); const nameFromUrl = searchParams.get('name') || ''; const locationFromUrl = searchParams.get('location') || ''; + const filtersFromUrl = searchParams.get('filters') || ''; // State for API data const [agents, setAgents] = useState([]); @@ -422,13 +423,29 @@ function ProfilesPageContent() { const [activeTypeId, setActiveTypeId] = useState(typeFromUrl); const [listingType, setListingType] = useState<'agents' | 'lenders'>('agents'); const [isFilterModalOpen, setIsFilterModalOpen] = useState(false); - const [filters, setFilters] = useState({}); + const [filters, setFilters] = useState(() => { + if (filtersFromUrl) { + try { + return JSON.parse(filtersFromUrl) as FilterState; + } catch { + return {}; + } + } + return {}; + }); // Sync state when URL params change (e.g., browser back/forward, client-side navigation) useEffect(() => { setActiveTypeId(typeFromUrl); setSearchQuery(nameFromUrl); - }, [typeFromUrl, nameFromUrl]); + if (filtersFromUrl) { + try { + setFilters(JSON.parse(filtersFromUrl) as FilterState); + } catch { + // ignore invalid JSON + } + } + }, [typeFromUrl, nameFromUrl, filtersFromUrl]); // Fetch agent types and filter fields on mount useEffect(() => { diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx index a757e46..3fc8691 100644 --- a/src/components/home/HeroSection.tsx +++ b/src/components/home/HeroSection.tsx @@ -4,6 +4,7 @@ import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import Image from 'next/image'; import { agentsService, AgentType } from '@/services/agents.service'; +import { profileSectionsService } from '@/services/profile-sections.service'; import type { HeroContent } from '@/types/cms'; const defaultHeroContent: HeroContent = { @@ -17,25 +18,18 @@ export function HeroSection({ content }: { content?: HeroContent }) { const data = content ?? defaultHeroContent; const router = useRouter(); const [agentTypes, setAgentTypes] = useState([]); + const [specializationOptions, setSpecializationOptions] = useState<{ id: string; name: string }[]>([]); + const [specializationSlug, setSpecializationSlug] = useState(''); const [searchParams, setSearchParams] = useState({ - category: '', + specialization: '', type: '', name: '', location: '', }); const [openDropdown, setOpenDropdown] = useState(null); - - // Category options (UI only - no functionality) - const categoryOptions = [ - { id: 'residential', name: 'Residential' }, - { id: 'commercial', name: 'Commercial' }, - { id: 'industrial', name: 'Industrial' }, - { id: 'land', name: 'Land' }, - { id: 'rental', name: 'Rental' }, - ]; const [validationError, setValidationError] = useState(null); - // Fetch agent types on mount + // Fetch agent types and specialization options on mount useEffect(() => { const fetchAgentTypes = async () => { try { @@ -45,7 +39,20 @@ export function HeroSection({ content }: { content?: HeroContent }) { console.error('Failed to fetch agent types:', error); } }; + const fetchSpecializations = async () => { + try { + const fields = await profileSectionsService.getFilterableFields(); + const specField = fields.find(f => f.slug.includes('specialization')); + if (specField) { + setSpecializationSlug(specField.slug); + setSpecializationOptions(specField.options.map(o => ({ id: o.value, name: o.label }))); + } + } catch (error) { + console.error('Failed to fetch specializations:', error); + } + }; fetchAgentTypes(); + fetchSpecializations(); }, []); const handleSearch = () => { @@ -53,9 +60,10 @@ export function HeroSection({ content }: { content?: HeroContent }) { const hasType = searchParams.type.trim() !== ''; const hasName = searchParams.name.trim() !== ''; const hasLocation = searchParams.location.trim() !== ''; + const hasSpecialization = searchParams.specialization.trim() !== ''; - if (!hasType && !hasName && !hasLocation) { - setValidationError('Please enter at least one search criteria (Type, Name/Keyword, or Location)'); + if (!hasType && !hasName && !hasLocation && !hasSpecialization) { + setValidationError('Please enter at least one search criteria (Type, Name/Keyword, Location, or Specialization)'); return; } @@ -66,6 +74,9 @@ export function HeroSection({ content }: { content?: HeroContent }) { 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.specialization && specializationSlug) { + params.set('filters', JSON.stringify({ [specializationSlug]: [searchParams.specialization] })); + } router.push(`/user/profiles?${params.toString()}`); }; @@ -77,9 +88,10 @@ export function HeroSection({ content }: { content?: HeroContent }) { setOpenDropdown(openDropdown === dropdown ? null : dropdown); }; - const selectCategory = (value: string) => { - setSearchParams({ ...searchParams, category: value }); + const selectSpecialization = (value: string) => { + setSearchParams({ ...searchParams, specialization: value }); setOpenDropdown(null); + setValidationError(null); }; const selectType = (value: string) => { @@ -179,32 +191,32 @@ export function HeroSection({ content }: { content?: HeroContent }) { /> - {/* Category Select (UI only) */} + {/* Specialization Select */}
- {openDropdown === 'category' && ( + {openDropdown === 'specialization' && (
- {categoryOptions.map((category, index, arr) => ( + {specializationOptions.map((option, index, arr) => ( ))}