@@ -9,12 +9,16 @@ import {
99 ActivityIndicator ,
1010 Alert ,
1111 Linking ,
12+ Modal ,
13+ Platform ,
1214} from "react-native" ;
15+ import Constants from "expo-constants" ;
1316import { SafeAreaView } from "react-native-safe-area-context" ;
1417import { useRouter } from "expo-router" ;
1518import { useTranslation } from "react-i18next" ;
1619import { useAuth } from "../../src/store/auth" ;
1720import { changeEmail , changePassword , deleteAccount } from "../../src/api/auth" ;
21+ import { submitBugReport } from "../../src/api/bugReports" ;
1822import { api } from "../../src/api/client" ;
1923import { LanguagePicker } from "../../src/components/LanguagePicker" ;
2024import { colors , spacing , radius , font } from "../../src/theme" ;
@@ -33,6 +37,30 @@ export default function AccountScreen() {
3337 const router = useRouter ( ) ;
3438 const { user, logout, setUser } = useAuth ( ) ;
3539
40+ const [ bugOpen , setBugOpen ] = useState ( false ) ;
41+ const [ bugText , setBugText ] = useState ( "" ) ;
42+ const [ bugSubmitting , setBugSubmitting ] = useState ( false ) ;
43+
44+ async function handleSubmitBug ( ) {
45+ const description = bugText . trim ( ) ;
46+ if ( ! description || bugSubmitting ) return ;
47+ setBugSubmitting ( true ) ;
48+ try {
49+ const res = await submitBugReport ( {
50+ description,
51+ page : "mobile-app" ,
52+ userAgent : `${ Platform . OS } app ${ Constants . expoConfig ?. version ?? "unknown" } ` ,
53+ } ) ;
54+ setBugOpen ( false ) ;
55+ setBugText ( "" ) ;
56+ Alert . alert ( t ( "bug.thanks" , { number : res . number } ) ) ;
57+ } catch ( err ) {
58+ Alert . alert ( t ( "bug.failed" ) , ( err as Error ) . message ) ;
59+ } finally {
60+ setBugSubmitting ( false ) ;
61+ }
62+ }
63+
3664 const [ emailForm , setEmailForm ] = useState ( {
3765 email : "" ,
3866 password : "" ,
@@ -261,6 +289,16 @@ export default function AccountScreen() {
261289 </ Pressable >
262290 </ View >
263291
292+ < SectionHeader title = { t ( "account.reportBug" ) } />
293+ < View style = { s . card } >
294+ < Pressable
295+ style = { ( { pressed } ) => [ s . btn , pressed && s . pressed ] }
296+ onPress = { ( ) => setBugOpen ( true ) }
297+ >
298+ < Text style = { s . btnText } > { t ( "account.reportBug" ) } </ Text >
299+ </ Pressable >
300+ </ View >
301+
264302 < SectionHeader title = { t ( "account.language" ) } />
265303 < View style = { s . card } >
266304 < LanguagePicker />
@@ -299,6 +337,39 @@ export default function AccountScreen() {
299337 </ Pressable >
300338 </ View >
301339 </ ScrollView >
340+
341+ < Modal
342+ visible = { bugOpen }
343+ transparent
344+ animationType = "slide"
345+ onRequestClose = { ( ) => setBugOpen ( false ) }
346+ >
347+ < Pressable style = { s . bugBackdrop } onPress = { ( ) => setBugOpen ( false ) } />
348+ < View style = { s . bugSheet } >
349+ < Text style = { s . bugTitle } > { t ( "account.reportBug" ) } </ Text >
350+ < TextInput
351+ style = { s . bugInput }
352+ placeholder = { t ( "bug.placeholder" ) }
353+ placeholderTextColor = { colors . textDim }
354+ value = { bugText }
355+ onChangeText = { setBugText }
356+ multiline
357+ textAlignVertical = "top"
358+ autoFocus
359+ />
360+ < Pressable
361+ style = { ( { pressed } ) => [ s . btn , pressed && s . pressed ] }
362+ onPress = { handleSubmitBug }
363+ disabled = { bugSubmitting || ! bugText . trim ( ) }
364+ >
365+ { bugSubmitting ? (
366+ < ActivityIndicator color = { colors . text } />
367+ ) : (
368+ < Text style = { s . btnText } > { t ( "bug.send" ) } </ Text >
369+ ) }
370+ </ Pressable >
371+ </ View >
372+ </ Modal >
302373 </ SafeAreaView >
303374 ) ;
304375}
@@ -412,4 +483,23 @@ const s = StyleSheet.create({
412483 pressed : { opacity : 0.75 } ,
413484 btnText : { color : colors . text , fontSize : font . md , fontWeight : "600" } ,
414485 dangerText : { color : colors . danger } ,
486+ bugBackdrop : { flex : 1 , backgroundColor : "rgba(0,0,0,0.5)" } ,
487+ bugSheet : {
488+ backgroundColor : colors . surface ,
489+ borderTopLeftRadius : radius . lg ,
490+ borderTopRightRadius : radius . lg ,
491+ padding : spacing . md ,
492+ gap : spacing . sm ,
493+ } ,
494+ bugTitle : { color : colors . text , fontSize : font . lg , fontWeight : "700" } ,
495+ bugInput : {
496+ backgroundColor : colors . surfaceHigh ,
497+ color : colors . text ,
498+ borderRadius : radius . sm ,
499+ borderWidth : 1 ,
500+ borderColor : colors . border ,
501+ padding : spacing . sm ,
502+ fontSize : font . md ,
503+ minHeight : 120 ,
504+ } ,
415505} ) ;
0 commit comments