2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2023-11-26 02:24:16 +03:00
|
|
|
import { useCallback, useLayoutEffect, useState } from 'react';
|
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
import { ConceptLoader } from '@/components/Common/ConceptLoader';
|
|
|
|
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';
|
2023-12-13 14:32:57 +03:00
|
|
|
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';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2023-11-26 02:24:16 +03:00
|
|
|
import SearchPanel from './SearchPanel';
|
|
|
|
import ViewLibrary from './ViewLibrary';
|
|
|
|
|
|
|
|
function LibraryPage() {
|
2023-12-13 14:32:57 +03:00
|
|
|
const router = useConceptNavigation();
|
|
|
|
const urlParams = useQueryStrings();
|
|
|
|
const searchFilter = (urlParams.get('filter') || null) as LibraryFilterStrategy | null;
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
const { user } = useAuth();
|
|
|
|
|
2023-11-26 02:24:16 +03:00
|
|
|
const library = useLibrary();
|
|
|
|
const { setShowScroll } = useConceptTheme();
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2023-12-05 01:22:44 +03:00
|
|
|
const [filter, setFilter] = useState<ILibraryFilter>({});
|
|
|
|
const [items, setItems] = useState<ILibraryItem[]>([]);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
|
|
|
const [query, setQuery] = useState('');
|
2023-12-28 14:04:44 +03:00
|
|
|
const [strategy, setStrategy] = useLocalStorage<LibraryFilterStrategy>(
|
|
|
|
'search_strategy',
|
|
|
|
LibraryFilterStrategy.MANUAL
|
|
|
|
);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
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;
|
2023-12-13 14:32:57 +03:00
|
|
|
setQuery('');
|
|
|
|
setStrategy(inputStrategy);
|
|
|
|
setFilter(ApplyStrategy(inputStrategy));
|
|
|
|
}, [user, router, setQuery, setFilter, setStrategy, strategy, searchFilter]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
setShowScroll(true);
|
|
|
|
return () => setShowScroll(false);
|
|
|
|
}, [setShowScroll]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
setItems(library.applyFilter(filter));
|
|
|
|
}, [library, filter, filter.query]);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
const resetQuery = useCallback(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
setQuery('');
|
|
|
|
setFilter({});
|
2023-12-28 14:04:44 +03:00
|
|
|
}, []);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
|
|
|
return (
|
2023-12-05 01:22:44 +03:00
|
|
|
<>
|
2023-12-28 14:04:44 +03:00
|
|
|
{library.loading ? <ConceptLoader /> : null}
|
|
|
|
{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}
|
|
|
|
</>
|
|
|
|
);
|
2023-11-26 02:24:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
export default LibraryPage;
|
2023-12-13 14:32:57 +03:00
|
|
|
|
|
|
|
// ====== Internals =======
|
|
|
|
function ApplyStrategy(strategy: LibraryFilterStrategy): ILibraryFilter {
|
2023-12-28 14:04:44 +03:00
|
|
|
// prettier-ignore
|
2023-12-13 14:32:57 +03:00
|
|
|
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-13 14:32:57 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
}
|