118 lines
2.8 KiB
TypeScript
118 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import React, { createContext, useContext, useState, useMemo, useCallback } from 'react';
|
|
import type {
|
|
ReviewIQFilters,
|
|
ReviewIQFilterContextValue,
|
|
TimeRange,
|
|
Sentiment,
|
|
URTDomain,
|
|
Intensity,
|
|
} from '@/components/reviewiq/types';
|
|
|
|
const defaultFilters: ReviewIQFilters = {
|
|
timeRange: 'all',
|
|
sentiment: [],
|
|
urtDomain: null,
|
|
intensity: [],
|
|
brushRange: null,
|
|
};
|
|
|
|
const ReviewIQFilterContext = createContext<ReviewIQFilterContextValue | null>(null);
|
|
|
|
export function ReviewIQFilterProvider({ children }: { children: React.ReactNode }) {
|
|
const [filters, setFilters] = useState<ReviewIQFilters>(defaultFilters);
|
|
|
|
const toggleSentiment = useCallback((s: Sentiment) => {
|
|
setFilters((prev) => ({
|
|
...prev,
|
|
sentiment: prev.sentiment.includes(s)
|
|
? prev.sentiment.filter((x) => x !== s)
|
|
: [...prev.sentiment, s],
|
|
}));
|
|
}, []);
|
|
|
|
const setURTDomain = useCallback((domain: URTDomain | null) => {
|
|
setFilters((prev) => ({
|
|
...prev,
|
|
urtDomain: prev.urtDomain === domain ? null : domain,
|
|
}));
|
|
}, []);
|
|
|
|
const toggleIntensity = useCallback((i: Intensity) => {
|
|
setFilters((prev) => ({
|
|
...prev,
|
|
intensity: prev.intensity.includes(i)
|
|
? prev.intensity.filter((x) => x !== i)
|
|
: [...prev.intensity, i],
|
|
}));
|
|
}, []);
|
|
|
|
const setTimeRange = useCallback((range: TimeRange) => {
|
|
setFilters((prev) => ({
|
|
...prev,
|
|
timeRange: range,
|
|
brushRange: null, // Clear brush when time range changes
|
|
}));
|
|
}, []);
|
|
|
|
const setBrushRange = useCallback((range: { start: string; end: string } | null) => {
|
|
setFilters((prev) => ({
|
|
...prev,
|
|
brushRange: range,
|
|
}));
|
|
}, []);
|
|
|
|
const clearFilters = useCallback(() => {
|
|
setFilters(defaultFilters);
|
|
}, []);
|
|
|
|
const hasActiveFilters = useMemo(() => {
|
|
return (
|
|
filters.timeRange !== 'all' ||
|
|
filters.sentiment.length > 0 ||
|
|
filters.urtDomain !== null ||
|
|
filters.intensity.length > 0 ||
|
|
filters.brushRange !== null
|
|
);
|
|
}, [filters]);
|
|
|
|
const value = useMemo<ReviewIQFilterContextValue>(
|
|
() => ({
|
|
filters,
|
|
setFilters,
|
|
toggleSentiment,
|
|
setURTDomain,
|
|
toggleIntensity,
|
|
setTimeRange,
|
|
setBrushRange,
|
|
clearFilters,
|
|
hasActiveFilters,
|
|
}),
|
|
[
|
|
filters,
|
|
toggleSentiment,
|
|
setURTDomain,
|
|
toggleIntensity,
|
|
setTimeRange,
|
|
setBrushRange,
|
|
clearFilters,
|
|
hasActiveFilters,
|
|
]
|
|
);
|
|
|
|
return (
|
|
<ReviewIQFilterContext.Provider value={value}>
|
|
{children}
|
|
</ReviewIQFilterContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useReviewIQFilters(): ReviewIQFilterContextValue {
|
|
const context = useContext(ReviewIQFilterContext);
|
|
if (!context) {
|
|
throw new Error('useReviewIQFilters must be used within ReviewIQFilterProvider');
|
|
}
|
|
return context;
|
|
}
|