mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-08 07:03:57 -04:00
Meke age optional in API requests
This commit is contained in:
@@ -4,6 +4,7 @@ import {createSupabaseDirectClient} from 'shared/supabase/init'
|
||||
import {from, join, limit, orderBy, renderSql, select, where,} from 'shared/supabase/sql-builder'
|
||||
import {getCompatibleLovers} from 'api/compatible-lovers'
|
||||
import {intersection} from 'lodash'
|
||||
import {MAX_INT, MIN_INT} from "common/constants";
|
||||
|
||||
export const getLovers: APIHandler<'get-lovers'> = async (props, _auth) => {
|
||||
const pg = createSupabaseDirectClient()
|
||||
@@ -37,8 +38,8 @@ export const getLovers: APIHandler<'get-lovers'> = async (props, _auth) => {
|
||||
(!name || l.user.name.toLowerCase().includes(name.toLowerCase())) &&
|
||||
(!genders || genders.includes(l.gender)) &&
|
||||
(!pref_gender || intersection(pref_gender, l.pref_gender).length) &&
|
||||
(!pref_age_min || l.age >= pref_age_min) &&
|
||||
(!pref_age_max || l.age <= pref_age_max) &&
|
||||
(!pref_age_min || (l.age ?? MAX_INT) >= pref_age_min) &&
|
||||
(!pref_age_max || (l.age ?? MIN_INT) <= pref_age_max) &&
|
||||
(!pref_relation_styles ||
|
||||
intersection(pref_relation_styles, l.pref_relation_styles).length) &&
|
||||
(!wants_kids_strength ||
|
||||
@@ -87,18 +88,18 @@ export const getLovers: APIHandler<'get-lovers'> = async (props, _auth) => {
|
||||
pref_gender?.length &&
|
||||
where(`pref_gender && $(pref_gender)`, {pref_gender}),
|
||||
|
||||
pref_age_min !== undefined &&
|
||||
where(`age >= $(pref_age_min)`, {pref_age_min}),
|
||||
pref_age_min &&
|
||||
where(`age >= $(pref_age_min) or age is null`, {pref_age_min}),
|
||||
|
||||
pref_age_max !== undefined &&
|
||||
where(`age <= $(pref_age_max)`, {pref_age_max}),
|
||||
pref_age_max &&
|
||||
where(`age <= $(pref_age_max) or age is null`, {pref_age_max}),
|
||||
|
||||
pref_relation_styles?.length &&
|
||||
where(`pref_relation_styles && $(pref_relation_styles)`, {
|
||||
pref_relation_styles,
|
||||
}),
|
||||
|
||||
wants_kids_strength !== undefined &&
|
||||
!!wants_kids_strength &&
|
||||
wants_kids_strength !== -1 &&
|
||||
where(
|
||||
wants_kids_strength >= 2
|
||||
@@ -125,7 +126,7 @@ export const getLovers: APIHandler<'get-lovers'> = async (props, _auth) => {
|
||||
limit(limitParam)
|
||||
)
|
||||
|
||||
// console.debug('query:', query)
|
||||
// console.log('query:', query)
|
||||
|
||||
const lovers = await pg.map(query, [], convertRow)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ END IF;
|
||||
END$$;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS lovers (
|
||||
age INTEGER DEFAULT 18 NOT NULL,
|
||||
age INTEGER NULL,
|
||||
bio JSON,
|
||||
born_in_location TEXT,
|
||||
city TEXT NOT NULL,
|
||||
@@ -36,8 +36,8 @@ CREATE TABLE IF NOT EXISTS lovers (
|
||||
photo_urls TEXT[],
|
||||
pinned_url TEXT,
|
||||
political_beliefs TEXT[],
|
||||
pref_age_max INTEGER DEFAULT 100 NOT NULL,
|
||||
pref_age_min INTEGER DEFAULT 18 NOT NULL,
|
||||
pref_age_max INTEGER NULL,
|
||||
pref_age_min INTEGER NULL,
|
||||
pref_gender TEXT[] NOT NULL,
|
||||
pref_relation_styles TEXT[] NOT NULL,
|
||||
referred_by_username TEXT,
|
||||
|
||||
@@ -44,11 +44,11 @@ const genderTypes = z.array(genderType)
|
||||
|
||||
export const baseLoversSchema = z.object({
|
||||
// Required fields
|
||||
age: z.number().min(18).max(100),
|
||||
age: z.number().min(18).max(100).optional(),
|
||||
gender: genderType,
|
||||
pref_gender: genderTypes,
|
||||
pref_age_min: z.number().min(18).max(999),
|
||||
pref_age_max: z.number().min(18).max(1000),
|
||||
pref_age_min: z.number().min(18).max(100).optional(),
|
||||
pref_age_max: z.number().min(18).max(100).optional(),
|
||||
pref_relation_styles: z.array(
|
||||
z.union([
|
||||
z.literal('collaboration'),
|
||||
|
||||
2
common/src/constants.ts
Normal file
2
common/src/constants.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const MAX_INT = 99999
|
||||
export const MIN_INT = -MAX_INT
|
||||
@@ -1,4 +1,5 @@
|
||||
import { LoverRow } from 'common/love/lover'
|
||||
import {MAX_INT, MIN_INT} from "common/constants";
|
||||
|
||||
const isPreferredGender = (
|
||||
preferredGenders: string[] | undefined,
|
||||
@@ -25,8 +26,8 @@ export const areGenderCompatible = (lover1: LoverRow, lover2: LoverRow) => {
|
||||
)
|
||||
}
|
||||
|
||||
const satisfiesAgeRange = (lover: LoverRow, age: number) => {
|
||||
return age >= lover.pref_age_min && age <= lover.pref_age_max
|
||||
const satisfiesAgeRange = (lover: LoverRow, age: number | null | undefined) => {
|
||||
return (age ?? MAX_INT) >= (lover.pref_age_min ?? MIN_INT) && (age ?? MIN_INT) <= (lover.pref_age_max ?? MAX_INT)
|
||||
}
|
||||
|
||||
export const areAgeCompatible = (lover1: LoverRow, lover2: LoverRow) => {
|
||||
|
||||
@@ -19,7 +19,7 @@ export function getLoveOgImageUrl(user: User, lover?: LoverRow | null) {
|
||||
avatarUrl: lover?.pinned_url,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
age: lover?.age.toString() ?? '25',
|
||||
age: lover?.age?.toString() ?? '25',
|
||||
city: lover?.city ?? 'Internet',
|
||||
gender: lover?.gender ?? '???',
|
||||
} as LoveOgProps
|
||||
|
||||
@@ -262,7 +262,7 @@ export type Database = {
|
||||
}
|
||||
lovers: {
|
||||
Row: {
|
||||
age: number
|
||||
age: number | null
|
||||
bio: Json | null
|
||||
bio_text: unknown | null
|
||||
born_in_location: string | null
|
||||
@@ -292,8 +292,8 @@ export type Database = {
|
||||
photo_urls: string[] | null
|
||||
pinned_url: string | null
|
||||
political_beliefs: string[] | null
|
||||
pref_age_max: number
|
||||
pref_age_min: number
|
||||
pref_age_max: number | null
|
||||
pref_age_min: number | null
|
||||
pref_gender: string[]
|
||||
pref_relation_styles: string[]
|
||||
referred_by_username: string | null
|
||||
@@ -308,7 +308,7 @@ export type Database = {
|
||||
website: string | null
|
||||
}
|
||||
Insert: {
|
||||
age?: number
|
||||
age?: number | null
|
||||
bio?: Json | null
|
||||
bio_text?: unknown | null
|
||||
born_in_location?: string | null
|
||||
@@ -338,8 +338,8 @@ export type Database = {
|
||||
photo_urls?: string[] | null
|
||||
pinned_url?: string | null
|
||||
political_beliefs?: string[] | null
|
||||
pref_age_max?: number
|
||||
pref_age_min?: number
|
||||
pref_age_max?: number | null
|
||||
pref_age_min?: number | null
|
||||
pref_gender: string[]
|
||||
pref_relation_styles: string[]
|
||||
referred_by_username?: string | null
|
||||
@@ -354,7 +354,7 @@ export type Database = {
|
||||
website?: string | null
|
||||
}
|
||||
Update: {
|
||||
age?: number
|
||||
age?: number | null
|
||||
bio?: Json | null
|
||||
bio_text?: unknown | null
|
||||
born_in_location?: string | null
|
||||
@@ -384,8 +384,8 @@ export type Database = {
|
||||
photo_urls?: string[] | null
|
||||
pinned_url?: string | null
|
||||
political_beliefs?: string[] | null
|
||||
pref_age_max?: number
|
||||
pref_age_min?: number
|
||||
pref_age_max?: number | null
|
||||
pref_age_min?: number | null
|
||||
pref_gender?: string[]
|
||||
pref_relation_styles?: string[]
|
||||
referred_by_username?: string | null
|
||||
|
||||
@@ -3,11 +3,11 @@ import { FilterFields } from './search'
|
||||
import { RangeSlider } from 'web/components/widgets/slider'
|
||||
|
||||
export const PREF_AGE_MIN = 18
|
||||
export const PREF_AGE_MAX = 99
|
||||
export const PREF_AGE_MAX = 100
|
||||
|
||||
export function getNoMinMaxAge(
|
||||
pref_age_min: number | undefined,
|
||||
pref_age_max: number | undefined
|
||||
pref_age_min: number | null | undefined,
|
||||
pref_age_max: number | null | undefined
|
||||
) {
|
||||
const noMinAge = !pref_age_min || pref_age_min <= PREF_AGE_MIN
|
||||
const noMaxAge = !pref_age_max || pref_age_max >= PREF_AGE_MAX
|
||||
@@ -15,8 +15,8 @@ export function getNoMinMaxAge(
|
||||
}
|
||||
|
||||
export function AgeFilterText(props: {
|
||||
pref_age_min: number | undefined
|
||||
pref_age_max: number | undefined
|
||||
pref_age_min: number | null | undefined
|
||||
pref_age_max: number | null | undefined
|
||||
highlightedClass?: string
|
||||
}) {
|
||||
const { pref_age_min, pref_age_max, highlightedClass } = props
|
||||
|
||||
@@ -52,6 +52,79 @@ export function DesktopFilters(props: {
|
||||
on={isYourFilters}
|
||||
hidden={!youLover}
|
||||
/>
|
||||
{/* CONNECTION */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open) => (
|
||||
<DropdownButton
|
||||
open={open}
|
||||
content={
|
||||
<Row className="items-center gap-1">
|
||||
<FaUserGroup className="h-4 w-4" />
|
||||
<RelationshipFilterText
|
||||
relationship={
|
||||
filters.pref_relation_styles as
|
||||
| RelationshipType[]
|
||||
| undefined
|
||||
}
|
||||
highlightedClass={open ? 'text-primary-500' : undefined}
|
||||
/>
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<RelationshipFilter filters={filters} updateFilter={updateFilter} />
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-50"
|
||||
/>
|
||||
{/* LOCATION */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
content={
|
||||
<LocationFilterText
|
||||
youLover={youLover}
|
||||
location={locationFilterProps.location}
|
||||
radius={locationFilterProps.radius}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
open={open}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<LocationFilter
|
||||
youLover={youLover}
|
||||
locationFilterProps={locationFilterProps}
|
||||
/>
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-80"
|
||||
/>
|
||||
{/* AGE RANGE */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
open={open}
|
||||
content={
|
||||
<AgeFilterText
|
||||
pref_age_min={filters.pref_age_min}
|
||||
pref_age_max={filters.pref_age_max}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<Col className="mx-2 mb-4">
|
||||
<AgeFilter filters={filters} updateFilter={updateFilter} />
|
||||
</Col>
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-80"
|
||||
/>
|
||||
{/* GENDER */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
@@ -91,165 +164,94 @@ export function DesktopFilters(props: {
|
||||
{/* }*/}
|
||||
{/* popoverClassName="bg-canvas-50"*/}
|
||||
{/*/>*/}
|
||||
{/* AGE RANGE */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
open={open}
|
||||
content={
|
||||
<AgeFilterText
|
||||
pref_age_min={filters.pref_age_min}
|
||||
pref_age_max={filters.pref_age_max}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<Col className="mx-2 mb-4">
|
||||
<AgeFilter filters={filters} updateFilter={updateFilter} />
|
||||
</Col>
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-80"
|
||||
/>
|
||||
{/* LOCATION */}
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
content={
|
||||
<LocationFilterText
|
||||
youLover={youLover}
|
||||
location={locationFilterProps.location}
|
||||
radius={locationFilterProps.radius}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
open={open}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<LocationFilter
|
||||
youLover={youLover}
|
||||
locationFilterProps={locationFilterProps}
|
||||
/>
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-80"
|
||||
/>
|
||||
<CustomizeableDropdown
|
||||
buttonContent={(open) => (
|
||||
<DropdownButton
|
||||
open={open}
|
||||
content={
|
||||
<Row className="items-center gap-1">
|
||||
<FaUserGroup className="h-4 w-4" />
|
||||
<RelationshipFilterText
|
||||
relationship={
|
||||
filters.pref_relation_styles as
|
||||
| RelationshipType[]
|
||||
| undefined
|
||||
}
|
||||
highlightedClass={open ? 'text-primary-500' : undefined}
|
||||
/>
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
dropdownMenuContent={
|
||||
<RelationshipFilter filters={filters} updateFilter={updateFilter} />
|
||||
}
|
||||
popoverClassName="bg-canvas-50"
|
||||
menuWidth="w-50"
|
||||
/>
|
||||
{/* WANTS KIDS */}
|
||||
<DropdownMenu
|
||||
items={[
|
||||
{
|
||||
name: wantsKidsLabels.no_preference.name,
|
||||
icon: wantsKidsLabels.no_preference.icon,
|
||||
onClick: () => {
|
||||
updateFilter({
|
||||
wants_kids_strength: wantsKidsLabels.no_preference.strength,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
name: wantsKidsLabels.wants_kids.name,
|
||||
icon: wantsKidsLabels.wants_kids.icon,
|
||||
onClick: () => {
|
||||
updateFilter({
|
||||
wants_kids_strength: wantsKidsLabels.wants_kids.strength,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
name: wantsKidsLabels.doesnt_want_kids.name,
|
||||
icon: wantsKidsLabels.doesnt_want_kids.icon,
|
||||
onClick: () => {
|
||||
updateFilter({
|
||||
wants_kids_strength: wantsKidsLabels.doesnt_want_kids.strength,
|
||||
})
|
||||
},
|
||||
},
|
||||
]}
|
||||
closeOnClick
|
||||
buttonClass={'!text-ink-600 !hover:!text-ink-600'}
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
content={
|
||||
<KidsLabel
|
||||
strength={
|
||||
filters.wants_kids_strength ??
|
||||
wantsKidsLabels.no_preference.strength
|
||||
}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
open={open}
|
||||
/>
|
||||
)}
|
||||
menuItemsClass={'bg-canvas-50'}
|
||||
menuWidth="w-48"
|
||||
/>
|
||||
{/*<DropdownMenu*/}
|
||||
{/* items={[*/}
|
||||
{/* {*/}
|
||||
{/* name: wantsKidsLabels.no_preference.name,*/}
|
||||
{/* icon: wantsKidsLabels.no_preference.icon,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({*/}
|
||||
{/* wants_kids_strength: wantsKidsLabels.no_preference.strength,*/}
|
||||
{/* })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* {*/}
|
||||
{/* name: wantsKidsLabels.wants_kids.name,*/}
|
||||
{/* icon: wantsKidsLabels.wants_kids.icon,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({*/}
|
||||
{/* wants_kids_strength: wantsKidsLabels.wants_kids.strength,*/}
|
||||
{/* })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* {*/}
|
||||
{/* name: wantsKidsLabels.doesnt_want_kids.name,*/}
|
||||
{/* icon: wantsKidsLabels.doesnt_want_kids.icon,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({*/}
|
||||
{/* wants_kids_strength: wantsKidsLabels.doesnt_want_kids.strength,*/}
|
||||
{/* })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* ]}*/}
|
||||
{/* closeOnClick*/}
|
||||
{/* buttonClass={'!text-ink-600 !hover:!text-ink-600'}*/}
|
||||
{/* buttonContent={(open: boolean) => (*/}
|
||||
{/* <DropdownButton*/}
|
||||
{/* content={*/}
|
||||
{/* <KidsLabel*/}
|
||||
{/* strength={*/}
|
||||
{/* filters.wants_kids_strength ??*/}
|
||||
{/* wantsKidsLabels.no_preference.strength*/}
|
||||
{/* }*/}
|
||||
{/* highlightedClass={open ? 'text-primary-500' : ''}*/}
|
||||
{/* />*/}
|
||||
{/* }*/}
|
||||
{/* open={open}*/}
|
||||
{/* />*/}
|
||||
{/* )}*/}
|
||||
{/* menuItemsClass={'bg-canvas-50'}*/}
|
||||
{/* menuWidth="w-48"*/}
|
||||
{/*/>*/}
|
||||
{/* HAS KIDS */}
|
||||
<DropdownMenu
|
||||
items={[
|
||||
{
|
||||
name: hasKidsLabels.no_preference.name,
|
||||
onClick: () => {
|
||||
updateFilter({ has_kids: hasKidsLabels.no_preference.value })
|
||||
},
|
||||
},
|
||||
{
|
||||
name: hasKidsLabels.doesnt_have_kids.name,
|
||||
onClick: () => {
|
||||
updateFilter({ has_kids: hasKidsLabels.doesnt_have_kids.value })
|
||||
},
|
||||
},
|
||||
{
|
||||
name: hasKidsLabels.has_kids.name,
|
||||
onClick: () => {
|
||||
updateFilter({ has_kids: hasKidsLabels.has_kids.value })
|
||||
},
|
||||
},
|
||||
]}
|
||||
closeOnClick
|
||||
buttonClass={'!text-ink-600 !hover:!text-ink-600'}
|
||||
buttonContent={(open: boolean) => (
|
||||
<DropdownButton
|
||||
content={
|
||||
<HasKidsLabel
|
||||
has_kids={filters.has_kids ?? -1}
|
||||
highlightedClass={open ? 'text-primary-500' : ''}
|
||||
/>
|
||||
}
|
||||
open={open}
|
||||
/>
|
||||
)}
|
||||
menuItemsClass="bg-canvas-50"
|
||||
menuWidth="w-40"
|
||||
/>
|
||||
{/*<DropdownMenu*/}
|
||||
{/* items={[*/}
|
||||
{/* {*/}
|
||||
{/* name: hasKidsLabels.no_preference.name,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({ has_kids: hasKidsLabels.no_preference.value })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* {*/}
|
||||
{/* name: hasKidsLabels.doesnt_have_kids.name,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({ has_kids: hasKidsLabels.doesnt_have_kids.value })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* {*/}
|
||||
{/* name: hasKidsLabels.has_kids.name,*/}
|
||||
{/* onClick: () => {*/}
|
||||
{/* updateFilter({ has_kids: hasKidsLabels.has_kids.value })*/}
|
||||
{/* },*/}
|
||||
{/* },*/}
|
||||
{/* ]}*/}
|
||||
{/* closeOnClick*/}
|
||||
{/* buttonClass={'!text-ink-600 !hover:!text-ink-600'}*/}
|
||||
{/* buttonContent={(open: boolean) => (*/}
|
||||
{/* <DropdownButton*/}
|
||||
{/* content={*/}
|
||||
{/* <HasKidsLabel*/}
|
||||
{/* has_kids={filters.has_kids ?? -1}*/}
|
||||
{/* highlightedClass={open ? 'text-primary-500' : ''}*/}
|
||||
{/* />*/}
|
||||
{/* }*/}
|
||||
{/* open={open}*/}
|
||||
{/* />*/}
|
||||
{/* )}*/}
|
||||
{/* menuItemsClass="bg-canvas-50"*/}
|
||||
{/* menuWidth="w-40"*/}
|
||||
{/*/>*/}
|
||||
<button
|
||||
className="text-ink-500 hover:text-primary-500 underline"
|
||||
onClick={clearFilters}
|
||||
|
||||
@@ -68,6 +68,68 @@ export function MobileFilters(props: {
|
||||
hidden={!youLover}
|
||||
/>
|
||||
</Col>
|
||||
{/* RELATIONSHIP STYLE */}
|
||||
<MobileFilterSection
|
||||
title="Seeking"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={hasAny(filters.pref_relation_styles)}
|
||||
selection={
|
||||
<RelationshipFilterText
|
||||
relationship={filters.pref_relation_styles as RelationshipType[]}
|
||||
highlightedClass={
|
||||
hasAny(filters.pref_relation_styles)
|
||||
? 'text-primary-600'
|
||||
: 'text-ink-400'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<RelationshipFilter filters={filters} updateFilter={updateFilter} />
|
||||
</MobileFilterSection>
|
||||
{/* LOCATION */}
|
||||
<MobileFilterSection
|
||||
title="Location"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={!!locationFilterProps.location}
|
||||
selection={
|
||||
<LocationFilterText
|
||||
location={locationFilterProps.location}
|
||||
radius={locationFilterProps.radius}
|
||||
youLover={youLover}
|
||||
highlightedClass={
|
||||
!locationFilterProps.location
|
||||
? 'text-ink-400'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<LocationFilter
|
||||
youLover={youLover}
|
||||
locationFilterProps={locationFilterProps}
|
||||
/>
|
||||
</MobileFilterSection>
|
||||
{/* AGE RANGE */}
|
||||
<MobileFilterSection
|
||||
title="Age"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
childrenClassName={'pb-6'}
|
||||
isActive={!noMinAge || !noMaxAge}
|
||||
selection={
|
||||
<AgeFilterText
|
||||
pref_age_min={filters.pref_age_min}
|
||||
pref_age_max={filters.pref_age_max}
|
||||
highlightedClass={
|
||||
noMinAge && noMaxAge ? 'text-ink-400' : 'text-primary-600'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AgeFilter filters={filters} updateFilter={updateFilter} />
|
||||
</MobileFilterSection>
|
||||
{/* GENDER */}
|
||||
<MobileFilterSection
|
||||
title="Gender"
|
||||
@@ -102,114 +164,52 @@ export function MobileFilters(props: {
|
||||
{/*>*/}
|
||||
{/* <PrefGenderFilter filters={filters} updateFilter={updateFilter} />*/}
|
||||
{/*</MobileFilterSection>*/}
|
||||
{/* AGE RANGE */}
|
||||
<MobileFilterSection
|
||||
title="Age"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
childrenClassName={'pb-6'}
|
||||
isActive={!noMinAge || !noMaxAge}
|
||||
selection={
|
||||
<AgeFilterText
|
||||
pref_age_min={filters.pref_age_min}
|
||||
pref_age_max={filters.pref_age_max}
|
||||
highlightedClass={
|
||||
noMinAge && noMaxAge ? 'text-ink-400' : 'text-primary-600'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AgeFilter filters={filters} updateFilter={updateFilter} />
|
||||
</MobileFilterSection>
|
||||
{/* LOCATION */}
|
||||
<MobileFilterSection
|
||||
title="Location"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={!!locationFilterProps.location}
|
||||
selection={
|
||||
<LocationFilterText
|
||||
location={locationFilterProps.location}
|
||||
radius={locationFilterProps.radius}
|
||||
youLover={youLover}
|
||||
highlightedClass={
|
||||
!locationFilterProps.location
|
||||
? 'text-ink-400'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<LocationFilter
|
||||
youLover={youLover}
|
||||
locationFilterProps={locationFilterProps}
|
||||
/>
|
||||
</MobileFilterSection>
|
||||
{/* RELATIONSHIP STYLE */}
|
||||
<MobileFilterSection
|
||||
title="Relationship style"
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={hasAny(filters.pref_relation_styles)}
|
||||
selection={
|
||||
<RelationshipFilterText
|
||||
relationship={filters.pref_relation_styles as RelationshipType[]}
|
||||
highlightedClass={
|
||||
hasAny(filters.pref_relation_styles)
|
||||
? 'text-primary-600'
|
||||
: 'text-ink-400'
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<RelationshipFilter 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-400'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<WantsKidsFilter filters={filters} updateFilter={updateFilter} />
|
||||
</MobileFilterSection>
|
||||
{/*<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-400'*/}
|
||||
{/* : '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-400 h-4 w-4" />}
|
||||
selection={
|
||||
<HasKidsLabel
|
||||
has_kids={filters.has_kids ?? -1}
|
||||
highlightedClass={
|
||||
(filters.has_kids ?? -1) == hasKidsLabels.no_preference.value
|
||||
? 'text-ink-400'
|
||||
: 'text-primary-600'
|
||||
}
|
||||
mobile
|
||||
/>
|
||||
}
|
||||
>
|
||||
<HasKidsFilter filters={filters} updateFilter={updateFilter} />
|
||||
</MobileFilterSection>
|
||||
{/*<MobileFilterSection*/}
|
||||
{/* title="Has kids"*/}
|
||||
{/* openFilter={openFilter}*/}
|
||||
{/* setOpenFilter={setOpenFilter}*/}
|
||||
{/* isActive={filters.has_kids != null && filters.has_kids !== -1}*/}
|
||||
{/* icon={<FaChild className="text-ink-400 h-4 w-4" />}*/}
|
||||
{/* selection={*/}
|
||||
{/* <HasKidsLabel*/}
|
||||
{/* has_kids={filters.has_kids ?? -1}*/}
|
||||
{/* highlightedClass={*/}
|
||||
{/* (filters.has_kids ?? -1) == hasKidsLabels.no_preference.value*/}
|
||||
{/* ? 'text-ink-400'*/}
|
||||
{/* : 'text-primary-600'*/}
|
||||
{/* }*/}
|
||||
{/* mobile*/}
|
||||
{/* />*/}
|
||||
{/* }*/}
|
||||
{/*>*/}
|
||||
{/* <HasKidsFilter filters={filters} updateFilter={updateFilter} />*/}
|
||||
{/*</MobileFilterSection>*/}
|
||||
<button
|
||||
className="text-ink-500 hover:text-primary-500 underline"
|
||||
onClick={clearFilters}
|
||||
|
||||
@@ -45,8 +45,8 @@ export const initialFilters: Partial<FilterFields> = {
|
||||
genders: undefined,
|
||||
pref_age_max: undefined,
|
||||
pref_age_min: undefined,
|
||||
has_kids: -1,
|
||||
wants_kids_strength: -1,
|
||||
has_kids: undefined,
|
||||
wants_kids_strength: undefined,
|
||||
is_smoker: undefined,
|
||||
pref_relation_styles: undefined,
|
||||
pref_gender: undefined,
|
||||
@@ -61,7 +61,21 @@ export const useFilters = (you: Lover | undefined) => {
|
||||
)
|
||||
|
||||
const updateFilter = (newState: Partial<FilterFields>) => {
|
||||
setFilters((prevState) => ({ ...prevState, ...newState }))
|
||||
const updatedState = { ...newState }
|
||||
|
||||
if ('pref_age_min' in updatedState && updatedState.pref_age_min !== undefined) {
|
||||
if (updatedState.pref_age_min != null && updatedState.pref_age_min <= 18) {
|
||||
updatedState.pref_age_min = undefined
|
||||
}
|
||||
}
|
||||
|
||||
if ('pref_age_max' in updatedState && updatedState.pref_age_max !== undefined) {
|
||||
if (updatedState.pref_age_max != null && updatedState.pref_age_max >= 99) {
|
||||
updatedState.pref_age_max = undefined
|
||||
}
|
||||
}
|
||||
|
||||
setFilters((prevState) => ({ ...prevState, ...updatedState }))
|
||||
}
|
||||
|
||||
const clearFilters = () => {
|
||||
@@ -110,11 +124,11 @@ export const useFilters = (you: Lover | undefined) => {
|
||||
(you?.wants_kids_strength ?? 2) as wantsKidsDatabase
|
||||
),
|
||||
}
|
||||
console.log(you, yourFilters)
|
||||
|
||||
const isYourFilters =
|
||||
!!you &&
|
||||
!!location &&
|
||||
location.id === you.geodb_city_id &&
|
||||
(!location || location.id === you.geodb_city_id) &&
|
||||
isEqual(filters.genders?.length ? filters.genders : undefined, yourFilters.genders?.length ? yourFilters.genders : undefined) &&
|
||||
// isEqual(filters.pref_gender?.length ? filters.pref_gender[0] : undefined, you.gender) &&
|
||||
// you?.pref_gender.length &&
|
||||
|
||||
@@ -29,6 +29,10 @@ export function wantsKidsToHasKidsFilter(wantsKidsStrength: wantsKidsDatabase) {
|
||||
export function wantsKidsDatabaseToWantsKidsFilter(
|
||||
wantsKidsStrength: wantsKidsDatabase
|
||||
) {
|
||||
console.log(wantsKidsStrength)
|
||||
if (wantsKidsStrength == wantsKidsLabels.no_preference.strength) {
|
||||
return wantsKidsLabels.no_preference.strength
|
||||
}
|
||||
if (wantsKidsStrength > wantsKidsLabels.wants_kids.strength) {
|
||||
return wantsKidsLabels.wants_kids.strength
|
||||
}
|
||||
|
||||
@@ -107,11 +107,11 @@ function Seeking(props: { lover: Lover }) {
|
||||
})
|
||||
|
||||
const ageRangeText =
|
||||
min == 18 && max == 99
|
||||
min == 18 && max == 100
|
||||
? 'of any age'
|
||||
: min == max
|
||||
? `exactly ${min} years old`
|
||||
: max == 99
|
||||
: max == 100
|
||||
? `${min} or older`
|
||||
: `between ${min} - ${max} years old`
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ export const OptionalLoveUserForm = (props: {
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="Age"
|
||||
value={lover['age'] > 0 ? lover['age'] : undefined}
|
||||
value={lover['age'] ?? undefined}
|
||||
min={18}
|
||||
max={100}
|
||||
onChange={(e) => setLover('age', Number(e.target.value))}
|
||||
@@ -236,12 +236,13 @@ export const OptionalLoveUserForm = (props: {
|
||||
<Col>
|
||||
<span>Min</span>
|
||||
<Select
|
||||
value={lover['pref_age_min']}
|
||||
value={lover['pref_age_min'] ?? ''}
|
||||
onChange={(e) =>
|
||||
setLover('pref_age_min', Number(e.target.value))
|
||||
}
|
||||
className={'w-18 border-ink-300 rounded-md'}
|
||||
>
|
||||
<option key={""} value={""}></option>
|
||||
{range(18, 100).map((m) => (
|
||||
<option key={m} value={m}>
|
||||
{m}
|
||||
@@ -252,12 +253,13 @@ export const OptionalLoveUserForm = (props: {
|
||||
<Col>
|
||||
<span>Max</span>
|
||||
<Select
|
||||
value={lover['pref_age_max']}
|
||||
value={lover['pref_age_max'] ?? ''}
|
||||
onChange={(e) =>
|
||||
setLover('pref_age_max', Number(e.target.value))
|
||||
}
|
||||
className={'w-18 border-ink-300 rounded-md'}
|
||||
>
|
||||
<option key={""} value={""}></option>
|
||||
{range(18, 100).map((m) => (
|
||||
<option key={m} value={m}>
|
||||
{m}
|
||||
|
||||
@@ -38,17 +38,17 @@ export function ProfilesHome() {
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||||
const [isReloading, setIsReloading] = useState(false);
|
||||
|
||||
const [debouncedAgeRange, setRawAgeRange] = useState({
|
||||
min: filters.pref_age_min ?? PREF_AGE_MIN,
|
||||
max: filters.pref_age_max ?? PREF_AGE_MAX,
|
||||
});
|
||||
|
||||
const debouncedSetAge = useCallback(debounce((state) => setRawAgeRange(state), 50), []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
debouncedSetAge({min: filters.pref_age_min ?? PREF_AGE_MIN, max: filters.pref_age_max ?? PREF_AGE_MAX});
|
||||
}, [filters.pref_age_min, filters.pref_age_max]);
|
||||
// const [debouncedAgeRange, setRawAgeRange] = useState({
|
||||
// min: filters.pref_age_min ?? PREF_AGE_MIN,
|
||||
// max: filters.pref_age_max ?? PREF_AGE_MAX,
|
||||
// });
|
||||
//
|
||||
// const debouncedSetAge = useCallback(debounce((state) => setRawAgeRange(state), 50), []);
|
||||
//
|
||||
// useEffect(() => {
|
||||
// if (!user) return;
|
||||
// debouncedSetAge({min: filters.pref_age_min ?? PREF_AGE_MIN, max: filters.pref_age_max ?? PREF_AGE_MAX});
|
||||
// }, [filters.pref_age_min, filters.pref_age_max]);
|
||||
|
||||
const id = useRef(0);
|
||||
useEffect(() => {
|
||||
@@ -66,7 +66,7 @@ export function ProfilesHome() {
|
||||
.finally(() => {
|
||||
if (current === id.current) setIsReloading(false);
|
||||
});
|
||||
}, [JSON.stringify(omit(filters, ['pref_age_min', 'pref_age_max'])), debouncedAgeRange.min, debouncedAgeRange.max]);
|
||||
}, [filters]);
|
||||
|
||||
const {data: starredUserIds, refresh: refreshStars} = useGetter('star', user?.id, getStars);
|
||||
const compatibleLovers = useCompatibleLovers(user?.id);
|
||||
|
||||
@@ -15,11 +15,11 @@ import {SignupBio} from "web/components/bio/editable-bio";
|
||||
import {JSONContent} from "@tiptap/core";
|
||||
|
||||
export const initialRequiredState = {
|
||||
age: 30,
|
||||
age: undefined,
|
||||
gender: '',
|
||||
pref_gender: [],
|
||||
pref_age_min: 18,
|
||||
pref_age_max: 100,
|
||||
pref_age_min: undefined,
|
||||
pref_age_max: undefined,
|
||||
pref_relation_styles: [],
|
||||
wants_kids_strength: -1,
|
||||
looking_for_matches: true,
|
||||
|
||||
@@ -70,7 +70,7 @@ function formatFilters(filters: Partial<FilterFields>, location: locationType |
|
||||
const entries: ReactElement[] = []
|
||||
|
||||
let ageEntry = null
|
||||
let ageMin: number | undefined = filters.pref_age_min
|
||||
let ageMin: number | undefined | null = filters.pref_age_min
|
||||
if (ageMin == 18) ageMin = undefined
|
||||
let ageMax = filters.pref_age_max;
|
||||
if (ageMax == 99 || ageMax == 100) ageMax = undefined
|
||||
|
||||
@@ -11,7 +11,7 @@ import SiteLogo from 'web/components/site-logo'
|
||||
import {useTracking} from 'web/hooks/use-tracking'
|
||||
import {track} from 'web/lib/service/analytics'
|
||||
import {safeLocalStorage} from 'web/lib/util/local'
|
||||
import {removeUndefinedProps} from 'common/util/object'
|
||||
import {removeNullOrUndefinedProps} from 'common/util/object'
|
||||
import {useLoverByUserId} from 'web/hooks/use-lover'
|
||||
import {LoverRow} from 'common/love/lover'
|
||||
import {LovePage} from "web/components/love-page";
|
||||
@@ -94,7 +94,7 @@ export default function SignupPage() {
|
||||
console.log('loverForm', loverForm)
|
||||
const lover = await api(
|
||||
'create-lover',
|
||||
removeUndefinedProps({
|
||||
removeNullOrUndefinedProps({
|
||||
...loverForm,
|
||||
referred_by_username: referredByUsername,
|
||||
}) as any
|
||||
|
||||
Reference in New Issue
Block a user