about summary refs log tree commit diff
path: root/src/view/com/modals/EditProfile.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/modals/EditProfile.tsx')
-rw-r--r--src/view/com/modals/EditProfile.tsx123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx
new file mode 100644
index 000000000..72cbd4119
--- /dev/null
+++ b/src/view/com/modals/EditProfile.tsx
@@ -0,0 +1,123 @@
+import React, {useState} from 'react'
+import Toast from '../util/Toast'
+import {StyleSheet, Text, TextInput, TouchableOpacity, View} from 'react-native'
+import LinearGradient from 'react-native-linear-gradient'
+import {ErrorMessage} from '../util/ErrorMessage'
+import {useStores} from '../../../state'
+import {ProfileViewModel} from '../../../state/models/profile-view'
+import {s, colors, gradients} from '../../lib/styles'
+
+export const snapPoints = ['80%']
+
+export function Component({profileView}: {profileView: ProfileViewModel}) {
+  const store = useStores()
+  const [error, setError] = useState<string>('')
+  const [displayName, setDisplayName] = useState<string>(
+    profileView.displayName || '',
+  )
+  const [description, setDescription] = useState<string>(
+    profileView.description || '',
+  )
+  const onPressSave = async () => {
+    if (error) {
+      setError('')
+    }
+    try {
+      await profileView.updateProfile({
+        displayName,
+        description,
+      })
+      Toast.show('Profile updated', {
+        position: Toast.positions.TOP,
+      })
+      store.shell.closeModal()
+    } catch (e: any) {
+      console.error(e)
+      setError(
+        'Failed to save your profile. Check your internet connection and try again.',
+      )
+    }
+  }
+
+  return (
+    <View style={s.flex1}>
+      <Text style={[s.textCenter, s.bold, s.f16]}>Edit my profile</Text>
+      <View style={styles.inner}>
+        {error !== '' && (
+          <View style={s.mb10}>
+            <ErrorMessage message={error} />
+          </View>
+        )}
+        <View style={styles.group}>
+          <Text style={styles.label}>Display Name</Text>
+          <TextInput
+            style={styles.textInput}
+            placeholder="e.g. Alice Roberts"
+            value={displayName}
+            onChangeText={setDisplayName}
+          />
+        </View>
+        <View style={styles.group}>
+          <Text style={styles.label}>Biography</Text>
+          <TextInput
+            style={[styles.textArea]}
+            placeholder="e.g. Artist, dog-lover, and memelord."
+            multiline
+            value={description}
+            onChangeText={setDescription}
+          />
+        </View>
+        <TouchableOpacity style={s.mt10} onPress={onPressSave}>
+          <LinearGradient
+            colors={[gradients.primary.start, gradients.primary.end]}
+            start={{x: 0, y: 0}}
+            end={{x: 1, y: 1}}
+            style={[styles.btn]}>
+            <Text style={[s.white, s.bold]}>Save Changes</Text>
+          </LinearGradient>
+        </TouchableOpacity>
+      </View>
+    </View>
+  )
+}
+
+const styles = StyleSheet.create({
+  inner: {
+    padding: 14,
+  },
+  group: {
+    marginBottom: 10,
+  },
+  label: {
+    fontWeight: 'bold',
+    paddingHorizontal: 4,
+    paddingBottom: 4,
+  },
+  textInput: {
+    borderWidth: 1,
+    borderColor: colors.gray3,
+    borderRadius: 6,
+    paddingHorizontal: 14,
+    paddingVertical: 10,
+    fontSize: 16,
+  },
+  textArea: {
+    borderWidth: 1,
+    borderColor: colors.gray3,
+    borderRadius: 6,
+    paddingHorizontal: 12,
+    paddingTop: 10,
+    fontSize: 16,
+    height: 100,
+    textAlignVertical: 'top',
+  },
+  btn: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'center',
+    width: '100%',
+    borderRadius: 32,
+    padding: 10,
+    marginBottom: 10,
+  },
+})