diff --git a/mani/app/_layout.tsx b/mani/app/_layout.tsx index 3568fb3b94..d7622043dd 100644 --- a/mani/app/_layout.tsx +++ b/mani/app/_layout.tsx @@ -145,6 +145,8 @@ function RootLayout() { + + )} diff --git a/mani/app/account-settings.tsx b/mani/app/account-settings.tsx new file mode 100644 index 0000000000..09da88689e --- /dev/null +++ b/mani/app/account-settings.tsx @@ -0,0 +1,165 @@ +import { useState } from 'react' +import { Alert } from 'react-native' +import { Col } from 'components/layout/col' +import { Row } from 'components/layout/row' +import { ThemedText } from 'components/themed-text' +import { Button } from 'components/buttons/button' +import { useColor } from 'hooks/use-color' +import { usePrivateUser, useUser } from 'hooks/use-user' +import { api } from 'lib/api' +import { Input } from 'components/widgets/input' +import Page from 'components/page' +import { Switch } from 'components/form/switch' +import { IconSymbol } from 'components/ui/icon-symbol' +import { capitalize } from 'lodash' +import { TRADE_TERM } from 'common/envs/constants' +import { auth } from 'lib/firebase/init' +import { Toast } from 'react-native-toast-message/lib/src/Toast' +import Clipboard from 'expo-clipboard' + +function SettingRow(props: { label: string; children: React.ReactNode }) { + const { label, children } = props + return ( + + + {label} + + {children} + + ) +} + +export default function AccountSettingsPage() { + const user = useUser() + const privateUser = usePrivateUser() + const color = useColor() + const [apiKey, setApiKey] = useState(privateUser?.apiKey) + const [betWarnings, setBetWarnings] = useState(!user?.optOutBetWarnings) + const [loading, setLoading] = useState(false) + + const updateApiKey = async () => { + setLoading(true) + const newApiKey = await generateNewApiKey() + setApiKey(newApiKey ?? '') + setLoading(false) + } + + const copyApiKey = async () => { + if (!apiKey) return + await Clipboard.setStringAsync(apiKey) + Toast.show({ + type: 'success', + text1: 'API key copied to clipboard', + }) + } + + const confirmApiKeyUpdate = () => { + Alert.alert( + 'Update API Key', + 'Updating your API key will break any existing applications connected to your account. Are you sure?', + [ + { + text: 'Cancel', + style: 'cancel', + }, + { + text: 'Update', + onPress: updateApiKey, + }, + ] + ) + } + if (!user) return null + + const deleteAccount = async () => { + await api('me/delete', { username: user.username }) + await auth.signOut() + } + + const confirmDeleteAccount = () => { + Alert.alert( + 'Delete Account', + 'Are you sure you want to delete your account? This action cannot be undone.', + [ + { + text: 'Cancel', + style: 'cancel', + }, + { + text: 'Delete', + onPress: deleteAccount, + style: 'destructive', + }, + ] + ) + } + + return ( + + + + { + setBetWarnings(enabled) + api('me/update', { optOutBetWarnings: !enabled }) + }} + /> + + + + + + + + + + + + )} @@ -151,6 +146,12 @@ export function ProfileContent(props: { user: User }) { )} /> + {isCurrentUser && ( + setIsSettingsOpen(false)} + /> + )} ) } diff --git a/mani/components/profile/settings-modal.tsx b/mani/components/profile/settings-modal.tsx new file mode 100644 index 0000000000..1f0d66ecbf --- /dev/null +++ b/mani/components/profile/settings-modal.tsx @@ -0,0 +1,53 @@ +import { View } from 'react-native' +import { Modal } from 'components/layout/modal' +import { Col } from 'components/layout/col' +import { Button } from 'components/buttons/button' +import { useColor } from 'hooks/use-color' +import { auth } from 'lib/firebase/init' +import { clearData } from 'lib/auth-storage' +import { router } from 'expo-router' + +export function SettingsModal(props: { isOpen: boolean; onClose: () => void }) { + const { isOpen, onClose } = props + const color = useColor() + + const signOut = async () => { + try { + await auth.signOut() + await clearData('user') + onClose() + } catch (err) { + console.error('Error signing out:', err) + } + } + + return ( + + + +