import { View } from '../View.ts'; import { getName, getFullImg, copyMrf, delegateEvent } from '@/utils/index.ts'; import { fetchChildren, fetchRelated } from '@/api/index.ts'; import type { Store } from '@/state/store.ts'; import type { AppState, Tag } from '@/types/index.ts'; export class DetailPanel extends View { private panelEl: HTMLElement; constructor( container: HTMLElement, store: Store ) { super(container, store); this.panelEl = container; } async showDetail(mrf: string): Promise { const state = this.getState(); const tag = state.tags.find(t => t.mrf === mrf); if (!tag) return; this.setState({ selectedTag: tag }); this.panelEl.classList.add('open'); await this.renderDetail(tag); } close(): void { this.panelEl.classList.remove('open'); this.setState({ selectedTag: null }); } render(): void { const state = this.getState(); if (state.selectedTag) { this.renderDetail(state.selectedTag); } } private async renderDetail(tag: Tag): Promise { const state = this.getState(); const img = getFullImg(tag); const name = getName(tag, state.lang); this.panelEl.innerHTML = `
${img ? `${tag.ref}` : `
${tag.ref?.slice(0, 2) || 'T'}
` }
${tag.ref || ''}
${tag.mrf}
${name}
${tag.txt || tag.alias || ''}
`; this.bindDetailEvents(); await this.loadRelations(tag.mrf); } private bindDetailEvents(): void { const closeBtn = this.panelEl.querySelector('.detail-close'); closeBtn?.addEventListener('click', () => this.close()); const mrfEl = this.panelEl.querySelector('.detail-mrf'); mrfEl?.addEventListener('click', () => { const mrf = (mrfEl as HTMLElement).dataset.mrf; if (mrf) copyMrf(mrf); }); delegateEvent(this.panelEl, '.tag-chip', 'click', (_, target) => { const mrf = target.dataset.mrf; if (mrf) this.showDetail(mrf); }); } private async loadRelations(mrf: string): Promise { const [children, related] = await Promise.all([ fetchChildren(mrf), fetchRelated(mrf) ]); const childrenSection = this.panelEl.querySelector('#children-section') as HTMLElement; const childrenList = this.panelEl.querySelector('#children-list') as HTMLElement; if (children.length > 0) { childrenSection.style.display = 'block'; childrenList.innerHTML = children.map(c => { const label = c.name_es || c.alias || c.ref || c.mrf.slice(0, 8); return `${label}`; }).join(''); } const relatedSection = this.panelEl.querySelector('#related-section') as HTMLElement; const relatedList = this.panelEl.querySelector('#related-list') as HTMLElement; if (related.length > 0) { relatedSection.style.display = 'block'; relatedList.innerHTML = related.map(r => { const label = r.name_es || r.alias || r.ref || r.mrf.slice(0, 8); return `${label}`; }).join(''); } } }