mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-24 17:41:27 -04:00
Add profile filter: has photos
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import * as Sentry from '@sentry/node'
|
||||
import {type APIHandler} from 'api/helpers/endpoint'
|
||||
import {debug} from 'common/logger'
|
||||
import {OptionTableKey} from 'common/profiles/constants'
|
||||
import {compact} from 'lodash'
|
||||
import {convertRow} from 'shared/profiles/supabase'
|
||||
@@ -34,6 +33,8 @@ export type profileQueryType = {
|
||||
name?: string | undefined
|
||||
/** Filter by gender identity */
|
||||
genders?: string[] | undefined
|
||||
/** Filter for profiles with photos */
|
||||
hasPhoto?: boolean | undefined
|
||||
/** Filter by education level */
|
||||
education_levels?: string[] | undefined
|
||||
/** Filter by preferred gender for matches */
|
||||
@@ -89,13 +90,14 @@ export type profileQueryType = {
|
||||
|
||||
export const loadProfiles = async (props: profileQueryType) => {
|
||||
const pg = createSupabaseDirectClient()
|
||||
debug('loadProfiles', props)
|
||||
console.debug('get-profiles', props)
|
||||
const {
|
||||
limit: limitParam,
|
||||
after,
|
||||
name,
|
||||
userId,
|
||||
genders,
|
||||
hasPhoto,
|
||||
education_levels,
|
||||
pref_gender,
|
||||
pref_age_min,
|
||||
@@ -429,6 +431,8 @@ export const loadProfiles = async (props: profileQueryType) => {
|
||||
`,
|
||||
),
|
||||
|
||||
hasPhoto && where("pinned_url IS NOT NULL AND pinned_url != ''"),
|
||||
|
||||
lastModificationWithin &&
|
||||
where(`last_modification_time >= NOW() - INTERVAL $(lastModificationWithin)`, {
|
||||
lastModificationWithin,
|
||||
|
||||
@@ -359,10 +359,16 @@
|
||||
"filter.last_active.3days": "Letzte 3 Tage",
|
||||
"filter.last_active.week": "Letzte Woche",
|
||||
"filter.last_active.month": "Letzter Monat",
|
||||
"filter.last_active.now": "Jetzt online",
|
||||
"filter.last_active.3months": "Letzte 3 Monate",
|
||||
"filter.reset": "Zurücksetzen",
|
||||
"filter.short_bio_toggle": "Kurze Bios einschließen",
|
||||
"filter.show_photos": "Profilfotos anzeigen",
|
||||
"filter.has_photo": "Hat Foto",
|
||||
"filter.has_photo.title": "Hat Foto",
|
||||
"filter.has_photo.on": "Ja",
|
||||
"filter.has_photo.off": "Nein",
|
||||
"filter.has_photo.photos": "Fotos",
|
||||
"filter.wants_kids.any_preference": "Alle Präferenzen",
|
||||
"filter.wants_kids.doesnt_want_kids": "Möchte keine Kinder",
|
||||
"filter.wants_kids.either": "Egal",
|
||||
@@ -966,6 +972,7 @@
|
||||
"filter.group.values": "Werte & Überzeugungen",
|
||||
"filter.group.personality": "Persönlichkeit",
|
||||
"filter.group.advanced": "Erweitert",
|
||||
"filter.group.rendering": "Darstellung",
|
||||
"referrals.title": "Lade jemanden ein, Compass beizutreten!",
|
||||
"register.agreement.and": " und ",
|
||||
"register.agreement.prefix": "Mit der Registrierung akzeptiere ich die ",
|
||||
|
||||
@@ -359,10 +359,16 @@
|
||||
"filter.last_active.3days": "3 derniers jours",
|
||||
"filter.last_active.week": "Dernière semaine",
|
||||
"filter.last_active.month": "Dernier mois",
|
||||
"filter.last_active.now": "En ligne",
|
||||
"filter.last_active.3months": "3 derniers mois",
|
||||
"filter.reset": "Réinitialiser",
|
||||
"filter.short_bio_toggle": "Inclure les profils incomplets",
|
||||
"filter.show_photos": "Afficher les photos",
|
||||
"filter.has_photo": "A des photos",
|
||||
"filter.has_photo.title": "A des photos",
|
||||
"filter.has_photo.on": "Oui",
|
||||
"filter.has_photo.off": "Non",
|
||||
"filter.has_photo.photos": "Photos",
|
||||
"filter.wants_kids.any_preference": "N'importe",
|
||||
"filter.wants_kids.doesnt_want_kids": "Ne veut pas d'enfants",
|
||||
"filter.wants_kids.either": "N'importe",
|
||||
@@ -965,6 +971,7 @@
|
||||
"filter.group.values": "Valeurs & Croyances",
|
||||
"filter.group.personality": "Personnalité",
|
||||
"filter.group.advanced": "Avancé",
|
||||
"filter.group.rendering": "Rendu",
|
||||
"referrals.title": "Invitez quelqu'un à rejoindre Compass !",
|
||||
"register.agreement.and": " et ",
|
||||
"register.agreement.prefix": "En vous inscrivant, j'accepte les ",
|
||||
|
||||
@@ -761,6 +761,7 @@ export const API = (_apiTypeCheck = {
|
||||
has_kids: z.coerce.number().optional(),
|
||||
is_smoker: zBoolean.optional().optional(),
|
||||
shortBio: zBoolean.optional().optional(),
|
||||
hasPhoto: zBoolean.optional().optional(),
|
||||
geodbCityIds: arraybeSchema.optional(),
|
||||
lat: z.coerce.number().optional(),
|
||||
lon: z.coerce.number().optional(),
|
||||
|
||||
@@ -37,6 +37,7 @@ const filterLabels: Record<string, string> = {
|
||||
work: '',
|
||||
religion: '',
|
||||
orderBy: '',
|
||||
hasPhoto: '',
|
||||
diet: 'Diet',
|
||||
political_beliefs: 'Political views',
|
||||
languages: '',
|
||||
@@ -148,6 +149,8 @@ export function formatFilters(
|
||||
`filter.last_active.${value}`,
|
||||
LAST_ONLINE_CHOICES[value as keyof typeof LAST_ONLINE_CHOICES] ?? value,
|
||||
)
|
||||
else if (key === 'hasPhoto')
|
||||
stringValue = value && translate('filter.has_photo.title', 'Has photos')
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (choicesIdsToLabels[key]) {
|
||||
|
||||
@@ -18,6 +18,7 @@ export type FilterFields = {
|
||||
mbti: string[] | null | undefined
|
||||
name: string | null | undefined
|
||||
shortBio: boolean | null | undefined
|
||||
hasPhoto: boolean | null | undefined
|
||||
drinks_min: number | null | undefined
|
||||
drinks_max: number | null | undefined
|
||||
// Big Five personality filters (0-100 range)
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from 'web/components/filters/big5-filter'
|
||||
import {DietFilter, DietFilterText} from 'web/components/filters/diet-filter'
|
||||
import {EducationFilter, EducationFilterText} from 'web/components/filters/education-filter'
|
||||
import {HasPhotoFilter} from 'web/components/filters/has-photo-filter'
|
||||
import {InterestFilter, InterestFilterText} from 'web/components/filters/interest-filter'
|
||||
import {LanguageFilter, LanguageFilterText} from 'web/components/filters/language-filter'
|
||||
import {MbtiFilter, MbtiFilterText} from 'web/components/filters/mbti-filter'
|
||||
@@ -253,14 +254,6 @@ function Filters(props: {
|
||||
<ShortBioToggle updateFilter={updateFilter} filters={filters} hidden={false} />
|
||||
</Col>
|
||||
|
||||
{/* Show Photos */}
|
||||
<Col className="p-4 pt-0">
|
||||
<ShowPhotosToggle
|
||||
updateRenderingOptions={updateRenderingOptions}
|
||||
renderingOptions={renderingOptions}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
{/* ALWAYS VISIBLE FILTERS */}
|
||||
|
||||
{/* CONNECTION - Always visible */}
|
||||
@@ -731,6 +724,38 @@ function Filters(props: {
|
||||
>
|
||||
<LastActiveFilter filters={filters} updateFilter={updateFilter} />
|
||||
</FilterSection>
|
||||
|
||||
{/* HAS PHOTO */}
|
||||
<FilterSection
|
||||
title={t('filter.has_photo.title', 'Has photos')}
|
||||
openFilter={openFilter}
|
||||
setOpenFilter={setOpenFilter}
|
||||
isActive={!!filters.hasPhoto}
|
||||
selection={
|
||||
<span className={clsx(!filters.hasPhoto ? 'text-ink-900' : 'text-primary-600')}>
|
||||
{filters.hasPhoto
|
||||
? t('filter.has_photo', 'Has photos')
|
||||
: t('filter.has_photo.photos', 'Photos')}
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<HasPhotoFilter filters={filters} updateFilter={updateFilter} />
|
||||
</FilterSection>
|
||||
</FilterGroup>
|
||||
|
||||
{/* Rendering */}
|
||||
<FilterGroup
|
||||
title={t('filter.group.rendering', 'Rendering')}
|
||||
openGroup={openGroup}
|
||||
setOpenGroup={setOpenGroup}
|
||||
>
|
||||
{/* Show Photos */}
|
||||
<Col className="p-4 pt-0">
|
||||
<ShowPhotosToggle
|
||||
updateRenderingOptions={updateRenderingOptions}
|
||||
renderingOptions={renderingOptions}
|
||||
/>
|
||||
</Col>
|
||||
</FilterGroup>
|
||||
</Col>
|
||||
)
|
||||
|
||||
32
web/components/filters/has-photo-filter.tsx
Normal file
32
web/components/filters/has-photo-filter.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import clsx from 'clsx'
|
||||
import {FilterFields} from 'common/filters'
|
||||
import {Row} from 'web/components/layout/row'
|
||||
import {useT} from 'web/lib/locale'
|
||||
|
||||
export function HasPhotoFilter(props: {
|
||||
filters: Partial<FilterFields>
|
||||
updateFilter: (newState: Partial<FilterFields>) => void
|
||||
}) {
|
||||
const {filters, updateFilter} = props
|
||||
const t = useT()
|
||||
|
||||
const label = t('filter.has_photo', 'Has photos')
|
||||
const on = filters.hasPhoto ?? false
|
||||
|
||||
return (
|
||||
<Row className={clsx('mx-2 items-center hover-bold', on && 'font-semibold')}>
|
||||
<input
|
||||
id={label}
|
||||
type="checkbox"
|
||||
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded hover:bg-canvas-200 cursor-pointer"
|
||||
checked={on}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
updateFilter({hasPhoto: e.target.checked ? true : undefined})
|
||||
}
|
||||
/>
|
||||
<label htmlFor={label} className={clsx('text-ink-600 ml-2')}>
|
||||
{label}
|
||||
</label>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user