raised = false, 200); }"
x-data="{
raised: false,
raiseTimer: null,
tab: $wire.entangle('activeHeroTab'),
}"
>
scrollLockUntil && ! $event.target.closest('[role=tablist], [role=dialog]')) { open = false; activeDropdown = null; }"
@scroll.window="if (ignoreScroll) { ignoreScroll = false; return; } if (open && Date.now() > scrollLockUntil) { open = false; activeDropdown = null; }"
@resize.window="if (open) { fitDropdown(); }"
x-data="{
open: false,
aiMode: false,
mobileScreen: false,
mobileFocus: false,
isMobile() {
return window.matchMedia('(max-width: 767px)').matches;
},
openMobile() {
this.$refs.input?.blur();
this.open = false;
this.mobileScreen = true;
this.mobileFocus = true;
this.$nextTick(() => document.getElementById('mobile-search-input')?.focus());
},
closeMobile() {
this.mobileScreen = false;
this.mobileFocus = false;
document.getElementById('mobile-search-input')?.blur();
},
openAiFromMobile() {
this.closeMobile();
this.aiMode = true;
this.$nextTick(() => document.querySelector('[x-ref=aiInput]')?.focus());
},
mobilePick(item) {
this.choose(item);
if (item.has_children === false) {
this.mobileFocus = false;
document.getElementById('mobile-search-input')?.blur();
}
},
removeFromMobile(index) {
this.selected.splice(index);
this.query = '';
this.mobileFocus = true;
document.getElementById('mobile-search-input')?.focus();
this.loadSuggestions();
},
mobileEnter() {
if (this.query.trim().length >= 2 && this.options.length) {
this.mobilePick(this.options[0]);
return;
}
this.submit();
},
nearMeMobile() {
this.nearMe(true);
},
aiPrompt: '',
aiSuggestions: JSON.parse('[\u00222-room apartment for rent in Sofia up to €800\u0022,\u0022Apartment for sale in Varna near the sea\u0022,\u0022Holiday home in Bansko under €100,000\u0022]'),
init() {
this.$watch('query', () => {
clearTimeout(this.suggestTimer);
this.suggestTimer = setTimeout(() => this.loadSuggestions(), 250);
});
// AI modunda normal konum listesi açılmaz; AI moduna geçiş açık listeyi (arka plan ve yükseltme dahil) kapatır.
this.$watch('aiMode', (val) => {
if (val) {
this.open = false;
this.activeDropdown = null;
this.$refs.input?.blur();
}
});
this.$watch('open', (val) => {
if (val && this.aiMode) {
this.open = false;
return;
}
if (val) { this.loadSuggestions(); }
});
this.$watch('mobileScreen', (val) => { if (val) { this.loadSuggestions(); } });
if (! navigator.geolocation) {
this.geoAvailable = false;
} else if (navigator.permissions?.query) {
navigator.permissions.query({ name: 'geolocation' }).then((status) => {
this.geoAvailable = status.state !== 'denied';
status.onchange = () => { this.geoAvailable = status.state !== 'denied'; };
}).catch(() => {});
}
this.$watch('open', (val) => {
this.$dispatch('hero-search-state', { open: val && !this.aiMode });
if (val && ! this.isMobile()) {
this.$nextTick(() => this.placeBar());
}
});
this.$watch('aiMode', (val) => {
this.$dispatch('hero-search-state', { open: !val && this.open });
});
},
scrollLockUntil: 0,
ignoreScroll: false,
minDropdownSpace: 460,
dropdownMaxHeight: '',
/** Açılan paneli header'ın altına oturtur ve panel yüksekliğini görünür alanla sınırlar. */
placeBar() {
const bar = this.$refs.bar;
if (! bar) {
return;
}
const headerBottom = Math.max(0, document.querySelector('[data-site-header]')?.getBoundingClientRect().bottom ?? 0);
const tabs = this.$el.parentElement?.querySelector('[role=tablist]') ?? bar;
const tabsTop = tabs.getBoundingClientRect().top;
const freeBelow = window.innerHeight - bar.getBoundingClientRect().bottom;
if (freeBelow < this.minDropdownSpace || tabsTop < headerBottom + 12) {
const target = Math.max(0, window.scrollY + tabsTop - headerBottom - 12);
if (Math.abs(target - window.scrollY) > 0.5) {
this.scrollLockUntil = Date.now() + 800;
this.ignoreScroll = true;
setTimeout(() => { this.ignoreScroll = false; }, 2000);
window.scrollTo({ top: target, behavior: 'instant' });
}
}
this.fitDropdown();
},
fitDropdown() {
const bar = this.$refs.bar;
if (! bar) {
return;
}
const space = window.innerHeight - bar.getBoundingClientRect().bottom - 24;
this.dropdownMaxHeight = Math.max(280, space) + 'px';
},
autoGrow(el) {
el.style.height = 'auto';
el.style.height = Math.min(el.scrollHeight, 160) + 'px';
},
sendAi() {
const prompt = this.aiPrompt.trim();
if (prompt === '') {
return;
}
this.$dispatch('assistant:open', { prompt: prompt });
this.aiPrompt = '';
this.aiMode = false;
},
query: '',
selected: [],
suggestions: [],
popular: [],
suggestTimer: null,
suggestRequest: 0,
suggestUrl: '/en/location-suggest',
nearestUrl: '/en/location-nearest',
searchUrl: '/en/search',
childrenUrl: '/en/location-children',
childGroups: [],
stepText: '',
levelHeadings: JSON.parse('{\u0022region\u0022:\u0022Area\u0022,\u0022municipality\u0022:\u0022Municipality\u0022,\u0022settlement\u0022:\u0022Settlement\u0022,\u0022district\u0022:\u0022District\u0022,\u0022neighborhood\u0022:\u0022Neighbourhood\u0022}'),
geoAvailable: true,
geoBusy: false,
async loadSuggestions() {
const term = this.query.trim();
const request = ++this.suggestRequest;
try {
if (term.length < 2 && this.selected.length) {
const deepest = this.selected[this.selected.length - 1];
const childResponse = await fetch(this.childrenUrl + '?parent=' + encodeURIComponent(deepest.id), { headers: { 'Accept': 'application/json' } });
if (! childResponse.ok || request !== this.suggestRequest) {
return;
}
const childData = await childResponse.json();
this.childGroups = childData.groups ?? [];
this.stepText = childData.step ?? '';
return;
}
this.childGroups = [];
const response = await fetch(this.suggestUrl + '?q=' + encodeURIComponent(term), { headers: { 'Accept': 'application/json' } });
if (! response.ok || request !== this.suggestRequest) {
return;
}
const data = await response.json();
this.suggestions = data.items ?? [];
if (term.length < 2) {
this.popular = data.popular ?? [];
}
} catch (error) {
if (request === this.suggestRequest) {
this.suggestions = [];
this.childGroups = [];
}
}
},
// Dropdowns
activeDropdown: null,
toggleDropdown(name) {
this.activeDropdown = this.activeDropdown === name ? null : name;
},
// Gayrimenkul Tipi
propertyType: '',
propertyTypes: JSON.parse('[{\u0022id\u0022:\u0022residential\u0022,\u0022key\u0022:\u0022residential\u0022,\u0022label\u0022:\u0022Residential\u0022},{\u0022id\u0022:\u0022apartment\u0022,\u0022key\u0022:\u0022apartment\u0022,\u0022label\u0022:\u0022Apartment\u0022},{\u0022id\u0022:\u0022villa\u0022,\u0022key\u0022:\u0022villa\u0022,\u0022label\u0022:\u0022Villa\u0022},{\u0022id\u0022:\u0022commercial\u0022,\u0022key\u0022:\u0022commercial\u0022,\u0022label\u0022:\u0022Commercial\u0022},{\u0022id\u0022:\u0022office\u0022,\u0022key\u0022:\u0022office\u0022,\u0022label\u0022:\u0022Office\u0022},{\u0022id\u0022:\u0022shop\u0022,\u0022key\u0022:\u0022shop\u0022,\u0022label\u0022:\u0022Shop\u0022},{\u0022id\u0022:\u0022warehouse\u0022,\u0022key\u0022:\u0022warehouse\u0022,\u0022label\u0022:\u0022Warehouse\u0022},{\u0022id\u0022:\u0022land\u0022,\u0022key\u0022:\u0022land\u0022,\u0022label\u0022:\u0022Land\u0022},{\u0022id\u0022:\u0022agricultural_land\u0022,\u0022key\u0022:\u0022agricultural_land\u0022,\u0022label\u0022:\u0022Field\u0022},{\u0022id\u0022:\u0022building_plot\u0022,\u0022key\u0022:\u0022building_plot\u0022,\u0022label\u0022:\u0022Land for Development Swap\u0022},{\u0022id\u0022:\u0022transfer_commercial\u0022,\u0022key\u0022:\u0022commercial\u0022,\u0022label\u0022:\u0022Business Transfer\u0022},{\u0022id\u0022:\u0022hospitality\u0022,\u0022key\u0022:\u0022hospitality\u0022,\u0022label\u0022:\u0022Hospitality Property\u0022}]'),
roomTypes: ['residential', 'apartment', 'villa', 'house'],
get showsRooms() {
return this.propertyType === '' || this.roomTypes.includes(this.propertyType);
},
get propertyTypeLabel() {
return this.propertyTypes.find((item) => item.id === this.propertyType)?.label ?? 'All';
},
selectPropertyType(item) {
this.propertyType = this.propertyType === item.id ? '' : item.id;
if (! this.showsRooms) {
this.selectedRooms = [];
if (this.activeDropdown === 'rooms') {
this.activeDropdown = null;
}
}
},
// Oda Sayısı
roomOptions: JSON.parse('[{\u0022value\u0022:1,\u0022label\u0022:\u00221 room\u0022},{\u0022value\u0022:2,\u0022label\u0022:\u00222 rooms\u0022},{\u0022value\u0022:3,\u0022label\u0022:\u00223 rooms\u0022},{\u0022value\u0022:4,\u0022label\u0022:\u00224 rooms\u0022},{\u0022value\u0022:5,\u0022label\u0022:\u00225+ rooms\u0022}]'),
selectedRooms: [],
toggleRoom(room) {
const idx = this.selectedRooms.indexOf(room);
if (idx > -1) {
this.selectedRooms.splice(idx, 1);
} else {
this.selectedRooms.push(room);
}
},
get roomsLabel() {
return this.selectedRooms.length
? this.roomOptions.filter((room) => this.selectedRooms.includes(room.value)).map((room) => room.label).join(', ')
: 'All';
},
// Fiyat Aralığı
minPrice: '',
maxPrice: '',
sliderMin: 0,
sliderMax: 2000000,
formatPriceDisplay(val) {
if (!val) return '';
const num = Number(val);
if (num >= 1000000) {
const m = (num / 1000000);
return (m % 1 === 0 ? m : m.toFixed(1)) + 'M';
}
if (num >= 1000) {
return Math.round(num / 1000) + 'K';
}
return num.toLocaleString(document.documentElement.lang);
},
euro(text) {
return new Intl.NumberFormat(document.documentElement.lang, { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).formatToParts(0).map((part) => part.type === 'integer' ? text : part.value).join('').replace(/\s+/g, ' ');
},
get priceRangeLabel() {
const minNum = this.minPrice ? parseInt(this.minPrice.toString().replace(/\D/g, ''), 10) : 0;
const maxNum = this.maxPrice ? parseInt(this.maxPrice.toString().replace(/\D/g, ''), 10) : 0;
if (!minNum && !maxNum) {
return this.euro('0') + ' - ' + this.euro('2M+');
}
const minText = minNum ? this.euro(this.formatPriceDisplay(minNum)) : this.euro('0');
const maxText = maxNum ? this.euro(this.formatPriceDisplay(maxNum)) : this.euro('2M+');
return minText + ' - ' + maxText;
},
updateFromSlider() {
this.minPrice = this.sliderMin > 0 ? this.sliderMin.toLocaleString(document.documentElement.lang) : '';
this.maxPrice = this.sliderMax < 2000000 ? this.sliderMax.toLocaleString(document.documentElement.lang) : '';
},
updateFromInput() {
const minVal = parseInt((this.minPrice || '0').toString().replace(/\D/g, ''), 10) || 0;
const maxVal = parseInt((this.maxPrice || '2000000').toString().replace(/\D/g, ''), 10) || 2000000;
this.sliderMin = Math.min(Math.max(minVal, 0), 2000000);
this.sliderMax = Math.min(Math.max(maxVal, 0), 2000000);
},
// AI Filtre
minRent: '',
maxRent: '',
rentMin: 0,
rentMax: 6000,
minPayback: '',
maxPayback: '',
paybackMin: 5,
paybackMax: 30,
sortOptions: [
'Yatırımlık',
'Geri Dönüş Süresi',
'Kira Geliri',
'Fiyatı Düşen'
],
selectedSort: '',
pricePresets: [
{ label: 'All', min: 0, max: 0 },
{ label: '≤€100K', min: 0, max: 100000 },
{ label: '€100–250K', min: 100000, max: 250000 },
{ label: '€250–500K', min: 250000, max: 500000 },
{ label: '€500K+', min: 500000, max: 0 },
],
numericPrice(value) {
return parseInt((value || '0').toString().replace(/\D/g, ''), 10) || 0;
},
setPricePreset(preset) {
this.minPrice = preset.min ? preset.min.toLocaleString(document.documentElement.lang) : '';
this.maxPrice = preset.max ? preset.max.toLocaleString(document.documentElement.lang) : '';
this.updateFromInput();
},
isPricePreset(preset) {
return this.numericPrice(this.minPrice) === preset.min && this.numericPrice(this.maxPrice) === preset.max;
},
aiFilterOptions: [
{ key: 'yatirimSkoru', label: 'High investment score' },
{ key: 'geriDonus', label: 'Quick payback' },
{ key: 'kiraGetirisi', label: 'High rental yield' },
{ key: 'fiyatiDusen', label: 'Price dropped' },
],
aiFilterParams: {
yatirimSkoru: { score_min: 70 },
geriDonus: { payback_max: 15 },
kiraGetirisi: { yield_min: 6 },
fiyatiDusen: { price_dropped: 1 },
},
sortParams: {
'Yatırımlık': 'investment_score',
'Geri Dönüş Süresi': 'payback',
'Kira Geliri': 'rental_income',
'Fiyatı Düşen': 'price_dropped',
},
selectedAiFilters: [],
toggleAiFilter(key) {
const idx = this.selectedAiFilters.indexOf(key);
if (idx > -1) {
this.selectedAiFilters.splice(idx, 1);
} else {
this.selectedAiFilters.push(key);
}
},
get aiMobileLabel() {
return this.selectedAiFilters.length ? this.selectedAiFilters.length + ' ' + 'selected' : 'All';
},
toggleSort(item) {
this.selectedSort = this.selectedSort === item ? '' : item;
},
get aiFilterLabel() {
return this.selectedSort || 'All';
},
nearMe(mobile = false) {
if (! navigator.geolocation || this.geoBusy) {
this.geoAvailable = false;
return;
}
this.geoBusy = true;
navigator.geolocation.getCurrentPosition(
async (position) => {
try {
const response = await fetch(this.nearestUrl + '?lat=' + position.coords.latitude + '&lng=' + position.coords.longitude, { headers: { 'Accept': 'application/json' } });
const data = response.ok ? await response.json() : { item: null };
if (data.item) {
this.selected = [data.item];
this.query = '';
this.loadSuggestions();
this.open = ! mobile;
this.mobileFocus = false;
} else {
this.geoAvailable = false;
}
} catch (error) {
this.geoAvailable = false;
} finally {
this.geoBusy = false;
}
},
() => {
this.geoAvailable = false;
this.geoBusy = false;
},
{ timeout: 10000, maximumAge: 300000 }
);
},
get browsingChildren() {
return this.query.trim().length < 2 && this.selected.length > 0;
},
get options() {
if (this.browsingChildren) {
return this.childGroups.flatMap((group) => group.items.map((item) => ({ ...item, level: group.type })));
}
return this.query.trim().length < 2 ? this.popular : this.suggestions;
},
get groupCount() {
return this.query.trim().length < 2 ? new Set(this.options.map((item) => item.level)).size : 0;
},
get groupedOptions() {
const grouped = this.groupCount > 1;
let previous = null;
return this.options.map((item) => {
const heading = grouped && item.level !== previous
? (this.browsingChildren ? (this.childGroups.find((group) => group.type === item.level)?.heading ?? '') : (this.levelHeadings[item.level] ?? ''))
: '';
previous = item.level;
return { item, heading };
});
},
get stepLabel() {
return this.selected.length ? this.stepText : 'Select a city';
},
get selectedLabel() {
return this.selected.map((item) => item.label).join(' / ');
},
choose(item) {
this.selected = this.query.trim().length >= 2 ? [item] : [...this.selected, item];
this.query = '';
this.loadSuggestions();
},
pick(item) {
this.choose(item);
this.activeDropdown = null;
this.open = true;
this.$refs.input?.focus();
},
removeFrom(index) {
this.selected.splice(index);
this.query = '';
this.activeDropdown = null;
this.open = true;
this.$refs.input?.focus();
this.loadSuggestions();
},
backspace() {
if (this.query === '' && this.selected.length) {
this.selected.pop();
this.loadSuggestions();
}
},
enter() {
if (this.query.trim().length >= 2 && this.options.length) {
this.pick(this.options[0]);
return;
}
this.submit();
},
submit() {
const currentTab = (typeof tab !== 'undefined') ? tab : 'satilik';
const params = new URLSearchParams();
const location = this.selected[this.selected.length - 1] ?? null;
const term = this.query.trim();
if (location) {
params.set('location', location.id);
}
if (currentTab === 'danisman') {
params.set('tab', 'danisman');
} else {
if (currentTab === 'kiralik') {
params.set('transaction', 'rent');
} else {
params.set('transaction', 'sale');
}
if (currentTab === 'proje') {
params.set('new_build', '1');
}
const chosenType = this.propertyTypes.find((item) => item.id === this.propertyType);
if (chosenType) {
params.set('type', chosenType.key);
}
this.selectedAiFilters.forEach((key) => {
Object.entries(this.aiFilterParams[key] ?? {}).forEach(([name, value]) => params.set(name, value));
});
if (this.selectedSort && this.sortParams[this.selectedSort]) {
params.set('sort', this.sortParams[this.selectedSort]);
}
[['rent_income_min', this.minRent], ['rent_income_max', this.maxRent], ['payback_min', this.minPayback], ['payback_max', this.maxPayback]].forEach(([name, value]) => {
const number = this.numericPrice(value);
if (number) {
params.set(name, number);
}
});
if (term && ! location) {
params.set('q', term);
}
if (this.showsRooms) {
this.selectedRooms.forEach((room) => params.append('rooms[]', room));
}
const minPrice = this.numericPrice(this.minPrice);
const maxPrice = this.numericPrice(this.maxPrice);
if (minPrice) {
params.set('price_min', minPrice);
}
if (maxPrice) {
params.set('price_max', maxPrice);
}
}
this.open = false;
this.mobileScreen = false;
this.activeDropdown = null;
Livewire.navigate(this.searchUrl + '?' + params.toString());
},
}"
>
Find the property you're looking for with Imo
autoGrow($refs.aiInput))" class="shrink-0 cursor-pointer whitespace-nowrap rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 transition hover:border-emerald-700 hover:bg-emerald-50 dark:hover:bg-emerald-500/10 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200" x-text="suggestion">
$refs.aiInput?.focus())"
aria-label="Search with AI"
class="group inline-flex h-11 shrink-0 cursor-pointer items-center justify-center gap-2 rounded-xl bg-[#e3f7f6] max-sm:w-11 sm:px-3.5 transition hover:bg-[#d5f3f1] dark:bg-teal-950/60 dark:hover:bg-teal-950/80 active:scale-95"
>
Search with AI
Property Type
Rooms
Price Range
AI Filter
Search