-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseSliceData.ts
More file actions
79 lines (68 loc) · 2.16 KB
/
Copy pathuseSliceData.ts
File metadata and controls
79 lines (68 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* Shared Hook for Slice Data Management
* Eliminates repeated data extraction patterns across all collection slices
* Bismillah - Created for DRY compliance while preserving Prismic integration
*/
import { useState, useEffect, useMemo } from 'react';
interface UseSliceDataConfig<T> {
slice: any;
extractItems: (slice: any) => T[];
getFilterCategories?: (items: T[]) => string[];
defaultFilter?: string;
}
interface UseSliceDataReturn<T> {
items: T[];
filteredItems: T[];
categories: string[];
activeFilter: string;
setActiveFilter: (filter: string) => void;
isLoading: boolean;
isEmpty: boolean;
hasFilters: boolean;
}
export function useSliceData<T>({
slice,
extractItems,
getFilterCategories,
defaultFilter = 'all'
}: UseSliceDataConfig<T>): UseSliceDataReturn<T> {
const [isLoading, setIsLoading] = useState(true);
const [activeFilter, setActiveFilter] = useState(defaultFilter);
// Extract items from slice
const items = useMemo(() => {
if (!slice?.items) return [];
return extractItems(slice);
}, [slice, extractItems]);
// Extract filter categories
const categories = useMemo(() => {
if (!getFilterCategories || !items.length) return [];
return ['all', ...getFilterCategories(items)];
}, [items, getFilterCategories]);
// Filter items based on active filter
const filteredItems = useMemo(() => {
if (!items.length || activeFilter === 'all') return items;
if (!getFilterCategories) return items;
return items.filter((item: any) => {
// This will be customized per slice type
if (item.technology) return item.technology === activeFilter;
if (item.category) return item.category === activeFilter;
if (item.type) return item.type === activeFilter;
return true;
});
}, [items, activeFilter, getFilterCategories]);
// Simulate loading state
useEffect(() => {
const timer = setTimeout(() => setIsLoading(false), 500);
return () => clearTimeout(timer);
}, []);
return {
items,
filteredItems,
categories,
activeFilter,
setActiveFilter,
isLoading,
isEmpty: filteredItems.length === 0,
hasFilters: categories.length > 1,
};
}