ConceptPortal-public/rsconcept/frontend/src/pages/LibraryPage/LibraryPage.tsx

101 lines
3.2 KiB
TypeScript
Raw Normal View History

'use client';
import { useCallback, useLayoutEffect, useState } from 'react';
import { Loader } from '@/components/Common/Loader';
import InfoError from '@/components/InfoError';
import { useAuth } from '@/context/AuthContext';
import { useLibrary } from '@/context/LibraryContext';
2023-12-26 14:23:51 +03:00
import { useConceptNavigation } from '@/context/NavigationContext';
import { useConceptTheme } from '@/context/ThemeContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useQueryStrings from '@/hooks/useQueryStrings';
import { ILibraryItem } from '@/models/library';
2023-12-26 14:23:51 +03:00
import { ILibraryFilter, LibraryFilterStrategy } from '@/models/miscellaneous';
import SearchPanel from './SearchPanel';
import ViewLibrary from './ViewLibrary';
function LibraryPage() {
const router = useConceptNavigation();
const urlParams = useQueryStrings();
const searchFilter = (urlParams.get('filter') || null) as LibraryFilterStrategy | null;
2023-12-28 14:04:44 +03:00
const { user } = useAuth();
const library = useLibrary();
const { setShowScroll } = useConceptTheme();
2023-12-28 14:04:44 +03:00
const [filter, setFilter] = useState<ILibraryFilter>({});
const [items, setItems] = useState<ILibraryItem[]>([]);
const [query, setQuery] = useState('');
2023-12-28 14:04:44 +03:00
const [strategy, setStrategy] = useLocalStorage<LibraryFilterStrategy>(
'search_strategy',
LibraryFilterStrategy.MANUAL
);
useLayoutEffect(() => {
if (searchFilter === null) {
router.replace(`/library?filter=${strategy}`);
return;
}
2023-12-28 14:04:44 +03:00
const inputStrategy =
searchFilter && Object.values(LibraryFilterStrategy).includes(searchFilter)
? searchFilter
: LibraryFilterStrategy.MANUAL;
setQuery('');
setStrategy(inputStrategy);
setFilter(ApplyStrategy(inputStrategy));
}, [user, router, setQuery, setFilter, setStrategy, strategy, searchFilter]);
2023-12-28 14:04:44 +03:00
useLayoutEffect(() => {
setShowScroll(true);
return () => setShowScroll(false);
}, [setShowScroll]);
2023-12-28 14:04:44 +03:00
useLayoutEffect(() => {
setItems(library.applyFilter(filter));
}, [library, filter, filter.query]);
2023-12-28 14:04:44 +03:00
const resetQuery = useCallback(() => {
setQuery('');
setFilter({});
2023-12-28 14:04:44 +03:00
}, []);
return (
<>
{library.loading ? <Loader /> : null}
2023-12-28 14:04:44 +03:00
{library.error ? <InfoError error={library.error} /> : null}
{!library.loading && library.items ? (
<>
<SearchPanel
query={query}
setQuery={setQuery}
strategy={strategy}
total={library.items.length ?? 0}
filtered={items.length}
setFilter={setFilter}
/>
<ViewLibrary resetQuery={resetQuery} items={items} />
</>
) : null}
</>
);
}
export default LibraryPage;
// ====== Internals =======
function ApplyStrategy(strategy: LibraryFilterStrategy): ILibraryFilter {
2023-12-28 14:04:44 +03:00
// prettier-ignore
switch (strategy) {
2023-12-28 14:04:44 +03:00
case LibraryFilterStrategy.MANUAL: return {};
case LibraryFilterStrategy.COMMON: return { is_common: true };
case LibraryFilterStrategy.CANONICAL: return { is_canonical: true };
case LibraryFilterStrategy.PERSONAL: return { is_personal: true };
case LibraryFilterStrategy.SUBSCRIBE: return { is_subscribed: true };
case LibraryFilterStrategy.OWNED: return { is_owned: true };
}
2023-12-28 14:04:44 +03:00
}