finished the upgrade to filament 4. completely revamped the frontend with codex, now it looks great!

This commit is contained in:
2025-11-13 17:42:43 +01:00
parent f59fda588b
commit b311188bc1
138 changed files with 5440 additions and 4105 deletions

View File

@@ -1,15 +1,41 @@
<template>
<div class="gallery-grid">
<div class="grid">
<div
class="grid-item"
v-for="(image) in images"
:key="image.name"
<div class="space-y-4">
<p
v-if="!images.length"
class="rounded-3xl border border-dashed border-white/20 bg-white/5 px-4 py-10 text-center text-sm text-slate-300"
>
{{ props.translations.empty_gallery || 'Noch keine Bilder vorhanden.' }}
</p>
<div
v-else
class="grid grid-cols-2 gap-4 sm:grid-cols-3 sm:gap-6 xl:grid-cols-4 2xl:grid-cols-5"
>
<button
v-for="image in images"
:key="image.id ?? image.name"
type="button"
class="group relative aspect-[3/4] overflow-hidden rounded-[1.75rem] border border-white/10 bg-slate-900/30 shadow-2xl ring-1 ring-white/5 transition-all hover:border-emerald-300 focus:outline-none focus-visible:ring-4 focus-visible:ring-emerald-400"
@click="$emit('imageTapped', image, $event)"
:aria-label="fallbackLabel(image)"
>
<img :src="image.path" :alt="'Image ' + image.name" />
<div v-if="image.is_new" class="new-badge">{{ __('new') }}</div>
</div>
<img
:src="image.path"
:alt="fallbackLabel(image)"
loading="lazy"
class="h-full w-full object-cover transition duration-700 group-hover:scale-105"
/>
<span
v-if="image.is_new"
class="absolute left-4 top-4 inline-flex items-center gap-2 rounded-full bg-emerald-300/90 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-emerald-900 shadow-lg"
>
<span class="h-1.5 w-1.5 rounded-full bg-emerald-800"></span>
{{ __('new') }}
</span>
<div class="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-slate-950/70 via-slate-950/10 to-transparent p-4 text-left">
<p class="text-base font-semibold text-white drop-shadow">{{ fallbackLabel(image) }}</p>
<p class="text-xs uppercase tracking-[0.3em] text-white/70">Tap to open</p>
</div>
</button>
</div>
</div>
</template>
@@ -33,50 +59,6 @@ const emits = defineEmits(['imageTapped']);
const __ = (key) => {
return props.translations[key] || key;
};
const fallbackLabel = (image) => image?.name || props.translations.image || 'Bild';
</script>
<style scoped>
.gallery-grid {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 20px;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 Spalten */
gap: 20px; /* Zwischenabstand */
width: 100%;
max-width: 1200px; /* Beispiel: Maximale Breite des Rasters */
}
.grid-item {
cursor: pointer;
overflow: hidden;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
position: relative; /* Added for badge positioning */
}
.grid-item img {
width: 100%;
height: 200px; /* Feste Höhe für die Bilder im Raster */
object-fit: cover; /* Bilder zuschneiden, um den Bereich zu füllen */
display: block;
}
.new-badge {
position: absolute;
top: 10px;
right: 10px;
background-color: red;
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 0.8em;
font-weight: bold;
z-index: 10;
}
</style>