Add image carousel yippie
This commit is contained in:
78
web/src/components/photos/carousel.astro
Normal file
78
web/src/components/photos/carousel.astro
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
import { authPB } from "src/utils/pocketbase";
|
||||||
|
import type { RecordModel } from 'pocketbase'
|
||||||
|
|
||||||
|
// export const prerender = false
|
||||||
|
|
||||||
|
const pb = await authPB()
|
||||||
|
const photos = await pb.collection('photos').getFullList({
|
||||||
|
sort: '-created'
|
||||||
|
})
|
||||||
|
|
||||||
|
const getImageLink = async (record: any) => {
|
||||||
|
return pb.files.getURL(record, record.image)
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let pos = 0;
|
||||||
|
const dataElement = document.getElementById('carousel-data');
|
||||||
|
const photos = dataElement ? JSON.parse(dataElement.textContent || '[]') : [];
|
||||||
|
const cap = photos.length - 1;
|
||||||
|
const img = document.getElementById('carousel-img') as HTMLImageElement;
|
||||||
|
const titleEl = document.getElementById('photo-title');
|
||||||
|
const cameraEl = document.getElementById('photo-camera');
|
||||||
|
const locationEl = document.getElementById('photo-location');
|
||||||
|
|
||||||
|
function updatePhoto() {
|
||||||
|
const currentPhoto = photos[pos];
|
||||||
|
|
||||||
|
// Update image src
|
||||||
|
if (img && currentPhoto) {
|
||||||
|
const imageUrl = `/api/files/photos/${currentPhoto.id}/${currentPhoto.image}`;
|
||||||
|
img.src = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update metadata
|
||||||
|
if (titleEl) {
|
||||||
|
titleEl.textContent = currentPhoto.title || "Untitled";
|
||||||
|
}
|
||||||
|
if (cameraEl) {
|
||||||
|
cameraEl.textContent = currentPhoto.camera || "";
|
||||||
|
}
|
||||||
|
if (locationEl) {
|
||||||
|
locationEl.textContent = currentPhoto.location || "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inc() {
|
||||||
|
pos = pos === cap ? 0 : pos + 1;
|
||||||
|
updatePhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dec() {
|
||||||
|
pos = pos === 0 ? cap : pos - 1;
|
||||||
|
updatePhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
// make functions globally accessible
|
||||||
|
(window as any).inc = inc;
|
||||||
|
(window as any).dec = dec;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- Hidden element to pass server data to client -->
|
||||||
|
<div class="hidden" id="carousel-data">{JSON.stringify(photos)}</div>
|
||||||
|
|
||||||
|
<!-- <div class="flex flex-col w-7/8 self-center"> -->
|
||||||
|
<!-- <button id="dec-button" class="" onclick="dec()"><</button>
|
||||||
|
<button id="inc-button" class="" onclick="inc()">></button> -->
|
||||||
|
<img id="carousel-img" class="rounded-lg w-full h-full object-cover" src={ pb.files.getURL(photos[0], photos[0].image) } />
|
||||||
|
<!-- <div class="flex flex-col">
|
||||||
|
|
||||||
|
<p id="photo-title" class="bold text-2xl">{photos[0].title === "" ? "Untitled" : photos[0].title}</p>
|
||||||
|
{photos[0].camera && <p id="photo-camera" class="text-sm">{photos[0].camera}</p>}
|
||||||
|
{photos[0].location && <p id="photo-location" class="text-sm">{photos[0].location}</p>}
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import BaseHead from "./BaseHead.astro"
|
import BaseHead from "./BaseHead.astro"
|
||||||
import Sidebar from "@components/sidebar"
|
import Sidebar from "@components/sidebar"
|
||||||
|
import Navbar from "@components/index/navbar"
|
||||||
import Footer from "@components/footer"
|
import Footer from "@components/footer"
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -17,6 +18,13 @@ import Footer from "@components/footer"
|
|||||||
<slot name="sidebar" />
|
<slot name="sidebar" />
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|
||||||
|
<!-- <a href="/" class="b1-no-underline text-4xl">breadone dot net</a>
|
||||||
|
<Navbar/>
|
||||||
|
|
||||||
|
<div class="text-start mt-8">
|
||||||
|
<slot name="sidebar" />
|
||||||
|
</div> -->
|
||||||
|
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,33 @@
|
|||||||
---
|
---
|
||||||
import Base from "src/layout/Base.astro"
|
import Base from "src/layout/Base.astro"
|
||||||
|
import Carousel from "@components/photos/carousel"
|
||||||
import Sidebar from "src/components/sidebar.astro"
|
import Sidebar from "src/components/sidebar.astro"
|
||||||
import { authPB } from 'src/utils/pocketbase'
|
import { authPB } from 'src/utils/pocketbase'
|
||||||
import type { RecordModel } from 'pocketbase'
|
import type { RecordModel } from 'pocketbase'
|
||||||
|
|
||||||
export const prerender = false
|
|
||||||
|
|
||||||
const pb = await authPB()
|
const pb = await authPB()
|
||||||
const photos = await pb.collection('photos').getFullList({
|
const photos = await pb.collection('photos').getFullList({
|
||||||
sort: '-created'
|
sort: '-created'
|
||||||
})
|
})
|
||||||
|
|
||||||
const getImageLink = async (record: RecordModel) => {
|
|
||||||
const link = await pb.files.getURL(record, record.image)
|
|
||||||
return link.substring(21)
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Base>
|
<Base>
|
||||||
<div slot="sidebar">
|
<div slot="sidebar">
|
||||||
<p class="text-2xl">Photography :)</p>
|
<p id="photo-title" class="bold text-2xl">{photos[0].title === "" ? "Untitled" : photos[0].title}</p>
|
||||||
Chuck me an email if you'd like a print of these, I'll see what I can do
|
<p id="photo-camera" class="text-sm">📸 {photos[0].camera}</p>
|
||||||
|
<p id="photo-location" class="text-sm">📌 {photos[0].location}</p>
|
||||||
|
|
||||||
|
<button id="dec-button" class="" onclick="dec()"><</button>
|
||||||
|
<button id="inc-button" class="" onclick="inc()">></button>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <p class="text-2xl">Photography :)</p>
|
||||||
|
<p class="text-left">Chuck me an email if you'd like a print of these, I'll see what I can do</p> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
{
|
<Carousel/>
|
||||||
photos.map(photo => (
|
|
||||||
<div class="max-w-md overflow-hidden md:max-w-2xl md:my-2">
|
|
||||||
<div class="md:flex">
|
|
||||||
<div class="md:shrink-0">
|
|
||||||
<img class="h-full w-full object-cover md:h-full md:w-96" src={ pb.files.getURL(photo, photo.image, {'thumb': '1080x0'}) } alt={photo.alt}>
|
|
||||||
</div>
|
|
||||||
<div class="md:pl-4 md:mt-2 mb-8 mt-3">
|
|
||||||
<div class="bold text-xl">{photo.title === "" ? "Untitled" : photo.title}</div>
|
|
||||||
|
|
||||||
<div class="pt-2">
|
|
||||||
<p>📌 {photo.location}</p>
|
|
||||||
<p>📷 {photo.camera}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</Base>
|
</Base>
|
||||||
Reference in New Issue
Block a user