92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { FilterData } from '@/types';
|
|
import { cities, companies, countries, industries, states } from '@/types/data';
|
|
import createContextHook from '@nkzw/create-context-hook';
|
|
import { useEffect, useMemo, useState } from 'react';
|
|
|
|
export const [FilterProvider, useFilter] = createContextHook(() => {
|
|
const [filterData, setFilterDataState] = useState<FilterData>({
|
|
country: { name: '', iso: 'all' },
|
|
state: { name: '', iso: 'all' },
|
|
city: { name: '', iso: 'all' },
|
|
industries: [],
|
|
});
|
|
|
|
const [step, setStep] = useState<'filter' | 'items'>('filter');
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const itemsPerPage = 10;
|
|
|
|
const setFilterData = (updates: Partial<FilterData>) => {
|
|
setFilterDataState((prev) => ({ ...prev, ...updates }));
|
|
};
|
|
|
|
const availableStates = useMemo(() => {
|
|
if (filterData.country.iso === 'all' || !filterData.country.iso) {
|
|
return states;
|
|
}
|
|
return states.filter((s) => s.country_iso === filterData.country.iso);
|
|
}, [filterData.country.iso]);
|
|
|
|
const availableCities = useMemo(() => {
|
|
if (filterData.state.iso === 'all' || !filterData.state.iso) {
|
|
return cities;
|
|
}
|
|
return cities.filter((c) => c.state_iso === filterData.state.iso);
|
|
}, [filterData.state.iso]);
|
|
|
|
const filteredCompanies = useMemo(() => {
|
|
return companies.filter((company) => {
|
|
const countryMatch =
|
|
!filterData.country.iso ||
|
|
filterData.country.iso === 'all' ||
|
|
company.country === filterData.country.iso;
|
|
const industryMatch =
|
|
filterData.industries.length === 0 ||
|
|
(company.industry && filterData.industries.includes(company.industry));
|
|
return countryMatch && industryMatch;
|
|
});
|
|
}, [filterData]);
|
|
|
|
const totalItems = filteredCompanies.length;
|
|
const totalPages = Math.ceil(totalItems / itemsPerPage);
|
|
|
|
const paginatedData = useMemo(() => {
|
|
const startIndex = (currentPage - 1) * itemsPerPage;
|
|
const endIndex = startIndex + itemsPerPage;
|
|
return filteredCompanies.slice(startIndex, endIndex);
|
|
}, [filteredCompanies, currentPage]);
|
|
|
|
useEffect(() => {
|
|
if (filterData.country.iso !== 'all') {
|
|
const hasState = availableStates.some((s) => s.iso === filterData.state.iso);
|
|
if (!hasState) {
|
|
setFilterData({ state: { name: '', iso: 'all' }, city: { name: '', iso: 'all' } });
|
|
}
|
|
}
|
|
}, [filterData.country.iso, availableStates]);
|
|
|
|
useEffect(() => {
|
|
if (filterData.state.iso !== 'all') {
|
|
const hasCity = availableCities.some((c) => c.iso === filterData.city.iso);
|
|
if (!hasCity) {
|
|
setFilterData({ city: { name: '', iso: 'all' } });
|
|
}
|
|
}
|
|
}, [filterData.state.iso, availableCities]);
|
|
|
|
return {
|
|
filterData,
|
|
setFilterData,
|
|
countries,
|
|
states: availableStates,
|
|
cities: availableCities,
|
|
industries,
|
|
totalItems,
|
|
step,
|
|
setStep,
|
|
allData: paginatedData,
|
|
currentPage,
|
|
setCurrentPage,
|
|
totalPages,
|
|
};
|
|
});
|