/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import searchState, { debouncedFetch } from '@/app/api/[[...slugs]]/_lib/search/searchState'; import { Box, Center, Loader, Popover, Text, TextInput } from '@mantine/core'; import { IconX } from '@tabler/icons-react'; import { useEffect, useState } from 'react'; import { useSnapshot } from 'valtio'; import getDetailUrl from './searchUrl'; export default function GlobalSearch() { const snap = useSnapshot(searchState); const [opened, setOpened] = useState(false); const [isNavigating, setIsNavigating] = useState(false); // Buka popover saat ada query useEffect(() => { setOpened(!!snap.query); }, [snap.query]); // Infinite scroll handler useEffect(() => { const handleScroll = () => { const nearBottom = window.innerHeight + window.scrollY >= document.body.offsetHeight - 200; if (nearBottom && !snap.loading) searchState.next(); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, [snap.loading]); const handleSelect = async (e: React.MouseEvent, item: any) => { e.preventDefault(); e.stopPropagation(); if (isNavigating) return; setIsNavigating(true); try { // 🔥 pastikan objek udah “dikeluarkan” dari Proxy valtio const rawItem = JSON.parse(JSON.stringify(item)); // 🔥 pastikan type-nya string murni const type = String(rawItem.type || '').trim().toLowerCase(); // 🔥 panggil getDetailUrl pakai type yang fix let url = getDetailUrl({ ...rawItem, type }); // kalau hasil undefined atau default, fallback ke link eksternal if (!url || url === '/darmasaba') { if (rawItem.link && rawItem.link.startsWith('http')) { url = rawItem.link; } } if (!url) { console.warn('URL tidak ditemukan untuk item:', rawItem); setIsNavigating(false); return; } console.log('Navigating to:', url); // tutup popover dulu setOpened(false); searchState.query = ''; searchState.results = []; searchState.loading = false; // kasih delay biar UI nutup dulu await new Promise((r) => setTimeout(r, 100)); // navigasi if (url.startsWith('http')) { window.location.href = url; } else { window.location.href = url; } } catch (err) { console.error('Error saat navigasi:', err); setIsNavigating(false); } }; const clearSearch = () => { searchState.query = ''; searchState.results = []; searchState.page = 1; searchState.nextPage = null; setOpened(false); setIsNavigating(false); }; return ( { if (!isOpen) clearSearch(); setOpened(isOpen); }} width="target" position="bottom" shadow="md" withinPortal radius="md" zIndex={2000} closeOnClickOutside={true} closeOnEscape={true} styles={{ dropdown: { zIndex: 2000, borderRadius: 12, overflow: 'hidden', }, }} > { searchState.query = e.currentTarget.value; debouncedFetch(); }} radius="xl" size="md" rightSection={ snap.query ? ( ) : undefined } /> {[...snap.results].length > 0 ? ( [...snap.results].map((item: any, i: number) => ( !isNavigating && (e.currentTarget.style.background = '#f9f9f9')} onMouseLeave={(e) => (e.currentTarget.style.background = 'white')} onClick={(e) => handleSelect(e, item)} > {item.name ?? item.nama ?? item.namaPasar ?? item.judul ?? '(Tanpa nama)'} dari modul: {item.type || '-'} )) ) : (
{snap.loading ? : Tidak ada hasil}
)}
); }