Add pinned compatibility questions feature with backend support and UI integration

This commit is contained in:
MartinBraquet
2026-03-19 17:00:34 +01:00
parent 891b91d0ba
commit bdafa43472
17 changed files with 383 additions and 82 deletions

View File

@@ -11,6 +11,7 @@ import {getHiddenProfiles} from 'api/get-hidden-profiles'
import {getLastMessages} from 'api/get-last-messages'
import {getMessagesCountEndpoint} from 'api/get-messages-count'
import {getOptions} from 'api/get-options'
import {getPinnedCompatibilityQuestions} from 'api/get-pinned-compatibility-questions'
import {getChannelMessagesEndpoint} from 'api/get-private-messages'
import {getUser} from 'api/get-user'
import {hideProfile} from 'api/hide-profile'
@@ -20,6 +21,7 @@ import {saveSubscriptionMobile} from 'api/save-subscription-mobile'
import {sendSearchNotifications} from 'api/send-search-notifications'
import {localSendTestEmail} from 'api/test'
import {unhideProfile} from 'api/unhide-profile'
import {updateCompatibilityQuestionPin} from 'api/update-compatibility-question-pin'
import {updateConnectionInterests} from 'api/update-connection-interests'
import {updateOptions} from 'api/update-options'
import {vote} from 'api/vote'
@@ -406,7 +408,7 @@ Most endpoints require a valid Firebase JWT token. This gives you access to your
To obtain a token:
**In your app or browser console while logged in (JavaScript/TypeScript):**
**In your browser console while logged in (CTRL+SHIFT+C, then select the Console tab):**
\`\`\`js
const db = await new Promise((res, rej) => {
const req = indexedDB.open('firebaseLocalStorageDb')
@@ -633,6 +635,8 @@ const handlers: {[k in APIPath]: APIHandler<k>} = {
'update-user-locale': updateUserLocale,
'update-private-user-message-channel': updatePrivateUserMessageChannel,
'update-profile': updateProfileEndpoint,
'update-compatibility-question-pin': updateCompatibilityQuestionPin,
'get-pinned-compatibility-questions': getPinnedCompatibilityQuestions,
'get-connection-interests': getConnectionInterestsEndpoint,
'update-connection-interest': updateConnectionInterests,
'user/by-id/:id': getUser,

View File

@@ -0,0 +1,22 @@
import type {APIHandler} from 'api/helpers/endpoint'
import {Row} from 'common/supabase/utils'
import {createSupabaseDirectClient} from 'shared/supabase/init'
export async function getPinnedQuestionIds(userId: string) {
const pg = createSupabaseDirectClient()
const rows = await pg.manyOrNone<Row<'compatibility_prompts_pinned'>>(
`select * from compatibility_prompts_pinned
where user_id = $1
order by created_time desc`,
[userId],
)
// newest-first in table; return in that order
return rows.map((r) => r.question_id)
}
export const getPinnedCompatibilityQuestions: APIHandler<
'get-pinned-compatibility-questions'
> = async (_props, auth) => {
const pinnedQuestionIds = await getPinnedQuestionIds(auth.uid)
return {status: 'success', pinnedQuestionIds}
}

View File

@@ -0,0 +1,28 @@
import {getPinnedQuestionIds} from 'api/get-pinned-compatibility-questions'
import {createSupabaseDirectClient} from 'shared/supabase/init'
import {type APIHandler} from './helpers/endpoint'
export const updateCompatibilityQuestionPin: APIHandler<
'update-compatibility-question-pin'
> = async ({questionId, pinned}, auth) => {
const pg = createSupabaseDirectClient()
if (pinned) {
await pg.none(
`insert into compatibility_prompts_pinned (user_id, question_id)
values ($1, $2)
on conflict (user_id, question_id) do nothing`,
[auth.uid, questionId],
)
} else {
await pg.none(
`delete from compatibility_prompts_pinned
where user_id = $1 and question_id = $2`,
[auth.uid, questionId],
)
}
const pinnedQuestionIds = await getPinnedQuestionIds(auth.uid)
return {status: 'success', pinnedQuestionIds}
}