485 lines
15 KiB
TypeScript
485 lines
15 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import {
|
|
BlogCard,
|
|
ProductCard,
|
|
CategoryCard,
|
|
CardGrid,
|
|
CardGrid2,
|
|
CardGrid3,
|
|
CardGrid4,
|
|
CardGridAuto
|
|
} from './index';
|
|
import { Container, Button } from '@/components/ui';
|
|
import { Post, Product, ProductCategory } from '@/lib/data';
|
|
|
|
/**
|
|
* CardsExample - Comprehensive example showing all card variations
|
|
* This component demonstrates how to use the card components with real data
|
|
*/
|
|
|
|
// Mock data for demonstration
|
|
const mockPosts: Post[] = [
|
|
{
|
|
id: 1,
|
|
translationKey: 'post-1',
|
|
locale: 'de',
|
|
slug: 'weltweite-lieferketten',
|
|
path: '/de/blog/weltweite-lieferketten',
|
|
title: 'Weltweite Lieferketten: Herausforderungen und Lösungen',
|
|
titleHtml: '<strong>Weltweite Lieferketten</strong>: Herausforderungen und Lösungen',
|
|
contentHtml: '<p>Die globalen Lieferketten stehen vor unprecedented Herausforderungen...</p>',
|
|
excerptHtml: 'Erfahren Sie mehr über die aktuellen Herausforderungen in globalen Lieferketten und wie wir Lösungen entwickeln.',
|
|
featuredImage: 10988,
|
|
datePublished: '2024-12-15',
|
|
updatedAt: '2024-12-15',
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 2,
|
|
translationKey: 'post-2',
|
|
locale: 'de',
|
|
slug: 'nachhaltige-energie',
|
|
path: '/de/blog/nachhaltige-energie',
|
|
title: 'Nachhaltige Energie: Die Zukunft der Stromversorgung',
|
|
titleHtml: '<strong>Nachhaltige Energie</strong>: Die Zukunft der Stromversorgung',
|
|
contentHtml: '<p>Die Energiewende erfordert innovative Kabel- und Leitungslösungen...</p>',
|
|
excerptHtml: 'Entdecken Sie, wie moderne Kabeltechnologie zur Energiewende beiträgt.',
|
|
featuredImage: 20928,
|
|
datePublished: '2024-12-10',
|
|
updatedAt: '2024-12-10',
|
|
translation: null,
|
|
},
|
|
];
|
|
|
|
const mockProducts: Product[] = [
|
|
{
|
|
id: 1,
|
|
translationKey: 'product-1',
|
|
locale: 'de',
|
|
slug: 'n2xsfl2y-12-20kv',
|
|
path: '/de/produkte/n2xsfl2y-12-20kv',
|
|
name: 'N2XSFL2Y 12/20kV',
|
|
shortDescriptionHtml: 'Mittelspannungskabel mit LSA-Plus Verbindungssystem',
|
|
descriptionHtml: '<p>Das N2XSFL2Y Kabel ist für den Einsatz in Mittelspannungsnetzen optimiert...</p>',
|
|
images: [
|
|
'/media/media-1766870855811-N2XSFL2Y-3-scaled.webp',
|
|
'/media/media-1766870855815-N2XSFL2Y-2-scaled.webp',
|
|
],
|
|
featuredImage: '/media/media-1766870855811-N2XSFL2Y-3-scaled.webp',
|
|
sku: 'N2XSFL2Y-12-20KV',
|
|
regularPrice: '125.50',
|
|
salePrice: '',
|
|
currency: 'EUR',
|
|
stockStatus: 'instock',
|
|
categories: [{ id: 1, name: 'Mittelspannung', slug: 'mittelspannung' }],
|
|
attributes: [],
|
|
variations: [],
|
|
updatedAt: '2024-12-20',
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 2,
|
|
translationKey: 'product-2',
|
|
locale: 'de',
|
|
slug: 'na2xsf2x-0-6-1kv',
|
|
path: '/de/produkte/na2xsf2x-0-6-1kv',
|
|
name: 'NA2XSF2X 0,6/1kV',
|
|
shortDescriptionHtml: 'Niederspannungskabel für industrielle Anwendungen',
|
|
descriptionHtml: '<p>Robustes Niederspannungskabel für den industriellen Einsatz...</p>',
|
|
images: [
|
|
'/media/47052-NA2XSF2X_3x1x300_RM-25_12-20kV-3.webp',
|
|
],
|
|
featuredImage: '/media/47052-NA2XSF2X_3x1x300_RM-25_12-20kV-3.webp',
|
|
sku: 'NA2XSF2X-0-6-1KV',
|
|
regularPrice: '45.00',
|
|
salePrice: '38.50',
|
|
currency: 'EUR',
|
|
stockStatus: 'instock',
|
|
categories: [{ id: 2, name: 'Niederspannung', slug: 'niederspannung' }],
|
|
attributes: [],
|
|
variations: [],
|
|
updatedAt: '2024-12-18',
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 3,
|
|
translationKey: 'product-3',
|
|
locale: 'de',
|
|
slug: 'h1z2z2-k',
|
|
path: '/de/produkte/h1z2z2-k',
|
|
name: 'H1Z2Z2-K',
|
|
shortDescriptionHtml: 'Solarleiterkabel für Photovoltaikanlagen',
|
|
descriptionHtml: '<p>Spezielles Solarleiterkabel für den Einsatz in PV-Anlagen...</p>',
|
|
images: [
|
|
'/media/media-1766870855813-H1Z2Z2-K-scaled.webp',
|
|
],
|
|
featuredImage: '/media/media-1766870855813-H1Z2Z2-K-scaled.webp',
|
|
sku: 'H1Z2Z2-K',
|
|
regularPrice: '28.90',
|
|
salePrice: '',
|
|
currency: 'EUR',
|
|
stockStatus: 'onbackorder',
|
|
categories: [{ id: 3, name: 'Solar', slug: 'solar' }],
|
|
attributes: [],
|
|
variations: [],
|
|
updatedAt: '2024-12-22',
|
|
translation: null,
|
|
},
|
|
];
|
|
|
|
const mockCategories: ProductCategory[] = [
|
|
{
|
|
id: 1,
|
|
translationKey: 'cat-1',
|
|
locale: 'de',
|
|
slug: 'mittelspannung',
|
|
name: 'Mittelspannung',
|
|
path: '/de/produkt-kategorie/mittelspannung',
|
|
description: 'Kabel und Leitungen für Mittelspannungsnetze bis 36kV',
|
|
count: 12,
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 2,
|
|
translationKey: 'cat-2',
|
|
locale: 'de',
|
|
slug: 'niederspannung',
|
|
name: 'Niederspannung',
|
|
path: '/de/produkt-kategorie/niederspannung',
|
|
description: 'Kabel für Niederspannungsanwendungen bis 1kV',
|
|
count: 25,
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 3,
|
|
translationKey: 'cat-3',
|
|
locale: 'de',
|
|
slug: 'solar',
|
|
name: 'Solar',
|
|
path: '/de/produkt-kategorie/solar',
|
|
description: 'Spezielle Solarleiterkabel und Zubehör',
|
|
count: 8,
|
|
translation: null,
|
|
},
|
|
{
|
|
id: 4,
|
|
translationKey: 'cat-4',
|
|
locale: 'de',
|
|
slug: 'industrie',
|
|
name: 'Industrie',
|
|
path: '/de/produkt-kategorie/industrie',
|
|
description: 'Industrielle Kabel für anspruchsvolle Umgebungen',
|
|
count: 18,
|
|
translation: null,
|
|
},
|
|
];
|
|
|
|
export const CardsExample: React.FC = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
// Simulate loading
|
|
const simulateLoading = () => {
|
|
setLoading(true);
|
|
setTimeout(() => setLoading(false), 2000);
|
|
};
|
|
|
|
// Handle add to cart
|
|
const handleAddToCart = (product: Product) => {
|
|
console.log('Add to cart:', product.name);
|
|
alert(`"${product.name}" wurde zum Warenkorb hinzugefügt!`);
|
|
};
|
|
|
|
return (
|
|
<Container className="py-8 space-y-12">
|
|
{/* Header */}
|
|
<div className="text-center space-y-4">
|
|
<h1 className="text-4xl font-bold text-gray-900">
|
|
Card Components Showcase
|
|
</h1>
|
|
<p className="text-lg text-gray-600">
|
|
Comprehensive examples of all card variations for WordPress content
|
|
</p>
|
|
</div>
|
|
|
|
{/* Blog Cards Section */}
|
|
<section className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<h2 className="text-2xl font-bold text-gray-900">Blog Cards</h2>
|
|
<Button onClick={simulateLoading} variant="outline">
|
|
Simulate Loading
|
|
</Button>
|
|
</div>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Vertical Layout</h3>
|
|
<CardGrid2>
|
|
{mockPosts.map(post => (
|
|
<BlogCard
|
|
key={post.id}
|
|
post={post}
|
|
size="md"
|
|
showDate={true}
|
|
showCategories={true}
|
|
readMoreText="Weiterlesen"
|
|
/>
|
|
))}
|
|
</CardGrid2>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Horizontal Layout</h3>
|
|
<div className="space-y-4">
|
|
{mockPosts.map(post => (
|
|
<BlogCard
|
|
key={post.id}
|
|
post={post}
|
|
layout="horizontal"
|
|
size="md"
|
|
showDate={true}
|
|
showCategories={true}
|
|
readMoreText="Weiterlesen"
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Different Sizes</h3>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<BlogCard
|
|
post={mockPosts[0]}
|
|
size="sm"
|
|
showDate={true}
|
|
showCategories={true}
|
|
/>
|
|
<BlogCard
|
|
post={mockPosts[0]}
|
|
size="md"
|
|
showDate={true}
|
|
showCategories={true}
|
|
/>
|
|
<BlogCard
|
|
post={mockPosts[0]}
|
|
size="lg"
|
|
showDate={true}
|
|
showCategories={true}
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Product Cards Section */}
|
|
<section className="space-y-6">
|
|
<h2 className="text-2xl font-bold text-gray-900">Product Cards</h2>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Grid Layout</h3>
|
|
<CardGrid3>
|
|
{mockProducts.map(product => (
|
|
<ProductCard
|
|
key={product.id}
|
|
product={product}
|
|
size="md"
|
|
showPrice={true}
|
|
showStock={true}
|
|
showSku={true}
|
|
showCategories={true}
|
|
showAddToCart={true}
|
|
showViewDetails={false}
|
|
onAddToCart={handleAddToCart}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</CardGrid3>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Horizontal Layout</h3>
|
|
<div className="space-y-4">
|
|
{mockProducts.map(product => (
|
|
<ProductCard
|
|
key={product.id}
|
|
product={product}
|
|
layout="horizontal"
|
|
size="md"
|
|
showPrice={true}
|
|
showStock={true}
|
|
showSku={true}
|
|
showCategories={true}
|
|
showAddToCart={true}
|
|
onAddToCart={handleAddToCart}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Image Hover Swap</h3>
|
|
<CardGrid4>
|
|
{mockProducts.map(product => (
|
|
<ProductCard
|
|
key={product.id}
|
|
product={product}
|
|
size="sm"
|
|
showPrice={true}
|
|
showStock={true}
|
|
enableImageSwap={true}
|
|
onAddToCart={handleAddToCart}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</CardGrid4>
|
|
</section>
|
|
|
|
{/* Category Cards Section */}
|
|
<section className="space-y-6">
|
|
<h2 className="text-2xl font-bold text-gray-900">Category Cards</h2>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Standard Layout</h3>
|
|
<CardGrid4>
|
|
{mockCategories.map(category => (
|
|
<CategoryCard
|
|
key={category.id}
|
|
category={category}
|
|
size="md"
|
|
showCount={true}
|
|
showDescription={true}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</CardGrid4>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Icon-Based Layout</h3>
|
|
<CardGridAuto>
|
|
{mockCategories.map(category => (
|
|
<CategoryCard
|
|
key={category.id}
|
|
category={category}
|
|
size="sm"
|
|
useIcon={true}
|
|
showCount={true}
|
|
showDescription={false}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</CardGridAuto>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Horizontal Layout</h3>
|
|
<div className="space-y-3">
|
|
{mockCategories.map(category => (
|
|
<CategoryCard
|
|
key={category.id}
|
|
category={category}
|
|
layout="horizontal"
|
|
size="md"
|
|
showCount={true}
|
|
showDescription={true}
|
|
locale="de"
|
|
/>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Loading States Section */}
|
|
<section className="space-y-6">
|
|
<h2 className="text-2xl font-bold text-gray-900">Loading States</h2>
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">CardGrid Loading</h3>
|
|
{loading && (
|
|
<CardGrid3 loading={true} skeletonCount={6} />
|
|
)}
|
|
|
|
<h3 className="text-lg font-semibold text-gray-700">Empty States</h3>
|
|
<CardGrid3 items={[]} emptyMessage="Keine Produkte gefunden" />
|
|
</section>
|
|
|
|
{/* Mixed Content Section */}
|
|
<section className="space-y-6">
|
|
<h2 className="text-2xl font-bold text-gray-900">Mixed Content Grid</h2>
|
|
<CardGridAuto>
|
|
<BlogCard post={mockPosts[0]} size="sm" showDate={true} />
|
|
<ProductCard
|
|
product={mockProducts[0]}
|
|
size="sm"
|
|
showPrice={true}
|
|
showStock={false}
|
|
/>
|
|
<CategoryCard
|
|
category={mockCategories[0]}
|
|
size="sm"
|
|
useIcon={true}
|
|
showCount={false}
|
|
/>
|
|
<BlogCard post={mockPosts[1]} size="sm" showDate={true} />
|
|
<ProductCard
|
|
product={mockProducts[1]}
|
|
size="sm"
|
|
showPrice={true}
|
|
showStock={false}
|
|
/>
|
|
<CategoryCard
|
|
category={mockCategories[1]}
|
|
size="sm"
|
|
useIcon={true}
|
|
showCount={false}
|
|
/>
|
|
</CardGridAuto>
|
|
</section>
|
|
|
|
{/* Usage Examples */}
|
|
<section className="space-y-6 bg-gray-50 p-6 rounded-lg">
|
|
<h2 className="text-2xl font-bold text-gray-900">Usage Examples</h2>
|
|
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold">Basic Blog Card</h3>
|
|
<pre className="bg-gray-800 text-white p-4 rounded text-sm overflow-x-auto">
|
|
{`<BlogCard
|
|
post={post}
|
|
size="md"
|
|
layout="vertical"
|
|
showDate={true}
|
|
showCategories={true}
|
|
readMoreText="Weiterlesen"
|
|
/>`}</pre>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold">Product Card with Cart</h3>
|
|
<pre className="bg-gray-800 text-white p-4 rounded text-sm overflow-x-auto">
|
|
{`<ProductCard
|
|
product={product}
|
|
size="md"
|
|
showPrice={true}
|
|
showStock={true}
|
|
showAddToCart={true}
|
|
onAddToCart={(p) => console.log('Added:', p.name)}
|
|
/>`}</pre>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<h3 className="text-lg font-semibold">Category Card Grid</h3>
|
|
<pre className="bg-gray-800 text-white p-4 rounded text-sm overflow-x-auto">
|
|
{`<CardGrid4>
|
|
{categories.map(cat => (
|
|
<CategoryCard
|
|
key={cat.id}
|
|
category={cat}
|
|
size="md"
|
|
showCount={true}
|
|
/>
|
|
))}
|
|
</CardGrid4>`}</pre>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Best Practices */}
|
|
<section className="space-y-6 bg-blue-50 p-6 rounded-lg border border-blue-200">
|
|
<h2 className="text-2xl font-bold text-blue-900">Best Practices</h2>
|
|
<ul className="space-y-2 text-blue-800">
|
|
<li>✓ Use CardGrid components for consistent spacing and responsive layouts</li>
|
|
<li>✓ Always provide alt text for images</li>
|
|
<li>✓ Use appropriate sizes for different contexts (sm for lists, md for grids, lg for featured)</li>
|
|
<li>✓ Enable hover effects for better user experience</li>
|
|
<li>✓ Show loading states when fetching data</li>
|
|
<li>✓ Handle empty states gracefully</li>
|
|
<li>✓ Use the locale prop for internationalization</li>
|
|
<li>✓ Integrate with your data layer using the types from lib/data.ts</li>
|
|
</ul>
|
|
</section>
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
export default CardsExample; |