|
import { api } from '../api.js';
|
|
|
|
class PhotoGallery extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.photos = [];
|
|
this.boundHandleClick = this.handleClick.bind(this);
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.addEventListener('click', this.boundHandleClick);
|
|
this.render();
|
|
this.loadPhotos();
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
this.removeEventListener('click', this.boundHandleClick);
|
|
}
|
|
|
|
async loadPhotos() {
|
|
try {
|
|
this.photos = await api.getPhotos();
|
|
this.renderPhotos();
|
|
} catch (error) {
|
|
console.error('Failed to load photos:', error);
|
|
this.querySelector('.gallery-grid').innerHTML = '<p>Failed to load photos</p>';
|
|
}
|
|
}
|
|
|
|
async renderPhotos() {
|
|
const grid = this.querySelector('.gallery-grid');
|
|
if (this.photos.length === 0) {
|
|
grid.innerHTML = '<p class="empty-state">No photos yet</p>';
|
|
return;
|
|
}
|
|
|
|
grid.innerHTML = this.photos.map(photo => `
|
|
<div class="photo-item" data-file-id="${photo.id}">
|
|
<img
|
|
data-photo-id="${photo.id}"
|
|
alt="${photo.name}"
|
|
loading="lazy"
|
|
style="background: #f0f0f0;"
|
|
>
|
|
<div class="photo-info">
|
|
<span class="photo-name">${photo.name}</span>
|
|
<span class="photo-date">${new Date(photo.created_at).toLocaleDateString()}</span>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
grid.querySelectorAll('img[data-photo-id]').forEach(async (img) => {
|
|
const photoId = img.dataset.photoId;
|
|
try {
|
|
const response = await fetch(`/files/thumbnail/${photoId}`, {
|
|
headers: {
|
|
'Authorization': `Bearer ${api.getToken()}`
|
|
}
|
|
});
|
|
if (response.ok) {
|
|
const blob = await response.blob();
|
|
img.src = URL.createObjectURL(blob);
|
|
} else {
|
|
img.style.display = 'none';
|
|
}
|
|
} catch (error) {
|
|
img.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
this.attachListeners();
|
|
}
|
|
|
|
handleClick(e) {
|
|
const photoItem = e.target.closest('.photo-item');
|
|
if (photoItem) {
|
|
const fileId = photoItem.dataset.fileId;
|
|
const photo = this.photos.find(p => p.id === parseInt(fileId));
|
|
this.dispatchEvent(new CustomEvent('photo-click', {
|
|
detail: { photo },
|
|
bubbles: true
|
|
}));
|
|
}
|
|
}
|
|
|
|
attachListeners() {
|
|
}
|
|
|
|
render() {
|
|
this.innerHTML = `
|
|
<div class="photo-gallery">
|
|
<div class="gallery-header">
|
|
<h2>Photo Gallery</h2>
|
|
</div>
|
|
<div class="gallery-grid"></div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
customElements.define('photo-gallery', PhotoGallery);
|
|
export { PhotoGallery };
|