about summary refs log tree commit diff
path: root/src/view/com/util/error/ErrorScreen.tsx
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-12-28 14:06:01 -0600
committerGitHub <noreply@github.com>2022-12-28 14:06:01 -0600
commit7e31645e9a355f2a0b3c8d62430a53dbb4714674 (patch)
tree24db1b09b9065472f5c7e08f9e2798d63fee8b1a /src/view/com/util/error/ErrorScreen.tsx
parentcc63660982199a989859d3b5328ba43a4edec755 (diff)
downloadvoidsky-7e31645e9a355f2a0b3c8d62430a53dbb4714674.tar.zst
Add a design system (#34)
* Add theming system

* Add standard Button control and update RadioButtons

* Unify radiobutton with design system

* Update debug screen to have multiple views

* Add ToggleButton

* Update error controls to use design system

* Add typography to <Text> element

* Move DropdownButton into the design system

* Clean out old code

* Move Text into design system

* Add 'inverted' color palette

* Move LoadingPlaceholder into the design system
Diffstat (limited to 'src/view/com/util/error/ErrorScreen.tsx')
-rw-r--r--src/view/com/util/error/ErrorScreen.tsx113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/view/com/util/error/ErrorScreen.tsx b/src/view/com/util/error/ErrorScreen.tsx
new file mode 100644
index 000000000..6db54a9f2
--- /dev/null
+++ b/src/view/com/util/error/ErrorScreen.tsx
@@ -0,0 +1,113 @@
+import React from 'react'
+import {StyleSheet, TouchableOpacity, View} from 'react-native'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {Text} from '../text/Text'
+import {colors} from '../../../lib/styles'
+import {useTheme} from '../../../lib/ThemeContext'
+import {usePalette} from '../../../lib/hooks/usePalette'
+
+export function ErrorScreen({
+  title,
+  message,
+  details,
+  onPressTryAgain,
+}: {
+  title: string
+  message: string
+  details?: string
+  onPressTryAgain?: () => void
+}) {
+  const theme = useTheme()
+  const pal = usePalette('error')
+  return (
+    <View style={[styles.outer, pal.view]}>
+      <View style={styles.errorIconContainer}>
+        <View
+          style={[
+            styles.errorIcon,
+            {backgroundColor: theme.palette.error.icon},
+          ]}>
+          <FontAwesomeIcon
+            icon="exclamation"
+            style={{color: colors.white}}
+            size={24}
+          />
+        </View>
+      </View>
+      <Text type="h3" style={[styles.title, pal.text]}>
+        {title}
+      </Text>
+      <Text style={[styles.message, pal.textLight]}>{message}</Text>
+      {details && (
+        <Text
+          type="body2"
+          style={[
+            styles.details,
+            pal.textInverted,
+            {backgroundColor: theme.palette.default.background},
+          ]}>
+          {details}
+        </Text>
+      )}
+      {onPressTryAgain && (
+        <View style={styles.btnContainer}>
+          <TouchableOpacity
+            style={[styles.btn, {backgroundColor: theme.palette.error.icon}]}
+            onPress={onPressTryAgain}>
+            <FontAwesomeIcon icon="arrows-rotate" style={pal.text} size={16} />
+            <Text type="button" style={[styles.btnText, pal.text]}>
+              Try again
+            </Text>
+          </TouchableOpacity>
+        </View>
+      )}
+    </View>
+  )
+}
+
+const styles = StyleSheet.create({
+  outer: {
+    flex: 1,
+    paddingVertical: 30,
+    paddingHorizontal: 14,
+  },
+  title: {
+    textAlign: 'center',
+    marginBottom: 10,
+  },
+  message: {
+    textAlign: 'center',
+    marginBottom: 20,
+  },
+  details: {
+    textAlign: 'center',
+    paddingVertical: 10,
+    paddingHorizontal: 14,
+    overflow: 'hidden',
+    marginBottom: 20,
+  },
+  btnContainer: {
+    alignItems: 'center',
+  },
+  btn: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    paddingHorizontal: 16,
+    paddingVertical: 10,
+  },
+  btnText: {
+    marginLeft: 5,
+  },
+  errorIconContainer: {
+    alignItems: 'center',
+    marginBottom: 10,
+  },
+  errorIcon: {
+    borderRadius: 30,
+    width: 50,
+    height: 50,
+    alignItems: 'center',
+    justifyContent: 'center',
+    marginRight: 5,
+  },
+})