mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-19 14:29:21 -04:00
Add bookmarked search emails and factor out utils from web to common
This commit is contained in:
@@ -57,7 +57,6 @@ export const API = (_apiTypeCheck = {
|
||||
props: z.object({}),
|
||||
returns: {} as {
|
||||
status: 'success' | 'fail'
|
||||
lovers: Lover[]
|
||||
},
|
||||
},
|
||||
'mark-all-notifs-read': {
|
||||
|
||||
52
common/src/filters.ts
Normal file
52
common/src/filters.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import {Lover, LoverRow} from "common/love/lover";
|
||||
import {cloneDeep} from "lodash";
|
||||
import {filterDefined} from "common/util/array";
|
||||
|
||||
export type FilterFields = {
|
||||
orderBy: 'last_online_time' | 'created_time' | 'compatibility_score'
|
||||
geodbCityIds: string[] | null
|
||||
genders: string[]
|
||||
name: string | undefined
|
||||
} & Pick<
|
||||
LoverRow,
|
||||
| 'wants_kids_strength'
|
||||
| 'pref_relation_styles'
|
||||
| 'is_smoker'
|
||||
| 'has_kids'
|
||||
| 'pref_gender'
|
||||
| 'pref_age_min'
|
||||
| 'pref_age_max'
|
||||
>
|
||||
export const orderLovers = (
|
||||
lovers: Lover[],
|
||||
starredUserIds: string[] | undefined
|
||||
) => {
|
||||
if (!lovers) return
|
||||
|
||||
let s = cloneDeep(lovers)
|
||||
|
||||
if (starredUserIds) {
|
||||
s = filterDefined([
|
||||
...starredUserIds.map((id) => s.find((l) => l.user_id === id)),
|
||||
...s.filter((l) => !starredUserIds.includes(l.user_id)),
|
||||
])
|
||||
}
|
||||
|
||||
// s = alternateWomenAndMen(s)
|
||||
|
||||
return s
|
||||
}
|
||||
export const initialFilters: Partial<FilterFields> = {
|
||||
geodbCityIds: undefined,
|
||||
name: undefined,
|
||||
genders: undefined,
|
||||
pref_age_max: undefined,
|
||||
pref_age_min: undefined,
|
||||
has_kids: undefined,
|
||||
wants_kids_strength: undefined,
|
||||
is_smoker: undefined,
|
||||
pref_relation_styles: undefined,
|
||||
pref_gender: undefined,
|
||||
orderBy: 'created_time',
|
||||
}
|
||||
export type OriginLocation = { id: string; name: string }
|
||||
51
common/src/has-kids.ts
Normal file
51
common/src/has-kids.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
export interface HasKidLabel {
|
||||
name: string
|
||||
shortName: string
|
||||
value: number
|
||||
}
|
||||
|
||||
export interface HasKidsLabelsMap {
|
||||
[key: string]: HasKidLabel
|
||||
}
|
||||
|
||||
export const hasKidsLabels: HasKidsLabelsMap = {
|
||||
no_preference: {
|
||||
name: 'Any kids',
|
||||
shortName: 'Any kids',
|
||||
value: -1,
|
||||
},
|
||||
has_kids: {
|
||||
name: 'Has kids',
|
||||
shortName: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
doesnt_have_kids: {
|
||||
name: `Doesn't have kids`,
|
||||
shortName: 'No',
|
||||
value: 0,
|
||||
},
|
||||
}
|
||||
export const hasKidsNames = Object.values(hasKidsLabels).reduce<Record<number, string>>(
|
||||
(acc, {value, name}) => {
|
||||
acc[value] = name
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
|
||||
export const generateChoicesMap = (
|
||||
labels: HasKidsLabelsMap
|
||||
): Record<string, number> => {
|
||||
return Object.values(labels).reduce(
|
||||
(acc: Record<string, number>, label: HasKidLabel) => {
|
||||
acc[label.shortName] = label.value
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
// export const NO_PREFERENCE_STRENGTH = -1
|
||||
// export const WANTS_KIDS_STRENGTH = 2
|
||||
// export const DOESNT_WANT_KIDS_STRENGTH = 0
|
||||
26
common/src/love/bookmarked_searches.ts
Normal file
26
common/src/love/bookmarked_searches.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface MatchPrivateUser {
|
||||
email: string
|
||||
notificationPreferences: any
|
||||
}
|
||||
|
||||
export interface MatchUser {
|
||||
name: string
|
||||
username: string
|
||||
}
|
||||
|
||||
export interface MatchesType {
|
||||
description: {
|
||||
filters: any; // You might want to replace 'any' with a more specific type
|
||||
location: any; // You might want to replace 'any' with a more specific type
|
||||
};
|
||||
matches: any[]; // You might want to replace 'any' with a more specific type
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface MatchesByUserType {
|
||||
[key: string]: {
|
||||
user: any;
|
||||
privateUser: any;
|
||||
matches: MatchesType[];
|
||||
}
|
||||
}
|
||||
87
common/src/searches.ts
Normal file
87
common/src/searches.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
// Define nice labels for each key
|
||||
import {FilterFields, initialFilters} from "common/filters";
|
||||
import {wantsKidsNames} from "common/wants-kids";
|
||||
import {hasKidsNames} from "common/has-kids";
|
||||
|
||||
const filterLabels: Record<string, string> = {
|
||||
geodbCityIds: "",
|
||||
location: "",
|
||||
name: "Searching",
|
||||
genders: "",
|
||||
pref_age_max: "Max age",
|
||||
pref_age_min: "Min age",
|
||||
has_kids: "",
|
||||
wants_kids_strength: "Kids",
|
||||
is_smoker: "",
|
||||
pref_relation_styles: "Seeking",
|
||||
pref_gender: "",
|
||||
orderBy: "",
|
||||
}
|
||||
|
||||
export type locationType = {
|
||||
location: {
|
||||
name: string
|
||||
}
|
||||
radius: number
|
||||
}
|
||||
|
||||
|
||||
export function formatFilters(filters: Partial<FilterFields>, location: locationType | null): String[] | null {
|
||||
const entries: String[] = []
|
||||
|
||||
let ageEntry = null
|
||||
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
|
||||
if (ageMin || ageMax) {
|
||||
let text: string = 'Age: '
|
||||
if (ageMin) text = `${text}${ageMin}`
|
||||
if (ageMax) {
|
||||
if (ageMin) {
|
||||
text = `${text}-${ageMax}`
|
||||
} else {
|
||||
text = `${text}up to ${ageMax}`
|
||||
}
|
||||
} else {
|
||||
text = `${text}+`
|
||||
}
|
||||
ageEntry = text
|
||||
}
|
||||
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
const typedKey = key as keyof FilterFields
|
||||
|
||||
if (value === undefined || value === null) return
|
||||
if (typedKey == 'pref_age_min' || typedKey == 'pref_age_max' || typedKey == 'geodbCityIds' || typedKey == 'orderBy') return
|
||||
if (Array.isArray(value) && value.length === 0) return
|
||||
if (initialFilters[typedKey] === value) return
|
||||
|
||||
const label = filterLabels[typedKey] ?? key
|
||||
|
||||
let stringValue = value
|
||||
if (key === 'has_kids') stringValue = hasKidsNames[value as number]
|
||||
if (key === 'wants_kids_strength') stringValue = wantsKidsNames[value as number]
|
||||
if (Array.isArray(value)) stringValue = value.join(', ')
|
||||
|
||||
if (!label) {
|
||||
const str = String(stringValue)
|
||||
stringValue = str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
const display = stringValue
|
||||
|
||||
entries.push(`${label}${label ? ': ' : ''}${display}`)
|
||||
})
|
||||
|
||||
if (ageEntry) entries.push(ageEntry)
|
||||
|
||||
if (location?.location?.name) {
|
||||
const locString = `${location?.location?.name} (${location?.radius}mi)`
|
||||
entries.push(locString)
|
||||
}
|
||||
|
||||
if (entries.length === 0) return ['Anyone']
|
||||
|
||||
return entries
|
||||
}
|
||||
@@ -8,6 +8,7 @@ export type notification_preferences = {
|
||||
new_endorsement: notification_destination_types[]
|
||||
new_love_like: notification_destination_types[]
|
||||
new_love_ship: notification_destination_types[]
|
||||
new_search_alerts: notification_destination_types[]
|
||||
|
||||
// User-related
|
||||
new_message: notification_destination_types[]
|
||||
@@ -37,6 +38,7 @@ export const getDefaultNotificationPreferences = (isDev?: boolean) => {
|
||||
}
|
||||
const defaults: notification_preferences = {
|
||||
new_match: constructPref(true, true, true),
|
||||
new_search_alerts: constructPref(true, true, true),
|
||||
new_endorsement: constructPref(true, true, true),
|
||||
new_love_like: constructPref(true, false, false),
|
||||
new_love_ship: constructPref(true, false, false),
|
||||
@@ -59,8 +61,10 @@ export const getNotificationDestinationsForUser = (
|
||||
privateUser: PrivateUser,
|
||||
type: notification_preference
|
||||
) => {
|
||||
const destinations = privateUser.notificationPreferences[type]
|
||||
const opt_out = privateUser.notificationPreferences.opt_out_all
|
||||
let destinations = privateUser.notificationPreferences[type]
|
||||
if (!destinations) destinations = ['email', 'browser', 'mobile']
|
||||
let opt_out = privateUser.notificationPreferences.opt_out_all
|
||||
if (!opt_out) opt_out = []
|
||||
|
||||
return {
|
||||
sendToEmail: destinations.includes('email') && !opt_out.includes('email'),
|
||||
|
||||
68
common/src/wants-kids.ts
Normal file
68
common/src/wants-kids.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import {hasKidsLabels} from "common/has-kids";
|
||||
|
||||
export type KidLabel = {
|
||||
name: string
|
||||
shortName: string
|
||||
strength: number
|
||||
}
|
||||
|
||||
export type KidsLabelsMap = Record<string, KidLabel>
|
||||
|
||||
export const wantsKidsLabels: KidsLabelsMap = {
|
||||
no_preference: {
|
||||
name: 'Any preference',
|
||||
shortName: 'Either',
|
||||
strength: -1,
|
||||
},
|
||||
wants_kids: {
|
||||
name: 'Wants kids',
|
||||
shortName: 'Yes',
|
||||
strength: 2,
|
||||
},
|
||||
doesnt_want_kids: {
|
||||
name: `Doesn't want kids`,
|
||||
shortName: 'No',
|
||||
strength: 0,
|
||||
},
|
||||
}
|
||||
export const wantsKidsNames = Object.values(wantsKidsLabels).reduce<Record<number, string>>(
|
||||
(acc, {strength, name}) => {
|
||||
acc[strength] = name
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
export type wantsKidsDatabase = 0 | 1 | 2 | 3 | 4
|
||||
|
||||
export function wantsKidsToHasKidsFilter(wantsKidsStrength: wantsKidsDatabase) {
|
||||
if (wantsKidsStrength < wantsKidsLabels.wants_kids.strength) {
|
||||
return hasKidsLabels.doesnt_have_kids.value
|
||||
}
|
||||
return hasKidsLabels.no_preference.value
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if (wantsKidsStrength < wantsKidsLabels.wants_kids.strength) {
|
||||
return wantsKidsLabels.doesnt_want_kids.strength
|
||||
}
|
||||
return wantsKidsLabels.no_preference.strength
|
||||
}
|
||||
|
||||
export const generateChoicesMap = (labels: KidsLabelsMap): Record<string, number> => {
|
||||
return Object.values(labels).reduce(
|
||||
(acc: Record<string, number>, label: KidLabel) => {
|
||||
acc[label.shortName] = label.strength
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user