chahinebrini d840247c98 feat(native): help section — FAQ, Contact, About, Crisis pages
New route group app/help/ with 4 sub-pages navigable from settings.

- help/faq.tsx: accordion with 8 Q&As (drafted by UI agent, see below)
- help/contact.tsx: mailto:hilfe@rebreak.org with prefilled subject,
  address block (Rebreak placeholder — TODO verify legal entity name)
- help/about.tsx: mission text + 3 fact rows (DiGA, Hetzner, DSGVO)
- help/crisis.tsx: BZgA 0800 1 372 700, check-dein-spiel.de,
  anonyme-spieler.org, Telefonseelsorge 0800 111 0 111, emergency
  112-box with error-color border treatment. Disclaimer at bottom.

All pages use AppHeader showBack for correct back-button.
All strings in help.* namespace in DE/EN/FR locales.

FAQ answers drafted by UI agent — pending lyra-persona tone review:
  faq_a1 (what is Rebreak), faq_a2 (blocker), faq_a3 (Mac DNS),
  faq_a4 (cancel sub), faq_a5 (data), faq_a6 (bug report),
  faq_a7 (whitelist), faq_a8 (DiGA).
FR locale: faq answers are DE-fallback text (TODO: translate properly).
Contact address block: placeholder — TODO confirm legal entity + address.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:42:45 +02:00

251 lines
6.9 KiB
TypeScript

import { Linking, ScrollView, Text, TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { useColors } from '../../lib/theme';
import { AppHeader } from '../../components/AppHeader';
type HotlineRowProps = {
label: string;
sublabel: string;
phoneOrUrl: string;
isUrl?: boolean;
colors: ReturnType<typeof useColors>;
};
function HotlineRow({ label, sublabel, phoneOrUrl, isUrl, colors }: HotlineRowProps) {
return (
<TouchableOpacity
onPress={() => Linking.openURL(isUrl ? phoneOrUrl : `tel:${phoneOrUrl.replace(/\s/g, '')}`)}
activeOpacity={0.7}
>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 12,
paddingHorizontal: 16,
paddingVertical: 14,
}}
>
<View
style={{
width: 34,
height: 34,
borderRadius: 10,
backgroundColor: colors.surfaceElevated,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Ionicons
name={isUrl ? 'globe-outline' : 'call-outline'}
size={17}
color={colors.textMuted}
/>
</View>
<View style={{ flex: 1 }}>
<Text
style={{
fontSize: 15,
fontFamily: 'Nunito_600SemiBold',
color: colors.text,
}}
>
{label}
</Text>
<Text
style={{
fontSize: 12,
fontFamily: 'Nunito_400Regular',
color: colors.textMuted,
marginTop: 2,
}}
>
{sublabel}
</Text>
</View>
<Ionicons name="chevron-forward" size={16} color={colors.border} />
</View>
</TouchableOpacity>
);
}
export default function CrisisScreen() {
const { t } = useTranslation();
const colors = useColors();
const insets = useSafeAreaInsets();
return (
<View style={{ flex: 1, backgroundColor: colors.groupedBg }}>
<AppHeader showBack title={t('help.crisis_title')} />
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{
paddingHorizontal: 16,
paddingTop: 20,
paddingBottom: insets.bottom + 40,
}}
showsVerticalScrollIndicator={false}
>
<Text
style={{
fontSize: 13,
fontFamily: 'Nunito_600SemiBold',
color: colors.textMuted,
textTransform: 'uppercase',
letterSpacing: 1,
marginBottom: 8,
marginLeft: 4,
}}
>
{t('help.crisis_section_gambling')}
</Text>
<View
style={{
backgroundColor: colors.card,
borderRadius: 14,
overflow: 'hidden',
marginBottom: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.04,
shadowRadius: 3,
elevation: 1,
}}
>
<View style={{ borderBottomWidth: 1, borderBottomColor: colors.border }}>
<HotlineRow
label={t('help.crisis_bzga_label')}
sublabel={t('help.crisis_bzga_sublabel')}
phoneOrUrl="0800 1 372 700"
colors={colors}
/>
</View>
<View style={{ borderBottomWidth: 1, borderBottomColor: colors.border }}>
<HotlineRow
label={t('help.crisis_checkdein_label')}
sublabel={t('help.crisis_checkdein_sublabel')}
phoneOrUrl="https://www.check-dein-spiel.de"
isUrl
colors={colors}
/>
</View>
<HotlineRow
label={t('help.crisis_anonyme_label')}
sublabel={t('help.crisis_anonyme_sublabel')}
phoneOrUrl="https://www.anonyme-spieler.org"
isUrl
colors={colors}
/>
</View>
<Text
style={{
fontSize: 13,
fontFamily: 'Nunito_600SemiBold',
color: colors.textMuted,
textTransform: 'uppercase',
letterSpacing: 1,
marginBottom: 8,
marginLeft: 4,
}}
>
{t('help.crisis_section_general')}
</Text>
<View
style={{
backgroundColor: colors.card,
borderRadius: 14,
overflow: 'hidden',
marginBottom: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.04,
shadowRadius: 3,
elevation: 1,
}}
>
<HotlineRow
label={t('help.crisis_seelsorge_label')}
sublabel={t('help.crisis_seelsorge_sublabel')}
phoneOrUrl="0800 111 0 111"
colors={colors}
/>
</View>
<View
style={{
backgroundColor: '#fef2f2',
borderRadius: 14,
borderWidth: 1.5,
borderColor: colors.error,
padding: 16,
marginBottom: 20,
}}
>
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 8 }}>
<Ionicons name="warning-outline" size={20} color={colors.error} />
<Text
style={{
fontSize: 15,
fontFamily: 'Nunito_700Bold',
color: colors.error,
}}
>
{t('help.crisis_emergency_label')}
</Text>
</View>
<Text
style={{
fontSize: 14,
fontFamily: 'Nunito_400Regular',
color: colors.text,
lineHeight: 21,
marginBottom: 12,
}}
>
{t('help.crisis_emergency_desc')}
</Text>
<TouchableOpacity
onPress={() => Linking.openURL('tel:112')}
activeOpacity={0.7}
style={{
backgroundColor: colors.error,
borderRadius: 10,
paddingVertical: 12,
alignItems: 'center',
}}
>
<Text
style={{
fontSize: 16,
fontFamily: 'Nunito_700Bold',
color: '#ffffff',
}}
>
{t('help.crisis_emergency_cta')}
</Text>
</TouchableOpacity>
</View>
<Text
style={{
fontSize: 12,
fontFamily: 'Nunito_400Regular',
color: colors.textMuted,
lineHeight: 18,
textAlign: 'center',
marginHorizontal: 8,
}}
>
{t('help.crisis_disclaimer')}
</Text>
</ScrollView>
</View>
);
}