Initial commit - WhyRating Engine (Google Reviews Scraper)
This commit is contained in:
117
web/contexts/ReviewIQFilterContext.tsx
Normal file
117
web/contexts/ReviewIQFilterContext.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
'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;
|
||||
}
|
||||
Reference in New Issue
Block a user