75 lines
3.4 KiB
JavaScript
75 lines
3.4 KiB
JavaScript
import { DirectusClient } from '../services/directus-client.js';
|
|
import { FileDownloader } from '../services/file-downloader.js';
|
|
import { DocumentFormatter } from '../utils/document-formatter.js';
|
|
|
|
export class DocumentCardView {
|
|
constructor(item) {
|
|
this.item = item;
|
|
this.title = item.nama_berkas;
|
|
this.tags = DocumentFormatter.parseTags(item.tag);
|
|
this.category = DocumentFormatter.categoryFromTags(this.tags);
|
|
this.fileInfo = DocumentFormatter.fileInfoFromItem(item);
|
|
this.fileType = this.fileInfo.type;
|
|
this.assetUrl = DirectusClient.assetUrl(item.file);
|
|
this.viewerUrl = DirectusClient.viewerUrl(item);
|
|
this.downloadName = DocumentFormatter.downloadFilenameFromItem(item);
|
|
this.dateIso = item.tanggal_upload || '';
|
|
this.dateKey = this.dateIso ? this.dateIso.substring(0, 10) : '';
|
|
}
|
|
|
|
render() {
|
|
const card = document.createElement('article');
|
|
card.className = 'document-card';
|
|
card.dataset.date = this.dateKey;
|
|
|
|
const typeUpper = this.fileType.toUpperCase();
|
|
const typeClass = this.fileInfo.css;
|
|
const iconClass = this.fileInfo.icon;
|
|
const formattedDate = DocumentFormatter.formatDate(this.dateIso);
|
|
|
|
const safeTitle = DocumentFormatter.escapeHtml(this.title);
|
|
const safeViewerUrl = DocumentFormatter.escapeAttr(this.viewerUrl);
|
|
const safeAssetUrl = DocumentFormatter.escapeAttr(this.assetUrl);
|
|
|
|
// Build tag badges HTML.
|
|
const tagBadgesHtml = this.tags.length
|
|
? `<div class="doc-tags"><i class="fas fa-tags doc-tags-icon"></i>${this.tags.map(t => `<span class="doc-tag">${DocumentFormatter.escapeHtml(DocumentFormatter.formatTag(t))}</span>`).join('')}</div>`
|
|
: '';
|
|
|
|
card.innerHTML = `
|
|
<div class="doc-type-icon ${typeClass}"><i class="${iconClass}"></i></div>
|
|
<h3 class="doc-title">${safeTitle}</h3>
|
|
<div class="doc-meta">
|
|
<span class="doc-badge">${typeUpper}</span>
|
|
<span class="doc-badge date"><i class="far fa-calendar-alt"></i> ${formattedDate}</span>
|
|
</div>
|
|
${tagBadgesHtml}
|
|
<div class="doc-actions">
|
|
<a href="${safeViewerUrl}" class="btn-action-primary" target="_blank" rel="noopener"><span data-tp-i18n="card_open">Buka Berkas</span> <i class="fas fa-external-link-alt"></i></a>
|
|
<a href="${safeAssetUrl}" class="btn-action-outline"><span data-tp-i18n="card_download">Unduh Berkas</span> <i class="fas fa-download"></i></a>
|
|
</div>
|
|
`;
|
|
|
|
card.querySelector('.btn-action-outline').addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
FileDownloader.download(this.assetUrl, this.downloadName);
|
|
});
|
|
|
|
// Prefetch the asset when the user hovers over the card so the
|
|
// browser cache already has the file by the time the viewer loads.
|
|
let prefetched = false;
|
|
card.addEventListener('mouseenter', () => {
|
|
if (prefetched) return;
|
|
prefetched = true;
|
|
const link = document.createElement('link');
|
|
link.rel = 'prefetch';
|
|
link.as = 'fetch';
|
|
link.crossOrigin = 'anonymous';
|
|
link.href = this.assetUrl;
|
|
document.head.appendChild(link);
|
|
}, { once: true });
|
|
|
|
return card;
|
|
}
|
|
}
|