feat: add content certification/age-rating filter (#1418)

* feat(api): add TMDB certifications endpoint and discover certification params

re #501

* feat(discover): add certification/age-rating filter to movies and series

Add generic and US-only certification selector components, update Discover FilterSlideover, add
certification options to query constants

re #501

* fix(certificationselector): fix linter warning from useEffect missing dependency

* fix(jellyseerr-api.yml): prettier formatting

* chore(translation keys): run pnpm i18n:extract

* fix(certificationselector): change query destructure to Zod omit, fix translations, fix formatting

* style: fix whitespace with prettier
This commit is contained in:
Dillion
2025-05-06 12:55:02 -05:00
committed by GitHub
parent e5b77b2688
commit 149d79e540
10 changed files with 766 additions and 4 deletions

View File

@@ -109,6 +109,11 @@ export const QueryFilterOptions = z.object({
watchRegion: z.string().optional(),
watchProviders: z.string().optional(),
status: z.string().optional(),
certification: z.string().optional(),
certificationGte: z.string().optional(),
certificationLte: z.string().optional(),
certificationCountry: z.string().optional(),
certificationMode: z.enum(['exact', 'range']).optional(),
});
export type FilterOptions = z.infer<typeof QueryFilterOptions>;
@@ -192,6 +197,30 @@ export const prepareFilterValues = (
filterValues.watchRegion = values.watchRegion;
}
if (values.certification) {
filterValues.certification = values.certification;
}
if (values.certificationGte) {
filterValues.certificationGte = values.certificationGte;
}
if (values.certificationLte) {
filterValues.certificationLte = values.certificationLte;
}
if (values.certificationCountry) {
filterValues.certificationCountry = values.certificationCountry;
}
if (values.certificationMode) {
filterValues.certificationMode = values.certificationMode;
} else if (values.certification) {
filterValues.certificationMode = 'exact';
} else if (values.certificationGte || values.certificationLte) {
filterValues.certificationMode = 'range';
}
return filterValues;
};
@@ -223,6 +252,20 @@ export const countActiveFilters = (filterValues: FilterOptions): number => {
delete clonedFilters.watchRegion;
}
if (
clonedFilters.certification ||
clonedFilters.certificationGte ||
clonedFilters.certificationLte ||
clonedFilters.certificationCountry
) {
totalCount += 1;
delete clonedFilters.certification;
delete clonedFilters.certificationGte;
delete clonedFilters.certificationLte;
delete clonedFilters.certificationCountry;
}
delete clonedFilters.certificationMode;
totalCount += Object.keys(clonedFilters).length;
return totalCount;