Allow null for profiles

This commit is contained in:
MartinBraquet
2025-10-27 01:23:20 +01:00
parent cdbce13c49
commit cdbc9c305e
7 changed files with 73 additions and 69 deletions

View File

@@ -89,7 +89,7 @@ export const loadProfiles = async (props: profileQueryType) => {
const profiles = compatibleProfiles.filter(
(l) =>
(!name || l.user.name.toLowerCase().includes(name.toLowerCase())) &&
(!genders || genders.includes(l.gender)) &&
(!genders || genders.includes(l.gender ?? '')) &&
(!education_levels || education_levels.includes(l.education_level ?? '')) &&
(!pref_gender || intersection(pref_gender, l.pref_gender).length) &&
(!pref_age_min || (l.age ?? MAX_INT) >= pref_age_min) &&

View File

@@ -1,6 +1,6 @@
export const removePinnedUrlFromPhotoUrls = async (parsedBody: {
pinned_url?: string
photo_urls?: string[]
photo_urls?: string[] | null
}) => {
if (parsedBody.photo_urls && parsedBody.pinned_url) {
parsedBody.photo_urls = parsedBody.photo_urls.filter(

View File

@@ -47,56 +47,56 @@ export const zBoolean = z
.transform((val) => val === true || val === "true");
export const baseProfilesSchema = z.object({
age: z.number().min(18).max(100).optional(),
age: z.number().min(18).max(100).optional().nullable(),
bio: contentSchema.optional().nullable(),
bio_length: z.number().optional().nullable(),
city: z.string(),
city_latitude: z.number().optional(),
city_longitude: z.number().optional(),
country: z.string().optional(),
city_latitude: z.number().optional().nullable(),
city_longitude: z.number().optional().nullable(),
country: z.string().optional().nullable(),
gender: genderType,
geodb_city_id: z.string().optional(),
geodb_city_id: z.string().optional().nullable(),
looking_for_matches: zBoolean,
photo_urls: z.array(z.string()),
photo_urls: z.array(z.string()).nullable(),
pinned_url: z.string(),
pref_age_max: z.number().min(18).max(100).optional(),
pref_age_min: z.number().min(18).max(100).optional(),
pref_gender: genderTypes,
pref_relation_styles: z.array(z.string()),
referred_by_username: z.string().optional(),
region_code: z.string().optional(),
pref_age_max: z.number().min(18).max(100).optional().nullable(),
pref_age_min: z.number().min(18).max(100).optional().nullable(),
pref_gender: genderTypes.nullable(),
pref_relation_styles: z.array(z.string()).nullable(),
referred_by_username: z.string().optional().nullable(),
region_code: z.string().optional().nullable(),
visibility: z.union([z.literal('public'), z.literal('member')]),
wants_kids_strength: z.number(),
wants_kids_strength: z.number().nullable(),
})
const optionalProfilesSchema = z.object({
avatar_url: z.string().optional(),
avatar_url: z.string().optional().nullable(),
bio: contentSchema.optional().nullable(),
born_in_location: z.string().optional(),
born_in_location: z.string().optional().nullable(),
comments_enabled: zBoolean.optional(),
company: z.string().optional(),
diet: z.array(z.string()).optional(),
company: z.string().optional().nullable(),
diet: z.array(z.string()).optional().nullable(),
disabled: zBoolean.optional(),
drinks_max: z.number().min(0).optional(),
drinks_min: z.number().min(0).optional(),
drinks_per_month: z.number().min(0).optional(),
education_level: z.string().optional(),
ethnicity: z.array(z.string()).optional(),
has_kids: z.number().min(0).optional(),
has_pets: zBoolean.optional(),
height_in_inches: z.number().optional(),
is_smoker: zBoolean.optional(),
occupation: z.string().optional(),
occupation_title: z.string().optional(),
political_beliefs: z.array(z.string()).optional(),
political_details: z.string().optional(),
pref_romantic_styles: z.array(z.string()),
religion: z.array(z.string()).optional(),
religious_belief_strength: z.number().optional(),
religious_beliefs: z.string().optional(),
twitter: z.string().optional(),
university: z.string().optional(),
website: z.string().optional(),
drinks_max: z.number().min(0).optional().nullable(),
drinks_min: z.number().min(0).optional().nullable(),
drinks_per_month: z.number().min(0).optional().nullable(),
education_level: z.string().optional().nullable(),
ethnicity: z.array(z.string()).optional().nullable(),
has_kids: z.number().min(0).optional().nullable(),
has_pets: zBoolean.optional().nullable(),
height_in_inches: z.number().optional().nullable(),
is_smoker: zBoolean.optional().nullable(),
occupation: z.string().optional().nullable(),
occupation_title: z.string().optional().nullable(),
political_beliefs: z.array(z.string()).optional().nullable(),
political_details: z.string().optional().nullable(),
pref_romantic_styles: z.array(z.string()).nullable(),
religion: z.array(z.string()).optional().nullable(),
religious_belief_strength: z.number().optional().nullable(),
religious_beliefs: z.string().optional().nullable(),
twitter: z.string().optional().nullable(),
university: z.string().optional().nullable(),
website: z.string().optional().nullable(),
})
export const combinedProfileSchema =

View File

@@ -2,15 +2,15 @@ import { ProfileRow } from 'common/profiles/profile'
import {MAX_INT, MIN_INT} from "common/constants";
const isPreferredGender = (
preferredGenders: string[] | undefined,
gender: string | undefined
preferredGenders: string[] | undefined | null,
gender: string | undefined | null,
) => {
// console.debug('isPreferredGender', preferredGenders, gender)
if (preferredGenders === undefined || preferredGenders.length === 0 || gender === undefined) return true
if (!preferredGenders?.length || !gender) return true
// If simple gender preference, don't include non-binary.
if (
preferredGenders.length === 1 &&
preferredGenders?.length === 1 &&
(preferredGenders[0] === 'male' || preferredGenders[0] === 'female')
) {
return preferredGenders.includes(gender)
@@ -43,13 +43,15 @@ export const areLocationCompatible = (profile1: ProfileRow, profile2: ProfileRow
!profile2.city_latitude ||
!profile1.city_longitude ||
!profile2.city_longitude
)
) {
if (!profile1.city || !profile2.city) return true
return profile1.city.trim().toLowerCase() === profile2.city.trim().toLowerCase()
}
const latitudeDiff = Math.abs(profile1.city_latitude - profile2.city_latitude)
const longigudeDiff = Math.abs(profile1.city_longitude - profile2.city_longitude)
const longitudeDiff = Math.abs(profile1.city_longitude - profile2.city_longitude)
const root = (latitudeDiff ** 2 + longigudeDiff ** 2) ** 0.5
const root = (latitudeDiff ** 2 + longitudeDiff ** 2) ** 0.5
return root < 2.5
}
@@ -57,8 +59,9 @@ export const areRelationshipStyleCompatible = (
profile1: ProfileRow,
profile2: ProfileRow
) => {
if (!profile1.pref_relation_styles?.length || !profile2.pref_relation_styles) return true
return profile1.pref_relation_styles.some((style) =>
profile2.pref_relation_styles.includes(style)
profile2.pref_relation_styles?.includes(style)
)
}
@@ -66,7 +69,7 @@ export const areWantKidsCompatible = (profile1: ProfileRow, profile2: ProfileRow
const { wants_kids_strength: kids1 } = profile1
const { wants_kids_strength: kids2 } = profile2
if (kids1 === undefined || kids2 === undefined) return true
if (kids1 == null || kids2 == null) return true
const diff = Math.abs(kids1 - kids2)
return diff <= 2

View File

@@ -533,7 +533,7 @@ export type Database = {
bio_text: string | null
bio_tsv: unknown
born_in_location: string | null
city: string
city: string | null
city_latitude: number | null
city_longitude: number | null
comments_enabled: boolean
@@ -545,7 +545,7 @@ export type Database = {
drinks_per_month: number | null
education_level: string | null
ethnicity: string[] | null
gender: string
gender: string | null
geodb_city_id: string | null
has_kids: number | null
height_in_inches: number | null
@@ -562,8 +562,8 @@ export type Database = {
political_details: string | null
pref_age_max: number | null
pref_age_min: number | null
pref_gender: string[]
pref_relation_styles: string[]
pref_gender: string[] | null
pref_relation_styles: string[] | null
pref_romantic_styles: string[] | null
referred_by_username: string | null
region_code: string | null
@@ -574,7 +574,7 @@ export type Database = {
university: string | null
user_id: string
visibility: Database['public']['Enums']['lover_visibility']
wants_kids_strength: number
wants_kids_strength: number | null
website: string | null
}
Insert: {
@@ -584,7 +584,7 @@ export type Database = {
bio_text?: string | null
bio_tsv?: unknown
born_in_location?: string | null
city: string
city?: string | null
city_latitude?: number | null
city_longitude?: number | null
comments_enabled?: boolean
@@ -596,7 +596,7 @@ export type Database = {
drinks_per_month?: number | null
education_level?: string | null
ethnicity?: string[] | null
gender: string
gender?: string | null
geodb_city_id?: string | null
has_kids?: number | null
height_in_inches?: number | null
@@ -613,8 +613,8 @@ export type Database = {
political_details?: string | null
pref_age_max?: number | null
pref_age_min?: number | null
pref_gender: string[]
pref_relation_styles: string[]
pref_gender?: string[] | null
pref_relation_styles?: string[] | null
pref_romantic_styles?: string[] | null
referred_by_username?: string | null
region_code?: string | null
@@ -625,7 +625,7 @@ export type Database = {
university?: string | null
user_id: string
visibility?: Database['public']['Enums']['lover_visibility']
wants_kids_strength?: number
wants_kids_strength?: number | null
website?: string | null
}
Update: {
@@ -635,7 +635,7 @@ export type Database = {
bio_text?: string | null
bio_tsv?: unknown
born_in_location?: string | null
city?: string
city?: string | null
city_latitude?: number | null
city_longitude?: number | null
comments_enabled?: boolean
@@ -647,7 +647,7 @@ export type Database = {
drinks_per_month?: number | null
education_level?: string | null
ethnicity?: string[] | null
gender?: string
gender?: string | null
geodb_city_id?: string | null
has_kids?: number | null
height_in_inches?: number | null
@@ -664,8 +664,8 @@ export type Database = {
political_details?: string | null
pref_age_max?: number | null
pref_age_min?: number | null
pref_gender?: string[]
pref_relation_styles?: string[]
pref_gender?: string[] | null
pref_relation_styles?: string[] | null
pref_romantic_styles?: string[] | null
referred_by_username?: string | null
region_code?: string | null
@@ -676,7 +676,7 @@ export type Database = {
university?: string | null
user_id?: string
visibility?: Database['public']['Enums']['lover_visibility']
wants_kids_strength?: number
wants_kids_strength?: number | null
website?: string | null
}
Relationships: [

View File

@@ -17,7 +17,7 @@ import {Races} from './race'
import {Carousel} from 'web/components/widgets/carousel'
import {tryCatch} from 'common/util/try-catch'
import {ProfileRow} from 'common/profiles/profile'
import {removeNullOrUndefinedProps} from 'common/util/object'
import {removeUndefinedProps} from 'common/util/object'
import {isEqual, range} from 'lodash'
import {PlatformSelect} from 'web/components/widgets/platform-select'
import {PLATFORM_LABELS, type Site, SITE_ORDER} from 'common/socials'
@@ -32,7 +32,8 @@ import {
DIET_CHOICES,
EDUCATION_CHOICES,
POLITICAL_CHOICES,
RELATIONSHIP_CHOICES, RELIGION_CHOICES,
RELATIONSHIP_CHOICES,
RELIGION_CHOICES,
ROMANTIC_CHOICES
} from "web/components/filters/choices";
import toast from "react-hot-toast";
@@ -70,10 +71,10 @@ export const OptionalProfileUserForm = (props: {
const handleSubmit = async () => {
setIsSubmitting(true)
const {bio: _, ...otherProfileProps} = profile
console.debug('otherProfileProps', removeNullOrUndefinedProps(otherProfileProps))
const {bio: _bio, bio_text: _bio_text, bio_tsv: _bio_tsv, bio_length: _bio_length, ...otherProfileProps} = profile
console.debug('otherProfileProps', removeUndefinedProps(otherProfileProps))
const {error} = await tryCatch(
updateProfile(removeNullOrUndefinedProps(otherProfileProps) as any)
updateProfile(removeUndefinedProps(otherProfileProps) as any)
)
if (error) {
console.error(error)

View File

@@ -55,9 +55,9 @@ export default function ProfileHeader(props: {
return (
<Col className="w-full">
<Row className={clsx('flex-wrap justify-between gap-2 py-1')}>
{currentUser && isCurrentUser && disabled && <div className="text-red-500">You disabled your profile, so no one else can access it.</div>}
<Row className="items-center gap-1">
<Col className="gap-1">
{currentUser && isCurrentUser && disabled && <div className="text-red-500">You disabled your profile, so no one else can access it.</div>}
<Row className="items-center gap-1 text-xl">
{!isCurrentUser && <OnlineIcon last_online_time={userActivity?.last_online_time}/>}
<span>