setGroupName(series.Name)}
>
diff --git a/src/components/Collection/ListViewItem.tsx b/src/components/Collection/ListViewItem.tsx
index c95cf0a9c..cc262e691 100644
--- a/src/components/Collection/ListViewItem.tsx
+++ b/src/components/Collection/ListViewItem.tsx
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react';
import { useDispatch } from 'react-redux';
-import { Link } from 'react-router-dom';
+import { Link, useNavigate } from 'react-router-dom';
import {
mdiAlertCircleOutline,
mdiCalendarMonthOutline,
@@ -17,11 +17,14 @@ import { reduce } from 'lodash';
import BackgroundImagePlaceholderDiv from '@/components/BackgroundImagePlaceholderDiv';
import { listItemSize } from '@/components/Collection/constants';
+import Button from '@/components/Input/Button';
import { useSeriesTagsQuery } from '@/core/react-query/series/queries';
import { useSettingsQuery } from '@/core/react-query/settings/queries';
+import { resetFilter, setFilterTag } from '@/core/slices/collection';
import { setGroupId } from '@/core/slices/modals/editGroup';
import { setSeriesId } from '@/core/slices/modals/editSeries';
import { dayjs, formatThousand } from '@/core/util';
+import { addFilterCriteriaToStore } from '@/core/utilities/filter';
import useEventCallback from '@/hooks/useEventCallback';
import useMainPoster from '@/hooks/useMainPoster';
@@ -45,17 +48,29 @@ const renderFileSources = (sources: SeriesSizesFileSourcesType): string => {
return output.join(' | ');
};
-const SeriesTag = ({ text, type }: { text: string, type: 'AniDB' | 'User' }) => (
-
-
- {text}
-
-);
+const SeriesTag = React.memo(({ text, type }: { text: string, type: 'User' | 'AniDB' }) => {
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
+ const handleClick = useEventCallback(() => {
+ dispatch(resetFilter());
+ dispatch(setFilterTag({ HasTag: [{ Name: text, isExcluded: false }] }));
+ addFilterCriteriaToStore('HasTag').catch(console.error);
+ navigate('/webui/collection');
+ });
+
+ return (
+
+ );
+});
type Props = {
item: CollectionGroupType | SeriesType;
@@ -152,21 +167,18 @@ const ListViewItem = ({ groupExtras, isSeries, isSidebarOpen, item }: Props) =>
{showGroupIndicator && groupCount > 1 && (
@@ -177,7 +189,15 @@ const ListViewItem = ({ groupExtras, isSeries, isSidebarOpen, item }: Props) =>
-
{item.Name}
+
+
+ {item.Name}
+
+
diff --git a/src/components/Collection/PosterViewItem.tsx b/src/components/Collection/PosterViewItem.tsx
index 756ec53d4..49ad227fa 100644
--- a/src/components/Collection/PosterViewItem.tsx
+++ b/src/components/Collection/PosterViewItem.tsx
@@ -6,6 +6,7 @@ import { Icon } from '@mdi/react';
import { reduce } from 'lodash';
import BackgroundImagePlaceholderDiv from '@/components/BackgroundImagePlaceholderDiv';
+import Button from '@/components/Input/Button';
import { useSettingsQuery } from '@/core/react-query/settings/queries';
import { setGroupId } from '@/core/slices/modals/editGroup';
import { setSeriesId } from '@/core/slices/modals/editSeries';
@@ -65,14 +66,14 @@ const PosterViewItem = ({ isSeries = false, item }: Props) => {
});
return (
-
-
+
+
@@ -84,16 +85,13 @@ const PosterViewItem = ({ isSeries = false, item }: Props) => {
)}
{showGroupIndicator && !isSeries && groupCount > 1 && (
@@ -102,20 +100,28 @@ const PosterViewItem = ({ isSeries = false, item }: Props) => {
)}
-
-
{item.Name}
- {showEpisodeCount && (
-
- {episodeCount}
- Episodes
-
- )}
-
+
+
+
+
+ {item.Name}
+
+
+ {showEpisodeCount && (
+
+ {episodeCount}
+ Episodes
+
+ )}
-
+
);
};
diff --git a/src/components/Collection/Series/EditSeriesModal.tsx b/src/components/Collection/Series/EditSeriesModal.tsx
index 850235af1..c88db98dc 100644
--- a/src/components/Collection/Series/EditSeriesModal.tsx
+++ b/src/components/Collection/Series/EditSeriesModal.tsx
@@ -69,7 +69,7 @@ const EditSeriesModal = () => {
className={cx(
activeTab === key
? 'w-[12rem] text-center bg-panel-menu-item-background p-3 rounded-lg text-panel-menu-item-text cursor-pointer'
- : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer',
+ : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer transition-colors',
)}
key={key}
onClick={() => setActiveTab(key)}
diff --git a/src/components/Collection/Series/EditSeriesTabs/Action.tsx b/src/components/Collection/Series/EditSeriesTabs/Action.tsx
index f7ea48827..94405afd5 100644
--- a/src/components/Collection/Series/EditSeriesTabs/Action.tsx
+++ b/src/components/Collection/Series/EditSeriesTabs/Action.tsx
@@ -6,7 +6,7 @@ const Action = (
) => (
{
{seriesData?.AniDB?.Titles.map(title => (
setName(title.Name)}
>
diff --git a/src/components/Collection/SeriesTopPanel.tsx b/src/components/Collection/SeriesTopPanel.tsx
index e98b37d55..52d4eff22 100644
--- a/src/components/Collection/SeriesTopPanel.tsx
+++ b/src/components/Collection/SeriesTopPanel.tsx
@@ -11,6 +11,7 @@ import BackgroundImagePlaceholderDiv from '@/components/BackgroundImagePlacehold
import CleanDescription from '@/components/Collection/CleanDescription';
import SeriesInfo from '@/components/Collection/SeriesInfo';
import SeriesUserStats from '@/components/Collection/SeriesUserStats';
+import Button from '@/components/Input/Button';
import ShokoPanel from '@/components/Panels/ShokoPanel';
import { useSeriesImagesQuery, useSeriesTagsQuery } from '@/core/react-query/series/queries';
import { useSettingsQuery } from '@/core/react-query/settings/queries';
@@ -33,7 +34,7 @@ const SeriesTag = React.memo(({ text, type }: { text: string, type: 'User' | 'An
});
return (
-
- {text}
-
+
{text}
+
);
});
diff --git a/src/components/Collection/TimelineSidebar.tsx b/src/components/Collection/TimelineSidebar.tsx
index 8a28cf168..e98cde0b3 100644
--- a/src/components/Collection/TimelineSidebar.tsx
+++ b/src/components/Collection/TimelineSidebar.tsx
@@ -1,9 +1,8 @@
import React from 'react';
import { Link } from 'react-router-dom';
-import { mdiLoading } from '@mdi/js';
-import { Icon } from '@mdi/react';
import BackgroundImagePlaceholderDiv from '@/components/BackgroundImagePlaceholderDiv';
+import ShokoPanel from '@/components/Panels/ShokoPanel';
import { SeriesTypeEnum } from '@/core/types/api/series';
import { dayjs } from '@/core/util';
import useMainPoster from '@/hooks/useMainPoster';
@@ -17,42 +16,44 @@ const TimelineItem = ({ series }: { series: SeriesType }) => {
: series.AniDB?.Type;
return (
-
-
+
+
-
-
- {dayjs(series.AniDB?.AirDate).year()}
- |
-
{seriesType}
-
-
{series.Name}
+
+
+
+ {dayjs(series.AniDB?.AirDate).year()}
+ |
+
{seriesType}
+
+
+
+ {series.Name}
+
-
+
);
};
const TimelineSidebar = ({ isFetching, series }: { isFetching: boolean, series: SeriesType[] }) => (
-
-
-
Timeline
- {isFetching
- ? (
-
-
-
- )
- : (
-
- {series.map(item => )}
-
- )}
-
-
+
+ {series.map(item => )}
+
);
export default TimelineSidebar;
diff --git a/src/components/Dashboard/DashboardSettingsModal.tsx b/src/components/Dashboard/DashboardSettingsModal.tsx
index 76dff5c7a..827ab5947 100644
--- a/src/components/Dashboard/DashboardSettingsModal.tsx
+++ b/src/components/Dashboard/DashboardSettingsModal.tsx
@@ -113,7 +113,7 @@ const DashboardSettingsModal = ({ onClose, show }: Props) => {
className={cx(
activeTab === 'widgets'
? 'w-[12rem] text-center bg-panel-menu-item-background p-3 rounded-lg text-panel-menu-item-text cursor-pointer'
- : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer',
+ : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer transition-colors',
)}
key="widgets"
onClick={() => setActiveTab('widgets')}
@@ -124,7 +124,7 @@ const DashboardSettingsModal = ({ onClose, show }: Props) => {
className={cx(
activeTab === 'options'
? 'w-[12rem] text-center bg-panel-menu-item-background p-3 rounded-lg text-panel-menu-item-text cursor-pointer'
- : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer',
+ : 'w-[12rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer transition-colors',
)}
key="options"
onClick={() => setActiveTab('options')}
diff --git a/src/components/Dialogs/ActionsModal.tsx b/src/components/Dialogs/ActionsModal.tsx
index 0a6e146d0..9f3c1618b 100644
--- a/src/components/Dialogs/ActionsModal.tsx
+++ b/src/components/Dialogs/ActionsModal.tsx
@@ -104,7 +104,7 @@ const Action = ({ actionKey, length }: { actionKey: string, length: number }) =>
return (
5 ? 'mr-4' : '',
)}
onClick={handleAction}
@@ -138,7 +138,7 @@ function ActionsModal({ onClose, show }: Props) {
className={cx(
activeTab === key
? 'w-[7.5rem] text-center bg-panel-menu-item-background p-3 rounded-lg text-panel-menu-item-text cursor-pointer'
- : 'w-[7.5rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer',
+ : 'w-[7.5rem] text-center p-3 rounded-lg hover:bg-panel-menu-item-background-hover cursor-pointer transition-colors',
)}
key={key}
onClick={() => setActiveTab(key)}
diff --git a/src/components/Layout/TopNav.tsx b/src/components/Layout/TopNav.tsx
index 5fdfe7691..853677704 100644
--- a/src/components/Layout/TopNav.tsx
+++ b/src/components/Layout/TopNav.tsx
@@ -167,7 +167,7 @@ function TopNav() {
layoutEditMode && 'opacity-65 pointer-events-none',
)}
>
-
+
Shoko
diff --git a/src/components/Utilities/ReleaseManagement/Title.tsx b/src/components/Utilities/ReleaseManagement/Title.tsx
index 7ea65b9d7..4300cd9fa 100644
--- a/src/components/Utilities/ReleaseManagement/Title.tsx
+++ b/src/components/Utilities/ReleaseManagement/Title.tsx
@@ -4,7 +4,12 @@ import { mdiChevronRight } from '@mdi/js';
import { Icon } from '@mdi/react';
const TabButton = ({ id, name }: { id: string, name: string }) => (
-
(isActive ? 'text-panel-text-primary' : '')}>
+ (isActive ? 'text-panel-text-primary' : 'hover:text-panel-text-primary transition-colors')}
+ >
{name}
);
diff --git a/src/components/Utilities/Unrecognized/Title.tsx b/src/components/Utilities/Unrecognized/Title.tsx
index 6d11ea9b1..20caef864 100644
--- a/src/components/Utilities/Unrecognized/Title.tsx
+++ b/src/components/Utilities/Unrecognized/Title.tsx
@@ -4,7 +4,12 @@ import { mdiChevronRight } from '@mdi/js';
import { Icon } from '@mdi/react';
const TabButton = ({ id, name }: { id: string, name: string }) => (
- (isActive ? 'text-panel-text-primary' : '')}>
+ (isActive ? 'text-panel-text-primary' : 'hover:text-panel-text-primary transition-colors')}
+ >
{name}
);
diff --git a/src/pages/collection/Collection.tsx b/src/pages/collection/Collection.tsx
index b2ea93a19..e018a598d 100644
--- a/src/pages/collection/Collection.tsx
+++ b/src/pages/collection/Collection.tsx
@@ -198,7 +198,7 @@ function Collection() {
return (
-
+
diff --git a/src/pages/dashboard/panels/CollectionStats.tsx b/src/pages/dashboard/panels/CollectionStats.tsx
index 1540a519f..e31e079c4 100644
--- a/src/pages/dashboard/panels/CollectionStats.tsx
+++ b/src/pages/dashboard/panels/CollectionStats.tsx
@@ -1,23 +1,49 @@
import React from 'react';
-import { useSelector } from 'react-redux';
-import { Link } from 'react-router-dom';
+import { useDispatch, useSelector } from 'react-redux';
+import { Link, useNavigate } from 'react-router-dom';
import prettyBytes from 'pretty-bytes';
import ShokoPanel from '@/components/Panels/ShokoPanel';
import { useDashbordStatsQuery } from '@/core/react-query/dashboard/queries';
+import { resetFilter } from '@/core/slices/collection';
+import { addFilterCriteriaToStore } from '@/core/utilities/filter';
+import useEventCallback from '@/hooks/useEventCallback';
import type { RootState } from '@/core/store';
const Item = (
- { link, title, value = 0 }: { title: string, value?: string | number, link?: string },
-) => (
-
-
- {title}
+ { filter, link, title, value = 0 }: { title: string, value?: string | number, link?: string, filter?: string },
+) => {
+ const dispatch = useDispatch();
+ const navigate = useNavigate();
+ const handleMissingFilter = useEventCallback((filterName: string) => {
+ dispatch(resetFilter());
+ addFilterCriteriaToStore(filterName).then(() => {
+ navigate('/webui/collection');
+ }).catch(console.error);
+ });
+
+ return (
+
+
+ {title}
+
+ {/* eslint-disable-next-line no-nested-ternary */}
+ {link
+ ?
{value}
+ : filter
+ ? (
+
handleMissingFilter(filter)}
+ >
+ {value}
+
+ )
+ :
{value}
}
- {link ?
{value} :
{value}
}
-
-);
+ );
+};
function CollectionStats() {
const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode);
@@ -53,13 +79,24 @@ function CollectionStats() {
];
const childrenThird = [
-
,
+
,
,
+
,
-
,
];
return (
diff --git a/src/pages/settings/SettingsPage.tsx b/src/pages/settings/SettingsPage.tsx
index e4924015e..f8cf9526f 100644
--- a/src/pages/settings/SettingsPage.tsx
+++ b/src/pages/settings/SettingsPage.tsx
@@ -159,7 +159,7 @@ function SettingsPage() {
to={item.path}
className={({ isActive }) => (isActive
? 'w-full text-center bg-panel-menu-item-background py-2 px-2 rounded-lg text-panel-menu-item-text'
- : 'w-full text-center py-2 px-2 rounded-lg hover:bg-panel-menu-item-background-hover')}
+ : 'w-full text-center py-2 px-2 rounded-lg hover:bg-panel-menu-item-background-hover transition-colors')}
key={item.path}
>
{item.name}