Encourage users to keep their account when deleting for lack of matches

When someone picks a scarcity reason in the delete survey (not enough
relevant people, community not active enough, messages unanswered), show
a callout making the case for staying: keeping the account is free,
saved-search alerts come to them, and staying keeps them findable by
people who join later. Two compatible people who join at different times
and both delete never meet.

Also relabels the modal's cancel button to "Keep my account" in that case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
MartinBraquet
2026-07-24 23:54:53 +02:00
parent 9ab38056ab
commit 35c7ee178f
4 changed files with 114 additions and 0 deletions

View File

@@ -265,6 +265,15 @@
"delete_survey.reasons.taking_a_break": "Ich mache eine Pause von Dating-Apps",
"delete_survey.reasons.technical_issues": "Technische Probleme oder Fehler",
"delete_survey.reasons.too_much_time_or_effort": "Die Nutzung der Plattform erforderte mehr Zeit oder Aufwand als ich geben kann",
"delete_survey.stay.alerts_body": "Speichern Sie eine Suche, und wir benachrichtigen Sie, sobald jemand Neues dazu passt. Sie müssen nie wieder selbst nachsehen.",
"delete_survey.stay.alerts_title": "Wir kommen zu Ihnen.",
"delete_survey.stay.intro": "Compass wächst weiter, und Ihr Konto zu behalten kostet Sie nichts: keine Gebühren, und Sie können alle E-Mails in den Einstellungen abschalten.",
"delete_survey.stay.keep_account": "Mein Konto behalten",
"delete_survey.stay.timing_body": "Zwei Menschen, die hervorragend zueinander gepasst hätten, verpassen sich aus einem einzigen Grund: Sie waren zu unterschiedlichen Zeiten hier. Zu bleiben macht die Überschneidung erst möglich.",
"delete_survey.stay.timing_title": "Es kommt auf den Zeitpunkt an.",
"delete_survey.stay.title": "Eines noch, bevor Sie gehen",
"delete_survey.stay.visible_body": "Die nächste Person, die beitritt, kann Sie finden. Ist Ihr Profil gelöscht, sind Sie für alle unsichtbar, die nach heute dazukommen.",
"delete_survey.stay.visible_title": "Sie bleiben auffindbar.",
"delete_survey.title": "Schade, dass Sie gehen",
"delete_yourself.confirm_phrase": "delete my account",
"delete_yourself.description": "Das Löschen Ihres Kontos bedeutet, dass Sie es nicht mehr verwenden können. Sie verlieren den Zugriff auf alle Ihre Daten.",

View File

@@ -265,6 +265,15 @@
"delete_survey.reasons.taking_a_break": "Je fais une pause des applications de rencontre",
"delete_survey.reasons.technical_issues": "Problèmes techniques ou bugs",
"delete_survey.reasons.too_much_time_or_effort": "Utiliser la plateforme demandait plus de temps ou d'effort que je ne peux donner",
"delete_survey.stay.alerts_body": "Enregistrez une recherche et nous vous prévenons dès qu'une nouvelle personne y correspond. Vous n'avez jamais besoin de revenir vérifier.",
"delete_survey.stay.alerts_title": "Nous venons à vous.",
"delete_survey.stay.intro": "Compass continue de grandir, et garder votre compte ne vous coûte rien : aucun frais, et vous pouvez désactiver tous les e-mails dans les Paramètres.",
"delete_survey.stay.keep_account": "Garder mon compte",
"delete_survey.stay.timing_body": "Deux personnes qui auraient formé une belle rencontre se manquent pour une seule raison : elles étaient là à des moments différents. Rester, c'est ce qui rend le croisement possible.",
"delete_survey.stay.timing_title": "Tout est une question de moment.",
"delete_survey.stay.title": "Un mot avant votre départ",
"delete_survey.stay.visible_body": "La prochaine personne qui s'inscrit peut vous trouver. Si votre profil disparaît, vous êtes invisible pour tous ceux qui arriveront après aujourd'hui.",
"delete_survey.stay.visible_title": "Vous restez visible.",
"delete_survey.title": "Désolé de vous voir partir",
"delete_yourself.confirm_phrase": "delete my account",
"delete_yourself.description": "Supprimer votre compte signifie que vous ne pourrez plus l'utiliser. Vous perdrez l'accès à toutes vos données.",

