mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-04-08 08:39:36 -04:00
Add politics filter
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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<FilterFields> = {
|
||||
pref_relation_styles: undefined,
|
||||
pref_romantic_styles: undefined,
|
||||
diet: undefined,
|
||||
political_beliefs: undefined,
|
||||
pref_gender: undefined,
|
||||
shortBio: undefined,
|
||||
orderBy: 'created_time',
|
||||
|
||||
@@ -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<FilterFields>
|
||||
@@ -318,6 +319,32 @@ export function DesktopFilters(props: {
|
||||
menuWidth="w-50"
|
||||
/>
|
||||
|
||||
{/* POLITICS */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open) => (
|
||||
<DropdownButton
|
||||
open={open}
|
||||
content={
|
||||
<Row className="items-center gap-1">
|
||||
<PoliticalFilterText
|
||||
options={
|
||||
filters.political_beliefs as
|
||||
| PoliticalType[]
|
||||
| undefined
|
||||
}
|
||||
highlightedClass={open ? 'text-primary-500' : undefined}
|
||||
/>
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<PoliticalFilter filters={filters} updateFilter={updateFilter}/>
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-50"
|
||||
/>
|
||||
|
||||
{/* Short Bios */}
|
||||
<ShortBioToggle
|
||||
updateFilter={updateFilter}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {RelationshipFilter, RelationshipFilterText,} from './relationship-filter
|
||||
import {MyMatchesToggle} from './my-matches-toggle'
|
||||
import {Profile} from 'common/profiles/profile'
|
||||
import {Gender} from 'common/gender'
|
||||
import {DietType, RelationshipType, RomanticType} from 'web/lib/util/convert-types'
|
||||
import {DietType, PoliticalType, RelationshipType, RomanticType} from 'web/lib/util/convert-types'
|
||||
import {FilterFields} from "common/filters";
|
||||
import {ShortBioToggle} from "web/components/filters/short-bio-toggle";
|
||||
import {PrefGenderFilter, PrefGenderFilterText} from "./pref-gender-filter"
|
||||
@@ -21,6 +21,7 @@ import {HasKidsFilter, HasKidsLabel} from "./has-kids-filter"
|
||||
import {hasKidsLabels} from "common/has-kids";
|
||||
import {RomanticFilter, RomanticFilterText} from "web/components/filters/romantic-filter";
|
||||
import {DietFilter, DietFilterText} from "web/components/filters/diet-filter";
|
||||
import {PoliticalFilter, PoliticalFilterText} from "web/components/filters/political-filter";
|
||||
|
||||
function MobileFilters(props: {
|
||||
filters: Partial<FilterFields>
|
||||
@@ -188,53 +189,53 @@ function MobileFilters(props: {
|
||||
<RomanticFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
|
||||
{/* WANTS KIDS */}
|
||||
<MobileFilterSection
|
||||
title="Wants kids"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={
|
||||
filters.wants_kids_strength != null &&
|
||||
filters.wants_kids_strength !== -1
|
||||
}
|
||||
icon={<WantsKidsIcon strength={filters.wants_kids_strength ?? -1}/>}
|
||||
selection={
|
||||
<KidsLabel
|
||||
strength={filters.wants_kids_strength ?? -1}
|
||||
highlightedClass={
|
||||
(filters.wants_kids_strength ?? -1) ==
|
||||
wantsKidsLabels.no_preference.strength
|
||||
? 'text-ink-900'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<WantsKidsFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
{/* WANTS KIDS */}
|
||||
<MobileFilterSection
|
||||
title="Wants kids"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={
|
||||
filters.wants_kids_strength != null &&
|
||||
filters.wants_kids_strength !== -1
|
||||
}
|
||||
icon={<WantsKidsIcon strength={filters.wants_kids_strength ?? -1}/>}
|
||||
selection={
|
||||
<KidsLabel
|
||||
strength={filters.wants_kids_strength ?? -1}
|
||||
highlightedClass={
|
||||
(filters.wants_kids_strength ?? -1) ==
|
||||
wantsKidsLabels.no_preference.strength
|
||||
? 'text-ink-900'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<WantsKidsFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
|
||||
{/* HAS KIDS */}
|
||||
<MobileFilterSection
|
||||
title="Has kids"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={filters.has_kids != null && filters.has_kids !== -1}
|
||||
icon={<FaChild className="text-ink-900 h-4 w-4"/>}
|
||||
selection={
|
||||
<HasKidsLabel
|
||||
has_kids={filters.has_kids ?? -1}
|
||||
highlightedClass={
|
||||
(filters.has_kids ?? -1) == hasKidsLabels.no_preference.value
|
||||
? 'text-ink-900'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<HasKidsFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
{/* HAS KIDS */}
|
||||
<MobileFilterSection
|
||||
title="Has kids"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={filters.has_kids != null && filters.has_kids !== -1}
|
||||
icon={<FaChild className="text-ink-900 h-4 w-4"/>}
|
||||
selection={
|
||||
<HasKidsLabel
|
||||
has_kids={filters.has_kids ?? -1}
|
||||
highlightedClass={
|
||||
(filters.has_kids ?? -1) == hasKidsLabels.no_preference.value
|
||||
? 'text-ink-900'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<HasKidsFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
|
||||
</>}
|
||||
|
||||
@@ -258,6 +259,26 @@ function MobileFilters(props: {
|
||||
<DietFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
|
||||
{/* POLITICS */}
|
||||
<MobileFilterSection
|
||||
title="Politics"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={hasAny(filters.political_beliefs || undefined)}
|
||||
selection={
|
||||
<PoliticalFilterText
|
||||
options={filters.political_beliefs as PoliticalType[]}
|
||||
highlightedClass={
|
||||
hasAny(filters.political_beliefs || undefined)
|
||||
? 'text-primary-600'
|
||||
: 'text-ink-900'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<PoliticalFilter filters={filters} updateFilter={updateFilter}/>
|
||||
</MobileFilterSection>
|
||||
|
||||
{/* Short Bios */}
|
||||
<Col className="p-4 pb-2">
|
||||
<ShortBioToggle
|
||||
|
||||
61
web/components/filters/political-filter.tsx
Normal file
61
web/components/filters/political-filter.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import clsx from 'clsx'
|
||||
import {convertPoliticalTypes, PoliticalType,} from 'web/lib/util/convert-types'
|
||||
import stringOrStringArrayToText from 'web/lib/util/string-or-string-array-to-text'
|
||||
import {MultiCheckbox} from 'web/components/multi-checkbox'
|
||||
|
||||
import {POLITICAL_CHOICES} from "web/components/filters/choices";
|
||||
import {FilterFields} from "common/filters";
|
||||
|
||||
export function PoliticalFilterText(props: {
|
||||
options: PoliticalType[] | undefined
|
||||
highlightedClass?: string
|
||||
}) {
|
||||
const {options, highlightedClass} = props
|
||||
const length = (options ?? []).length
|
||||
|
||||
if (!options || length < 1) {
|
||||
return (
|
||||
<span className={clsx('text-semibold', highlightedClass)}>Any politics</span>
|
||||
)
|
||||
}
|
||||
|
||||
const convertedTypes = options.map((r) =>
|
||||
convertPoliticalTypes(r)
|
||||
)
|
||||
|
||||
if (length > 1) {
|
||||
return (
|
||||
<span>
|
||||
<span className={clsx('font-semibold', highlightedClass)}>
|
||||
Multiple
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<span className={clsx('font-semibold', highlightedClass)}>
|
||||
{stringOrStringArrayToText({
|
||||
text: convertedTypes,
|
||||
capitalizeFirstLetterOption: true,
|
||||
})}{' '}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function PoliticalFilter(props: {
|
||||
filters: Partial<FilterFields>
|
||||
updateFilter: (newState: Partial<FilterFields>) => void
|
||||
}) {
|
||||
const {filters, updateFilter} = props
|
||||
return (
|
||||
<MultiCheckbox
|
||||
selected={filters.political_beliefs ?? []}
|
||||
choices={POLITICAL_CHOICES as any}
|
||||
onChange={(c) => {
|
||||
updateFilter({political_beliefs: c})
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user