Browse Source

fix: components improvements

Oleksandr Honcharov 1 year ago
parent
commit
8b42dde04a

+ 9 - 4
src/components/AvatarPicker/index.tsx

@@ -1,5 +1,6 @@
 import React, { FC, useState } from 'react';
-import { Image, Text, TouchableOpacity } from 'react-native';
+import { Text, TouchableOpacity } from 'react-native';
+import { Image } from 'expo-image';
 import * as ImagePicker from 'expo-image-picker';
 import AddIcon from '../../../assets/icons/add.svg';
 
@@ -10,10 +11,11 @@ import { ImagePickerAsset } from 'expo-image-picker';
 
 type Props = {
   selectedAvatar: (avatarPath: ImagePickerAsset) => void;
+  defaultAvatar?: string;
 };
 
-export const AvatarPicker: FC<Props> = ({ selectedAvatar }) => {
-  const [image, setImage] = useState('');
+export const AvatarPicker: FC<Props> = ({ selectedAvatar, defaultAvatar }) => {
+  const [image, setImage] = useState(defaultAvatar);
 
   const pickImage = async () => {
     // No permissions request is necessary for launching the image library
@@ -38,7 +40,10 @@ export const AvatarPicker: FC<Props> = ({ selectedAvatar }) => {
         </>
       )}
       {image && (
-        <Image source={{ uri: image }} style={{ width: 100, height: 100, borderRadius: 100 / 2 }} />
+        <Image
+          source={{ uri: image ?? defaultAvatar }}
+          style={{ width: 100, height: 100, borderRadius: 100 / 2 }}
+        />
       )}
     </TouchableOpacity>
   );

+ 14 - 4
src/components/Calendar/InputDatePicker/index.tsx

@@ -3,19 +3,28 @@ import { View } from 'react-native';
 
 import { Input } from '../../Input';
 import { Modal } from '../../Modal';
-import SpinnerDatePicker from '../SpinnerDatePicker';
 import { Button } from '../../Button';
+import SpinnerDatePicker from '../SpinnerDatePicker';
+
+import CalendarIcon from '../../../../assets/icons/calendar.svg';
 
 type Props = {
   selectedDate?: (date: Date) => void;
   formikError?: string | boolean;
+  headerTitle?: string;
+  defaultDate?: Date;
 };
 
 //TODO: waiting for redesign in figma + input fixes
 
-export const InputDatePicker: FC<Props> = ({ selectedDate, formikError }) => {
+export const InputDatePicker: FC<Props> = ({
+  selectedDate,
+  formikError,
+  headerTitle,
+  defaultDate
+}) => {
   const [visible, setVisible] = useState(false);
-  const [spinnerSelectedDate, setSpinnerSelectedDate] = useState<Date>(new Date());
+  const [spinnerSelectedDate, setSpinnerSelectedDate] = useState<Date>(defaultDate ?? new Date());
 
   const onButtonPress = () => {
     setVisible(false);
@@ -27,6 +36,7 @@ export const InputDatePicker: FC<Props> = ({ selectedDate, formikError }) => {
   return (
     <View>
       <Input
+        icon={<CalendarIcon />}
         header={'Date of birth'}
         value={new Date(spinnerSelectedDate).toLocaleDateString()}
         isFocused={(b) => setVisible(b)}
@@ -37,7 +47,7 @@ export const InputDatePicker: FC<Props> = ({ selectedDate, formikError }) => {
       <Modal
         visibleInPercent={'50%'}
         onRequestClose={() => setVisible(false)}
-        headerTitle={'Select Region of Origin'}
+        headerTitle={headerTitle ?? 'Change me'}
         visible={visible}
       >
         <SpinnerDatePicker selectedDate={(date) => setSpinnerSelectedDate(date)} />

+ 22 - 30
src/components/FlatList/index.tsx

@@ -1,42 +1,32 @@
 import React, { FC, useEffect, useState } from 'react';
-import { FlatList as List, SafeAreaView } from 'react-native';
+import { FlatList as List, SafeAreaView, View } from 'react-native';
 import { Input } from '../Input';
 import { styles } from './styles';
 import { Item, ItemData } from './item';
-
-const DATA: ItemData[] = [
-  {
-    id: '1',
-    title: 'First Item'
-  },
-  {
-    id: '2',
-    title: 'Second Item'
-  },
-  {
-    id: '3',
-    title: 'Third Item'
-  }
-];
+import { useGetRegionsWithFlagQuery } from '../../modules/auth/regions/queries/use-post-get-regions';
 
 type Props = {
   itemObject: (object: any) => void;
 };
 
-//TODO: rework to generic types + custom props + fetch data
+//TODO: rework to generic types + custom props
 
 export const FlatList: FC<Props> = ({ itemObject }) => {
-  const [selectedObject, setSelectedObject] = useState<{ id: string; title: string }>();
+  const [selectedObject, setSelectedObject] = useState<{ name: string; id: number }>();
   const [search, setSearch] = useState('');
   const [filteredData, setFilteredData] = useState<ItemData[]>([]);
   const [masterData, setMasterData] = useState<ItemData[]>([]);
 
+  const { data } = useGetRegionsWithFlagQuery(true);
+
   useEffect(() => {
-    setFilteredData(DATA);
-    setMasterData(DATA);
-  }, []);
+    if (data) {
+      setFilteredData(data.data);
+      setMasterData(data.data);
+    }
+  }, [data]);
 
-  const selectItem = (object: { title: string; id: string }) => {
+  const selectItem = (object: { name: string; id: number }) => {
     itemObject(object);
     setSelectedObject(object);
   };
@@ -44,7 +34,7 @@ export const FlatList: FC<Props> = ({ itemObject }) => {
   const searchFilter = (text: string) => {
     if (text) {
       const newData = masterData.filter((item) => {
-        const itemData = item.title ? item.title.toLowerCase() : ''.toLowerCase();
+        const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
         const textData = text.toLowerCase();
         return itemData.indexOf(textData) > -1;
       });
@@ -73,16 +63,18 @@ export const FlatList: FC<Props> = ({ itemObject }) => {
 
   return (
     <SafeAreaView style={styles.container}>
-      <Input
-        inputMode={'search'}
-        placeholder={'test'}
-        onChange={(text) => searchFilter(text)}
-        value={search}
-      />
+      <View style={{ marginTop: 10 }}>
+        <Input
+          inputMode={'search'}
+          placeholder={'Search'}
+          onChange={(text) => searchFilter(text)}
+          value={search}
+        />
+      </View>
       <List
         data={filteredData}
         renderItem={renderItem}
-        keyExtractor={(item) => item.id}
+        keyExtractor={(item) => item.id.toString()}
         extraData={selectedObject}
       />
     </SafeAreaView>

+ 6 - 5
src/components/FlatList/modal-flatlist/index.tsx

@@ -8,15 +8,16 @@ import { FlatList } from '../index';
 type Props = {
   selectedObject?: (object: any) => void;
   headerTitle: string;
+  defaultObject?: { name?: string };
 };
 
 //TODO: rework to generic types
 
-export const ModalFlatList: FC<Props> = ({ selectedObject, headerTitle }) => {
+export const ModalFlatList: FC<Props> = ({ selectedObject, headerTitle, defaultObject }) => {
   const [visible, setVisible] = useState(false);
-  const [selectedFlatListObject, setSelectedFlatListObject] = useState<{ title?: string }>({});
+  const [selectedFlatListObject, setSelectedFlatListObject] = useState<{ name?: string }>({});
 
-  const onSelect = (object: { title: string }) => {
+  const onSelect = (object: { name: string }) => {
     setVisible(false);
     if (selectedObject) {
       selectedObject(object);
@@ -29,12 +30,12 @@ export const ModalFlatList: FC<Props> = ({ selectedObject, headerTitle }) => {
       <Input
         header={headerTitle}
         isFocused={(b) => setVisible(b)}
-        value={selectedFlatListObject?.title}
+        value={selectedFlatListObject?.name ?? defaultObject?.name}
         inputMode={'none'}
       />
       <Modal
         onRequestClose={() => setVisible(false)}
-        headerTitle={'Select Region of Origin'}
+        headerTitle={headerTitle ?? 'Change me'}
         visible={visible}
       >
         <FlatList itemObject={(object) => onSelect(object)} />

+ 1 - 1
src/components/FlatList/styles.ts

@@ -4,7 +4,7 @@ import { getFontSize } from '../../utils';
 export const styles = StyleSheet.create({
   container: {
     flex: 1,
-    marginTop: StatusBar.currentHeight || 0
+    gap: 15
   },
   item: {
     width: '100%',

+ 51 - 22
src/components/Input/index.tsx

@@ -1,4 +1,4 @@
-import React, { FC, useState } from 'react';
+import React, { FC, ReactNode, useState } from 'react';
 import {
   TextInput,
   Text,
@@ -20,6 +20,9 @@ type Props = {
   active?: boolean;
   onBlur?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
   formikError?: string | boolean;
+  icon?: ReactNode;
+  multiline?: boolean;
+  editable?: boolean;
 };
 
 export const Input: FC<Props> = ({
@@ -31,7 +34,10 @@ export const Input: FC<Props> = ({
   isFocused,
   onBlur,
   value,
-  formikError
+  formikError,
+  icon,
+  multiline,
+  editable
 }) => {
   const [focused, setFocused] = useState(false);
 
@@ -40,26 +46,49 @@ export const Input: FC<Props> = ({
   return (
     <View>
       {header ? <Text style={styles.text}>{header}</Text> : null}
-      <TextInput
-        value={value}
-        inputMode={inputMode ?? 'text'}
-        secureTextEntry={isPrivate ?? false}
-        placeholder={placeholder}
-        onChangeText={onChange}
-        onFocus={() => {
-          setFocused(true);
-          if (isFocused) {
-            isFocused(true);
-          }
-        }}
-        onBlur={(e) => {
-          setFocused(false);
-          if (onBlur) {
-            onBlur(e);
-          }
-        }}
-        style={[styles.wrapper, formikError ? styles.inputError : null]}
-      />
+      <View
+        style={[
+          [styles.wrapper, formikError ? styles.inputError : null],
+          { flexDirection: 'row', alignItems: 'center' },
+          multiline ? { height: 100 } : { height: 44 }
+        ]}
+      >
+        {icon ? (
+          <View
+            style={{
+              height: 44,
+              width: 44,
+              display: 'flex',
+              justifyContent: 'center',
+              alignItems: 'center'
+            }}
+          >
+            {icon}
+          </View>
+        ) : null}
+        <TextInput
+          editable={editable}
+          value={value}
+          inputMode={inputMode ?? 'text'}
+          secureTextEntry={isPrivate ?? false}
+          placeholder={placeholder}
+          onChangeText={onChange}
+          multiline={multiline}
+          onFocus={() => {
+            setFocused(true);
+            if (isFocused) {
+              isFocused(true);
+            }
+          }}
+          onBlur={(e) => {
+            setFocused(false);
+            if (onBlur) {
+              onBlur(e);
+            }
+          }}
+          style={[{ height: '100%', width: '100%' }, !icon ? { padding: 10 } : null]}
+        />
+      </View>
       {formikError ? <Text style={styles.errorText}>{formikError}</Text> : null}
     </View>
   );

+ 1 - 2
src/components/Input/style.ts

@@ -17,8 +17,7 @@ export const styling = (focused: boolean) =>
       borderColor: focused ? Colors.DARK_BLUE : 'rgba(250, 250, 250, 1)',
       borderRadius: 6,
       backgroundColor: 'rgba(250, 250, 250, 1)',
-      fontSize: 15,
-      padding: 10
+      fontSize: 15
     },
     text: {
       color: Colors.DARK_BLUE,

+ 2 - 2
src/components/TabBarButton/index.tsx

@@ -19,7 +19,7 @@ const getTabIcon = (routeName: string) => {
       return TravellersIcon;
     case NAVIGATION_PAGES.TRAVELS_TAB:
       return GlobeIcon;
-    case NAVIGATION_PAGES.PROFILE_TAB:
+    case NAVIGATION_PAGES.IN_APP_PROFILE:
       return ProfileIcon;
     default:
       return null;
@@ -29,7 +29,7 @@ const getTabIcon = (routeName: string) => {
 const TabBarButton = ({
   label,
   onPress,
-  focused,
+  focused
 }: {
   label: string;
   onPress: () => void;