diff --git a/backend/api/src/get-profiles.ts b/backend/api/src/get-profiles.ts index 1b48d57..59bb863 100644 --- a/backend/api/src/get-profiles.ts +++ b/backend/api/src/get-profiles.ts @@ -16,6 +16,7 @@ export type profileQueryType = { pref_age_min?: number | undefined, pref_age_max?: number | undefined, pref_relation_styles?: String[] | undefined, + pref_romantic_styles?: String[] | undefined, wants_kids_strength?: number | undefined, has_kids?: number | undefined, is_smoker?: boolean | undefined, @@ -42,6 +43,7 @@ export const loadProfiles = async (props: profileQueryType) => { pref_age_min, pref_age_max, pref_relation_styles, + pref_romantic_styles, wants_kids_strength, has_kids, is_smoker, @@ -73,6 +75,8 @@ export const loadProfiles = async (props: profileQueryType) => { (!pref_age_max || (l.age ?? MIN_INT) <= pref_age_max) && (!pref_relation_styles || intersection(pref_relation_styles, l.pref_relation_styles).length) && + (!pref_romantic_styles || + intersection(pref_romantic_styles, l.pref_romantic_styles).length) && (!wants_kids_strength || wants_kids_strength == -1 || (wants_kids_strength >= 2 @@ -136,6 +140,12 @@ export const loadProfiles = async (props: profileQueryType) => { { pref_relation_styles } ), + pref_romantic_styles?.length && + where( + `pref_romantic_styles IS NULL OR pref_romantic_styles = '{}' OR pref_romantic_styles && $(pref_romantic_styles)`, + { pref_romantic_styles } + ), + !!wants_kids_strength && wants_kids_strength !== -1 && where( diff --git a/backend/email/emails/functions/mock.ts b/backend/email/emails/functions/mock.ts index 6c417c3..36ef0d6 100644 --- a/backend/email/emails/functions/mock.ts +++ b/backend/email/emails/functions/mock.ts @@ -37,7 +37,8 @@ export const sinclairProfile: ProfileRow = { pref_gender: ['female', 'trans-female'], pref_age_min: 18, pref_age_max: 21, - pref_relation_styles: ['poly', 'open', 'mono'], + pref_relation_styles: ['friendship'], + pref_romantic_styles: ['poly', 'open', 'mono'], wants_kids_strength: 3, looking_for_matches: true, visibility: 'public', @@ -137,7 +138,8 @@ export const jamesProfile: ProfileRow = { pref_gender: ['female'], pref_age_min: 22, pref_age_max: 32, - pref_relation_styles: ['mono'], + pref_relation_styles: ['friendship'], + pref_romantic_styles: ['poly', 'open', 'mono'], wants_kids_strength: 4, looking_for_matches: true, visibility: 'public', diff --git a/backend/supabase/profiles.sql b/backend/supabase/profiles.sql index 21ca6b2..e144c5f 100644 --- a/backend/supabase/profiles.sql +++ b/backend/supabase/profiles.sql @@ -40,6 +40,7 @@ CREATE TABLE IF NOT EXISTS profiles ( pref_age_min INTEGER NULL, pref_gender TEXT[] NOT NULL, pref_relation_styles TEXT[] NOT NULL, + pref_romantic_styles TEXT[], referred_by_username TEXT, region_code TEXT, religious_belief_strength INTEGER, diff --git a/common/src/api/schema.ts b/common/src/api/schema.ts index a346adb..39e9b66 100644 --- a/common/src/api/schema.ts +++ b/common/src/api/schema.ts @@ -349,6 +349,7 @@ export const API = (_apiTypeCheck = { pref_age_min: z.coerce.number().optional(), pref_age_max: z.coerce.number().optional(), pref_relation_styles: arraybeSchema.optional(), + pref_romantic_styles: 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/api/zod-types.ts b/common/src/api/zod-types.ts index cc0f32b..1d713ec 100644 --- a/common/src/api/zod-types.ts +++ b/common/src/api/zod-types.ts @@ -49,13 +49,8 @@ export const baseProfilesSchema = z.object({ pref_gender: genderTypes, 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'), - z.literal('friendship'), - z.literal('relationship'), - ]) - ), + pref_relation_styles: z.array(z.string()), + pref_romantic_styles: z.array(z.string()), wants_kids_strength: z.number(), looking_for_matches: z.boolean(), photo_urls: z.array(z.string()), diff --git a/common/src/supabase/schema.ts b/common/src/supabase/schema.ts index 8989c8f..57be193 100644 --- a/common/src/supabase/schema.ts +++ b/common/src/supabase/schema.ts @@ -438,6 +438,7 @@ export type Database = { pref_age_min: number | null pref_gender: string[] pref_relation_styles: string[] + pref_romantic_styles: string[] | null referred_by_username: string | null region_code: string | null religious_belief_strength: number | null @@ -485,6 +486,7 @@ export type Database = { pref_age_min?: number | null pref_gender: string[] pref_relation_styles: string[] + pref_romantic_styles?: string[] | null referred_by_username?: string | null region_code?: string | null religious_belief_strength?: number | null @@ -532,6 +534,7 @@ export type Database = { pref_age_min?: number | null pref_gender?: string[] pref_relation_styles?: string[] + pref_romantic_styles?: string[] | null referred_by_username?: string | null region_code?: string | null religious_belief_strength?: number | null diff --git a/web/components/filters/choices.tsx b/web/components/filters/choices.tsx index fc67809..6aa3b7f 100644 --- a/web/components/filters/choices.tsx +++ b/web/components/filters/choices.tsx @@ -1,13 +1,20 @@ export const RELATIONSHIP_CHOICES = { - // Monogamous: 'mono', - // Polyamorous: 'poly', - // 'Open Relationship': 'open', // Other: 'other', Collaboration: 'collaboration', Friendship: 'friendship', Relationship: 'relationship', }; +export const ROMANTIC_CHOICES = { + Monogamous: 'mono', + Polyamorous: 'poly', + 'Open Relationship': 'open', +}; + export const REVERTED_RELATIONSHIP_CHOICES = Object.fromEntries( Object.entries(RELATIONSHIP_CHOICES).map(([key, value]) => [value, key]) +); + +export const REVERTED_ROMANTIC_CHOICES = Object.fromEntries( + Object.entries(ROMANTIC_CHOICES).map(([key, value]) => [value, key]) ); \ No newline at end of file diff --git a/web/components/optional-profile-form.tsx b/web/components/optional-profile-form.tsx index 11376c6..83011a5 100644 --- a/web/components/optional-profile-form.tsx +++ b/web/components/optional-profile-form.tsx @@ -28,7 +28,7 @@ import {City, CityRow, profileToCity, useCitySearch} from "web/components/search import {AddPhotosWidget} from './widgets/add-photos' import {RadioToggleGroup} from "web/components/widgets/radio-toggle-group"; import {MultipleChoiceOptions} from "common/love/multiple-choice"; -import {RELATIONSHIP_CHOICES} from "web/components/filters/choices"; +import {RELATIONSHIP_CHOICES, ROMANTIC_CHOICES} from "web/components/filters/choices"; import toast from "react-hot-toast"; export const OptionalLoveUserForm = (props: { @@ -42,7 +42,7 @@ export const OptionalLoveUserForm = (props: { const {profile, user, buttonLabel, setProfile, fromSignup, onSubmit} = props const [isSubmitting, setIsSubmitting] = useState(false) - const [lookingRelationship, setLookingRelationship] = useState(false) + const [lookingRelationship, setLookingRelationship] = useState((profile.pref_relation_styles || []).includes('relationship')) const router = useRouter() const [heightFeet, setHeightFeet] = useState( profile.height_in_inches @@ -554,6 +554,17 @@ export const OptionalLoveUserForm = (props: { currentChoice={profile.wants_kids_strength ?? -1} /> + + + + { + setProfile('pref_romantic_styles', selected) + }} + /> + } diff --git a/web/components/profile-about.tsx b/web/components/profile-about.tsx index 7ea4128..89e7f23 100644 --- a/web/components/profile-about.tsx +++ b/web/components/profile-about.tsx @@ -2,6 +2,7 @@ import clsx from 'clsx' import {convertRelationshipType, type RelationshipType,} from 'web/lib/util/convert-relationship-type' import stringOrStringArrayToText from 'web/lib/util/string-or-string-array-to-text' import {ReactNode} from 'react' +import {REVERTED_ROMANTIC_CHOICES} from 'web/components/filters/choices' import {BiSolidDrink} from 'react-icons/bi' import {BsPersonHeart} from 'react-icons/bs' import {FaChild} from 'react-icons/fa6' @@ -126,7 +127,7 @@ function Seeking(props: { profile: Profile }) { function RelationshipType(props: { profile: Profile }) { const {profile} = props const relationshipTypes = profile.pref_relation_styles - const seekingGenderText = stringOrStringArrayToText({ + let seekingGenderText = stringOrStringArrayToText({ text: relationshipTypes.map((rel) => convertRelationshipType(rel as RelationshipType).toLowerCase() ).sort(), @@ -138,6 +139,15 @@ function RelationshipType(props: { profile: Profile }) { asSentence: true, capitalizeFirstLetterOption: false, }) + if (relationshipTypes.includes('relationship')) { + const romanticStyles = profile.pref_romantic_styles + ?.map((style) => REVERTED_ROMANTIC_CHOICES[style].toLowerCase()) + .filter(Boolean) + if (romanticStyles && romanticStyles.length > 0) { + seekingGenderText += ` (${romanticStyles.join(', ')})` + } + + } return ( }