forked from izu/student-web-if-development-kit
refactor(tapops): modularize page code
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
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.fileType = DocumentFormatter.fileTypeFromName(this.title);
|
||||
this.assetUrl = DirectusClient.assetUrl(item.file);
|
||||
this.viewerUrl = DirectusClient.viewerUrl(item);
|
||||
this.downloadName = DocumentFormatter.downloadFilename(this.title, this.fileType);
|
||||
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.fileType === 'pdf' ? 'doc-type-pdf' : 'doc-type-docx';
|
||||
const iconClass = this.fileType === 'pdf' ? 'fas fa-file-pdf' : 'fas fa-file-word';
|
||||
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(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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user