You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.6 KiB
136 lines
4.6 KiB
<script setup lang="ts">
|
|
/**
|
|
* Educator Products Listing Page
|
|
*
|
|
* Displays educator annual passes using ProductCard and ProductGrid components.
|
|
* Fetches only educator category products from the database via API.
|
|
*/
|
|
|
|
// Page metadata
|
|
definePageMeta({
|
|
layout: 'default',
|
|
})
|
|
|
|
// Type definition for product
|
|
interface Product {
|
|
id: string
|
|
navProductId: string
|
|
name: string
|
|
description: string
|
|
price: string
|
|
stockQuantity: number
|
|
category: string
|
|
active: boolean
|
|
createdAt: Date
|
|
updatedAt: Date
|
|
}
|
|
|
|
// Fetch products from API - only educator passes
|
|
const { data: products, error, pending } = await useFetch<Product[]>('/api/products', {
|
|
key: 'educator-products', // Explicit key for role-based refresh
|
|
query: {
|
|
category: 'educator-annual-pass',
|
|
},
|
|
})
|
|
|
|
// Map product categories to badges
|
|
const getBadge = (category: string): string | undefined => {
|
|
const badges: Record<string, string> = {
|
|
'educator-annual-pass': 'Für Pädagogen',
|
|
}
|
|
return badges[category]
|
|
}
|
|
|
|
// Map product categories to discount percentages (for demo)
|
|
const getDiscount = (category: string): number | undefined => {
|
|
const discounts: Record<string, number> = {
|
|
// No discounts for now
|
|
}
|
|
return discounts[category]
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<NuxtLayout name="default">
|
|
<div class="min-h-screen px-4 py-12 md:px-6 lg:px-8">
|
|
<!-- Page Header -->
|
|
<div class="mx-auto mb-12 max-w-container-wide text-center">
|
|
<h1 class="mb-4 text-4xl font-bold text-white md:text-5xl">
|
|
Pädagogische Jahreskarten
|
|
</h1>
|
|
<p class="mx-auto max-w-2xl text-lg text-white/80">
|
|
Spezielle Jahreskarten für Pädagogen und Lehrkräfte.
|
|
Nutze die experimenta für deine Bildungsarbeit und profitiere von vergünstigten Konditionen.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Loading State -->
|
|
<div v-if="pending" class="mx-auto max-w-container-wide text-center">
|
|
<div class="card-glass inline-block">
|
|
<p class="text-white/80">Produkte werden geladen...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Error State -->
|
|
<div v-else-if="error" class="mx-auto max-w-container-wide">
|
|
<div class="card-glass border-red/50 bg-red/10">
|
|
<h2 class="mb-2 text-xl font-semibold text-red">
|
|
Fehler beim Laden der Produkte
|
|
</h2>
|
|
<p class="text-white/80">
|
|
{{ error.message || 'Ein unbekannter Fehler ist aufgetreten.' }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Products Grid -->
|
|
<div v-else-if="products && products.length > 0" class="mx-auto max-w-container-wide">
|
|
<ProductGrid :columns="3">
|
|
<ProductCard v-for="product in products" :key="product.id" image="/img/makerspace-jk-2025.jpg"
|
|
:title="product.name" :description="product.description" :price="Number(product.price)"
|
|
:badge="getBadge(product.category)" :discount-percentage="getDiscount(product.category)"
|
|
:product-id="product.id" />
|
|
</ProductGrid>
|
|
</div>
|
|
|
|
<!-- Empty State -->
|
|
<div v-else class="mx-auto max-w-container-wide text-center">
|
|
<div class="card-glass">
|
|
<h2 class="mb-2 text-xl font-semibold text-white">
|
|
Keine Produkte verfügbar
|
|
</h2>
|
|
<p class="text-white/80">
|
|
Aktuell sind keine Pädagogen-Jahreskarten verfügbar. Bitte schaue später noch einmal vorbei.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Info Card -->
|
|
<div class="mx-auto mt-12 max-w-container-wide">
|
|
<div class="card-info card-accent-border">
|
|
<h2 class="mb-3 text-xl font-semibold text-experimenta-accent">
|
|
Warum eine Pädagogen-Jahreskarte?
|
|
</h2>
|
|
<ul class="space-y-2 text-white/90">
|
|
<li class="flex items-start gap-2">
|
|
<span class="mt-1 text-experimenta-accent">✓</span>
|
|
<span>Speziell für Lehrkräfte und Pädagogen entwickelt</span>
|
|
</li>
|
|
<li class="flex items-start gap-2">
|
|
<span class="mt-1 text-experimenta-accent">✓</span>
|
|
<span>Vergünstigte Konditionen für Bildungseinrichtungen</span>
|
|
</li>
|
|
<li class="flex items-start gap-2">
|
|
<span class="mt-1 text-experimenta-accent">✓</span>
|
|
<span>Ideal für Schulausflüge und Projektwochen</span>
|
|
</li>
|
|
<li class="flex items-start gap-2">
|
|
<span class="mt-1 text-experimenta-accent">✓</span>
|
|
<span>Flexible Nutzung für deine Bildungsarbeit</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</NuxtLayout>
|
|
</template>
|
|
|