View File

@@ -8,6 +8,7 @@ import {deleteAccount} from 'web/lib/util/delete'
import {ConfirmationButton} from '../buttons/confirmation-button'
import {Col} from '../layout/col'
import {Title} from '../widgets/title'
import {SCARCITY_DELETION_REASONS, StayInsteadOfDelete} from './stay-instead-of-delete'
export function DeleteAccountSurveyModal() {
const [selectedReason, setSelectedReason] = useState<string | null>(null)
@@ -125,6 +126,8 @@ export function DeleteAccountSurveyModal() {
}
}
const showStayPitch = !!selectedReason && SCARCITY_DELETION_REASONS.includes(selectedReason)
return (
<ConfirmationButton
openModalBtn={{
@@ -132,6 +135,14 @@ export function DeleteAccountSurveyModal() {
label: t('delete_yourself.open_label', 'Delete account'),
color: 'red',
}}
cancelBtn={
showStayPitch
? {
label: t('delete_survey.stay.keep_account', 'Keep my account'),
color: 'indigo',
}
: undefined
}
submitBtn={{
label: t('delete_yourself.submit', 'Delete account'),
color: selectedReason ? 'red' : 'gray',
@@ -190,6 +201,12 @@ export function DeleteAccountSurveyModal() {
</div>
</RadioGroup>
{showStayPitch && (
<div className="mt-4">
<StayInsteadOfDelete />
</div>
)}
{
<div className="mt-4">
<label htmlFor="otherReason" className="block text-sm font-medium">

View File

@@ -0,0 +1,79 @@
import {BellAlertIcon, EyeIcon, HeartIcon} from '@heroicons/react/24/outline'
import {ReactNode} from 'react'
import {useT} from 'web/lib/locale'
import {Col} from '../layout/col'
import {Row} from '../layout/row'
/**
* Reasons that boil down to "there aren't enough people here (yet)". Deleting is the one move that
* makes that worse for the person doing it: they stop being found, and they stop being told when
* someone who fits shows up.
*/
export const SCARCITY_DELETION_REASONS = [
'not_enough_relevant_people',
'platform_not_active_enough',
'low_response_rate',
]
function Point(props: {icon: ReactNode; title: string; body: string}) {
const {icon, title, body} = props
return (
<Row className="gap-3">
<div className="text-primary-600 mt-0.5 shrink-0">{icon}</div>
<div className="text-sm">
<span className="font-medium">{title}</span> <span className="text-ink-700">{body}</span>
</div>
</Row>
)
}
/** Shown when the stated deletion reason is one that keeping the account actually helps with. */
export function StayInsteadOfDelete() {
const t = useT()
return (
<Col
className="border-primary-300 bg-primary-50 gap-3 rounded-lg border p-4"
data-testid="stay-instead-of-delete"
>
<div className="font-semibold">
{t('delete_survey.stay.title', 'One thing before you go')}
</div>
<div className="text-ink-700 text-sm">
{t(
'delete_survey.stay.intro',
'Compass keeps growing, and keeping your account costs you nothing — no fees, and you can turn every email off in Settings.',
)}
</div>
<Col className="gap-2.5">
<Point
icon={<BellAlertIcon className="h-5 w-5" />}
title={t('delete_survey.stay.alerts_title', 'We come to you.')}
body={t(
'delete_survey.stay.alerts_body',
'Save a search and we notify you as soon as someone new matches it. You never have to check back.',
)}
/>
<Point
icon={<EyeIcon className="h-5 w-5" />}
title={t('delete_survey.stay.visible_title', 'You stay findable.')}
body={t(
'delete_survey.stay.visible_body',
'The next person who joins can find you. If your profile is gone, you are invisible to everyone who arrives after today.',
)}
/>
<Point
icon={<HeartIcon className="h-5 w-5" />}
title={t('delete_survey.stay.timing_title', 'Timing is the whole game.')}
body={t(
'delete_survey.stay.timing_body',
'Two people who would have been a great match miss each other for one reason: they were here at different times. Staying is what makes the overlap possible.',
)}
/>
</Col>
</Col>
)
}