|
1 | 1 | --- |
2 | 2 | // Generic Carousel component for displaying content - both featured and suggested |
3 | 3 | import { getCollection } from 'astro:content' |
4 | | -import type { CollectionEntry } from 'astro:content' |
5 | | -import type { CarouselProps, CollectionKeyMap } from './props' |
| 4 | +import { |
| 5 | + type CollectionSlug, |
| 6 | + type CarouselVariant, |
| 7 | + type ItemType, |
| 8 | + collectionMap, |
| 9 | +} from './@types' |
| 10 | +import { prepareItems } from './server' |
6 | 11 |
|
7 | | -export type { CarouselProps as Props } from './props' |
| 12 | +export interface Props { |
| 13 | + title?: string |
| 14 | + limit?: number |
| 15 | + variant?: CarouselVariant |
| 16 | + currentSlug: string |
| 17 | + type: CollectionSlug |
| 18 | +} |
8 | 19 |
|
9 | 20 | const { |
10 | 21 | title = 'Featured Content', |
11 | 22 | limit = 3, |
12 | 23 | variant = 'featured', |
13 | 24 | currentSlug, |
14 | 25 | type, |
15 | | -} = Astro.props as CarouselProps |
16 | | -
|
17 | | -// Map the prop type to the actual collection key with proper typing |
18 | | -const collectionKey = { |
19 | | - services: 'services', |
20 | | - 'case-studies': 'caseStudies', |
21 | | - articles: 'articles', |
22 | | -}[type] as CollectionKeyMap[typeof type] |
23 | | -
|
24 | | -// Get all content from the specified collection with proper typing |
25 | | -const allItems = await getCollection(collectionKey) |
26 | | -type ItemType = CollectionEntry<CollectionKeyMap[typeof type]> |
27 | | -
|
28 | | -// Filter and sort items based on variant |
29 | | -let items: ItemType[] = allItems |
30 | | -
|
31 | | -switch (variant) { |
32 | | - case 'featured': |
33 | | - // Show only featured items, excluding current item |
34 | | - items = allItems |
35 | | - .filter((item: ItemType) => { |
36 | | - if (item.id === currentSlug) return false |
37 | | - // All collection types now use the consistent "featured" field |
38 | | - return item.data.featured === true |
39 | | - }) |
40 | | - .sort( |
41 | | - (a: ItemType, b: ItemType) => |
42 | | - new Date(b.data.publishDate).getTime() - new Date(a.data.publishDate).getTime() |
43 | | - ) |
44 | | - break |
| 26 | +} = Astro.props |
45 | 27 |
|
46 | | - case 'suggested': |
47 | | - // Filter out current item and get latest items (suggested mode) |
48 | | - items = allItems |
49 | | - .filter((item: ItemType) => item.id !== currentSlug) |
50 | | - .sort( |
51 | | - (a: ItemType, b: ItemType) => |
52 | | - new Date(b.data.publishDate).getTime() - new Date(a.data.publishDate).getTime() |
53 | | - ) |
54 | | - break |
55 | | -
|
56 | | - case 'random': |
57 | | - // Show all items excluding current one in random order |
58 | | - items = allItems |
59 | | - .filter((item: ItemType) => item.id !== currentSlug) |
60 | | - .sort(() => Math.random() - 0.5) |
61 | | - break |
62 | | -} |
63 | | -
|
64 | | -// Apply limit |
65 | | -if (limit) { |
66 | | - items = items.slice(0, limit) |
67 | | -} |
| 28 | +const allItems = await getCollection(collectionMap[type]) |
| 29 | +const items = prepareItems(allItems, variant, currentSlug, limit) |
68 | 30 | --- |
69 | 31 |
|
70 | 32 | { |
|
0 commit comments