From 2f3b19f71baae9471475acc1272b94fd4b7a5356 Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Thu, 7 May 2026 21:11:41 +0200 Subject: [PATCH] fix(profile/faq): demographics-hint auto-expand + FAQ-chevron-direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Profile: - Hint "fuelle deine anonymen Daten aus" oeffnet das DemographicsAccordion jetzt automatisch via expanded-Prop + useEffect mit LayoutAnimation. Vorher: scrollte hin, liess es geschlossen, User musste nochmal tappen. - DemographicsAccordion: expanded-Prop fuer external-trigger; interner expandedLocal-State, Toggle-Button bleibt unabhaengig functional. ProtectionDetailsSheet FAQ: - chevron-forward (0deg→90deg Rotation, sah aus wie Nav-Link) → chevron-down (0deg→180deg). Geschlossen=runter, offen=hoch. State-Toggling war schon korrekt, nur visuelle Affordance war falsch. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/rebreak-native/app/profile/index.tsx | 9 ++++++++- .../components/blocker/ProtectionDetailsSheet.tsx | 4 ++-- .../components/profile/DemographicsAccordion.tsx | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/rebreak-native/app/profile/index.tsx b/apps/rebreak-native/app/profile/index.tsx index 0ed5075..a70cd10 100644 --- a/apps/rebreak-native/app/profile/index.tsx +++ b/apps/rebreak-native/app/profile/index.tsx @@ -107,6 +107,7 @@ export default function ProfileScreen() { const insets = useSafeAreaInsets(); const [bannerDismissed, setBannerDismissed] = useState(false); const [demographics, setDemographics] = useState(DUMMY_DEMOGRAPHICS); + const [demographicsExpanded, setDemographicsExpanded] = useState(false); const { me } = useMe(); const { user } = useAuthStore(); @@ -148,6 +149,11 @@ export default function ProfileScreen() { ); } + function openDemographics() { + setDemographicsExpanded(true); + scrollToDemographics(); + } + return ( @@ -165,7 +171,7 @@ export default function ProfileScreen() { memberSince={profile.memberSince} provider={profile.provider} showDemographicsHint={!demoComplete} - onDemographicsHintPress={scrollToDemographics} + onDemographicsHintPress={openDemographics} onEditAvatar={() => { // TODO Phase C: AvatarPickerSheet (preset-grid + custom-upload via expo-image-picker) Alert.alert( @@ -241,6 +247,7 @@ export default function ProfileScreen() { { // TODO Phase C: PATCH /api/profile/me/demographics — Body: next // Endpoint: profile.demographics_consent_at = NOW() bei erstem Save (DSGVO-Audit-Trail). diff --git a/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx b/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx index adce30b..b5f3c90 100644 --- a/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx +++ b/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx @@ -653,7 +653,7 @@ function FaqItem({ question, answer }: { question: string; answer: string }) { const rotate = rotateAnim.interpolate({ inputRange: [0, 1], - outputRange: ['0deg', '90deg'], + outputRange: ['0deg', '180deg'], }); return ( @@ -692,7 +692,7 @@ function FaqItem({ question, answer }: { question: string; answer: string }) { transform: [{ rotate }], }} > - + {open && ( diff --git a/apps/rebreak-native/components/profile/DemographicsAccordion.tsx b/apps/rebreak-native/components/profile/DemographicsAccordion.tsx index 95a3024..d636e25 100644 --- a/apps/rebreak-native/components/profile/DemographicsAccordion.tsx +++ b/apps/rebreak-native/components/profile/DemographicsAccordion.tsx @@ -30,6 +30,7 @@ export type Demographics = { type Props = { demographics: Demographics; plan: Plan; + expanded?: boolean; defaultExpanded?: boolean; onChange?: (next: Demographics) => void; onRevokeConsent?: () => void; @@ -109,11 +110,21 @@ function mockPersist(_next: Demographics) { export function DemographicsAccordion({ demographics, plan, + expanded: expandedProp, defaultExpanded = false, onChange, onRevokeConsent, }: Props) { - const [expanded, setExpanded] = useState(defaultExpanded); + const [expandedLocal, setExpandedLocal] = useState(defaultExpanded); + + useEffect(() => { + if (expandedProp) { + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); + setExpandedLocal(true); + } + }, [expandedProp]); + + const expanded = expandedLocal; const [local, setLocal] = useState(demographics); // Select-Sheet-State @@ -128,7 +139,7 @@ export function DemographicsAccordion({ function toggle() { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); - setExpanded((v) => !v); + setExpandedLocal((v) => !v); } function persist(next: Demographics) {