From fdd96507b87e9d51ecb074fc6a5ab8dd427f6d63 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Thu, 23 Oct 2025 15:41:46 +0200 Subject: [PATCH] Add politics filter --- backend/api/src/get-profiles.ts | 10 ++ common/src/api/schema.ts | 1 + common/src/filters.ts | 2 + web/components/filters/desktop-filters.tsx | 29 ++++- web/components/filters/mobile-filters.tsx | 115 ++++++++++++-------- web/components/filters/political-filter.tsx | 61 +++++++++++ web/components/filters/use-filters.ts | 22 ++-- web/lib/util/convert-types.ts | 8 +- 8 files changed, 189 insertions(+), 59 deletions(-) create mode 100644 web/components/filters/political-filter.tsx diff --git a/backend/api/src/get-profiles.ts b/backend/api/src/get-profiles.ts index 378f7767..5dd1c8b0 100644 --- a/backend/api/src/get-profiles.ts +++ b/backend/api/src/get-profiles.ts @@ -18,6 +18,7 @@ export type profileQueryType = { pref_relation_styles?: String[] | undefined, pref_romantic_styles?: String[] | undefined, diet?: String[] | undefined, + political_beliefs?: String[] | undefined, wants_kids_strength?: number | undefined, has_kids?: number | undefined, is_smoker?: boolean | undefined, @@ -49,6 +50,7 @@ export const loadProfiles = async (props: profileQueryType) => { pref_relation_styles, pref_romantic_styles, diet, + political_beliefs, wants_kids_strength, has_kids, is_smoker, @@ -89,6 +91,8 @@ export const loadProfiles = async (props: profileQueryType) => { intersection(pref_romantic_styles, l.pref_romantic_styles).length) && (!diet || intersection(diet, l.diet).length) && + (!political_beliefs || + intersection(political_beliefs, l.political_beliefs).length) && (!wants_kids_strength || wants_kids_strength == -1 || !l.wants_kids_strength || @@ -172,6 +176,12 @@ export const loadProfiles = async (props: profileQueryType) => { {diet} ), + political_beliefs?.length && + where( + `political_beliefs IS NULL OR political_beliefs = '{}' OR political_beliefs && $(political_beliefs)`, + {political_beliefs} + ), + !!wants_kids_strength && wants_kids_strength !== -1 && where( diff --git a/common/src/api/schema.ts b/common/src/api/schema.ts index d158f236..2e496bc8 100644 --- a/common/src/api/schema.ts +++ b/common/src/api/schema.ts @@ -351,6 +351,7 @@ export const API = (_apiTypeCheck = { pref_relation_styles: arraybeSchema.optional(), pref_romantic_styles: arraybeSchema.optional(), diet: arraybeSchema.optional(), + political_beliefs: arraybeSchema.optional(), wants_kids_strength: z.coerce.number().optional(), has_kids: z.coerce.number().optional(), is_smoker: z.coerce.boolean().optional(), diff --git a/common/src/filters.ts b/common/src/filters.ts index f57af4b1..3fa0bfd7 100644 --- a/common/src/filters.ts +++ b/common/src/filters.ts @@ -23,6 +23,7 @@ export type FilterFields = { | 'pref_relation_styles' | 'pref_romantic_styles' | 'diet' + | 'political_beliefs' | 'is_smoker' | 'has_kids' | 'pref_gender' @@ -64,6 +65,7 @@ export const initialFilters: Partial = { pref_relation_styles: undefined, pref_romantic_styles: undefined, diet: undefined, + political_beliefs: undefined, pref_gender: undefined, shortBio: undefined, orderBy: 'created_time', diff --git a/web/components/filters/desktop-filters.tsx b/web/components/filters/desktop-filters.tsx index efda8729..c20f70ca 100644 --- a/web/components/filters/desktop-filters.tsx +++ b/web/components/filters/desktop-filters.tsx @@ -1,5 +1,5 @@ import {ChevronDownIcon, ChevronUpIcon} from '@heroicons/react/outline' -import {DietType, RelationshipType, RomanticType} from 'web/lib/util/convert-types' +import {DietType, PoliticalType, RelationshipType, RomanticType} from 'web/lib/util/convert-types' import {ReactNode} from 'react' import {FaUserGroup} from 'react-icons/fa6' import {Col} from 'web/components/layout/col' @@ -22,6 +22,7 @@ import {HasKidsLabel} from "web/components/filters/has-kids-filter"; import {RomanticFilter, RomanticFilterText} from "web/components/filters/romantic-filter"; import {FaHeart} from "react-icons/fa"; import {DietFilter, DietFilterText} from "web/components/filters/diet-filter"; +import {PoliticalFilter, PoliticalFilterText} from "web/components/filters/political-filter"; export function DesktopFilters(props: { filters: Partial @@ -318,6 +319,32 @@ export function DesktopFilters(props: { menuWidth="w-50" /> + {/* POLITICS */} + ( + + + + } + /> + )} + dropdownMenuContent={ + + } + popoverClassName="bg-canvas-50" + menuWidth="w-50" + /> + {/* Short Bios */} @@ -188,53 +189,53 @@ function MobileFilters(props: { - {/* WANTS KIDS */} - } - selection={ - - } - > - - + {/* WANTS KIDS */} + } + selection={ + + } + > + + - {/* HAS KIDS */} - } - selection={ - - } - > - - + {/* HAS KIDS */} + } + selection={ + + } + > + + } @@ -258,6 +259,26 @@ function MobileFilters(props: { + {/* POLITICS */} + + } + > + + + {/* Short Bios */} Any politics + ) + } + + const convertedTypes = options.map((r) => + convertPoliticalTypes(r) + ) + + if (length > 1) { + return ( + + + Multiple + + + ) + } + return ( +
+ + {stringOrStringArrayToText({ + text: convertedTypes, + capitalizeFirstLetterOption: true, + })}{' '} + +
+ ) +} + +export function PoliticalFilter(props: { + filters: Partial + updateFilter: (newState: Partial) => void +}) { + const {filters, updateFilter} = props + return ( + { + updateFilter({political_beliefs: c}) + }} + /> + ) +} diff --git a/web/components/filters/use-filters.ts b/web/components/filters/use-filters.ts index 9a6b741a..ee166882 100644 --- a/web/components/filters/use-filters.ts +++ b/web/components/filters/use-filters.ts @@ -85,6 +85,7 @@ export const useFilters = (you: Profile | undefined) => { pref_relation_styles: you?.pref_relation_styles.length ? you.pref_relation_styles : undefined, pref_romantic_styles: you?.pref_romantic_styles?.length ? you.pref_romantic_styles : undefined, diet: you?.diet?.length ? you.diet : undefined, + political_beliefs: you?.political_beliefs?.length ? you.political_beliefs : undefined, wants_kids_strength: wantsKidsDatabaseToWantsKidsFilter( (you?.wants_kids_strength ?? 2) as wantsKidsDatabase ), @@ -95,16 +96,17 @@ export const useFilters = (you: Profile | undefined) => { console.debug(you, yourFilters) const isYourFilters = - !!you && - (!location || location.id === you.geodb_city_id) && - isEqual(filters.genders?.length ? filters.genders : undefined, yourFilters.genders?.length ? yourFilters.genders : undefined) && - filters.pref_gender?.length == 1 && isEqual(filters.pref_gender?.length ? filters.pref_gender[0] : undefined, you.gender) && - isEqual(new Set(filters.pref_romantic_styles), new Set(you.pref_romantic_styles)) && - isEqual(new Set(filters.pref_relation_styles), new Set(you.pref_relation_styles)) && - isEqual(new Set(filters.diet), new Set(you.diet)) && - filters.pref_age_max == yourFilters.pref_age_max && - filters.pref_age_min == yourFilters.pref_age_min && - filters.wants_kids_strength == yourFilters.wants_kids_strength + !!you + && (!location || location.id === you.geodb_city_id) + && isEqual(filters.genders?.length ? filters.genders : undefined, yourFilters.genders?.length ? yourFilters.genders : undefined) + && (!you.gender || filters.pref_gender?.length == 1 && isEqual(filters.pref_gender?.length ? filters.pref_gender[0] : undefined, you.gender)) + && isEqual(new Set(filters.pref_romantic_styles), new Set(you.pref_romantic_styles)) + && isEqual(new Set(filters.pref_relation_styles), new Set(you.pref_relation_styles)) + && isEqual(new Set(filters.diet), new Set(you.diet)) + && isEqual(new Set(filters.political_beliefs), new Set(you.political_beliefs)) + && filters.pref_age_max == yourFilters.pref_age_max + && filters.pref_age_min == yourFilters.pref_age_min + && filters.wants_kids_strength == yourFilters.wants_kids_strength const setYourFilters = (checked: boolean) => { if (checked) { diff --git a/web/lib/util/convert-types.ts b/web/lib/util/convert-types.ts index b0f8939c..6be079ac 100644 --- a/web/lib/util/convert-types.ts +++ b/web/lib/util/convert-types.ts @@ -1,12 +1,14 @@ import { REVERTED_DIET_CHOICES, REVERTED_RELATIONSHIP_CHOICES, - REVERTED_ROMANTIC_CHOICES + REVERTED_ROMANTIC_CHOICES, + REVERTED_POLITICAL_CHOICES } from "web/components/filters/choices"; export type RelationshipType = keyof typeof REVERTED_RELATIONSHIP_CHOICES export type RomanticType = keyof typeof REVERTED_ROMANTIC_CHOICES export type DietType = keyof typeof REVERTED_DIET_CHOICES +export type PoliticalType = keyof typeof REVERTED_POLITICAL_CHOICES export function convertRelationshipType(relationshipType: RelationshipType) { return REVERTED_RELATIONSHIP_CHOICES[relationshipType] @@ -19,3 +21,7 @@ export function convertRomanticTypes(romanticType: RomanticType) { export function convertDietTypes(dietType: DietType) { return REVERTED_DIET_CHOICES[dietType] } + +export function convertPoliticalTypes(politicalType: PoliticalType) { + return REVERTED_POLITICAL_CHOICES[politicalType] +}