From 2fa2b05918a6155d2b816ded8ebf74261c4a0b7d Mon Sep 17 00:00:00 2001 From: Mochammad Adhi Buchori Date: Fri, 25 Apr 2025 08:41:08 +0700 Subject: [PATCH] Finalized the destination country dropdown feature in step 2, sub-step 7 of the supporting document --- src/components/TextInput.tsx | 140 +++++++++- src/data/DropdownData/CountryData.tsx | 253 ++++++++++++++++++ src/data/DropdownData/JobData.tsx | 9 + src/data/DropdownData/NationalityData.tsx | 6 + .../Step2SupportingDocsSubStep7.tsx | 6 +- .../Step4DataConfirmationSubStep2.tsx | 116 ++++++-- 6 files changed, 495 insertions(+), 35 deletions(-) create mode 100644 src/data/DropdownData/CountryData.tsx create mode 100644 src/data/DropdownData/JobData.tsx create mode 100644 src/data/DropdownData/NationalityData.tsx diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index d65d6d8..13d275f 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -1,18 +1,26 @@ import * as React from 'react'; -import {Platform, Pressable, StyleSheet, Text, View} from 'react-native'; +import {Image, Platform, Pressable, StyleSheet, Text, View} from 'react-native'; import {TextInput} from 'react-native-paper'; import Icon from 'react-native-vector-icons/MaterialIcons'; import Colors from '../../assets/styles/Colors'; import FontFamily from '../../assets/styles/FontFamily'; import DateTimePicker from '@react-native-community/datetimepicker'; import {useState} from 'react'; -import {Dropdown} from 'react-native-element-dropdown'; +import {Dropdown, SelectCountry} from 'react-native-element-dropdown'; type DropdownItem = { label: string; value: string | number; }; +type DropdownCountryItem = { + value: string; + label: string; + image: { + uri: string; + }; +}; + interface TextInputComponentProps { title?: string; placeholder?: string; @@ -20,7 +28,9 @@ interface TextInputComponentProps { isRequired?: boolean; isDate?: boolean; isDropdown?: boolean; + isDropdownCountry?: boolean; dropdownItemData?: DropdownItem[]; + dropdownCountryItemData?: DropdownCountryItem[]; isDisabled?: boolean; supportText?: string; containerHeight?: any; @@ -34,7 +44,9 @@ const TextInputComponent: React.FC = ({ isRequired = false, isDate = false, isDropdown = false, + isDropdownCountry = false, dropdownItemData, + dropdownCountryItemData, isDisabled = false, supportText, containerHeight, @@ -44,7 +56,13 @@ const TextInputComponent: React.FC = ({ const [selectedDate, setSelectedDate] = useState(undefined); const [formattedDate, setFormattedDate] = useState(''); const [showPicker, setShowPicker] = useState(false); - const [genderValue, setGenderValue] = useState(null); + const [dropdownValue, setDropdownValue] = useState(null); + const [country, setCountry] = useState(null); + const [searchQuery, setSearchQuery] = useState(''); + + const filteredItems = dropdownCountryItemData?.filter(item => + item.label.toLowerCase().includes(searchQuery.toLowerCase()), + ); const inputStyle = [ styles.containerBackground, @@ -76,7 +94,95 @@ const TextInputComponent: React.FC = ({ ); }; + const renderDropdownCountryItem = (item: any) => { + return ( + + + {item.label} + + ); + }; + + const renderLeftIcon = () => { + const selectedItem = filteredItems?.find(item => item.value === country); + if (!selectedItem?.image?.uri) return null; + + return ( + + ); + }; + + const renderInputSearch = ( + searchQuery: string, + setSearchQuery: React.Dispatch>, + ) => { + return ( + + + } + /> + + ); + }; + const renderInput = () => { + if (isDropdownCountry) { + return ( + + {title && ( + + {title} + {isRequired && *} + + )} + + renderInputSearch(searchQuery, setSearchQuery) + } + value={country} + data={filteredItems ?? []} + valueField="value" + labelField="label" + placeholder={placeholder} + searchPlaceholder="Cari" + onChange={item => { + setCountry(item.value); + }} + disable={isDisabled} + renderRightIcon={() => } + renderItem={renderDropdownCountryItem} + renderLeftIcon={renderLeftIcon} + /> + + ); + } + if (isDropdown) { return ( @@ -96,9 +202,9 @@ const TextInputComponent: React.FC = ({ labelField="label" valueField="value" placeholder={placeholder} - value={genderValue} + value={dropdownValue} onChange={item => { - setGenderValue(item.value); + setDropdownValue(item.value); }} disable={isDisabled} renderRightIcon={() => } @@ -233,9 +339,18 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', alignItems: 'center', }, + dropdownCountryItem: { + padding: 16, + gap: 16, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, dropdownTextItem: { flex: 1, fontSize: 13, + ...FontFamily.notoSansRegular, + color: Colors.primary30.color, }, supportText: { marginTop: 8, @@ -251,6 +366,21 @@ const styles = StyleSheet.create({ borderRadius: 12, borderColor: '#e3e3e5', }, + imageCountryStyle: { + width: 32, + height: 20, + borderRadius: 4, + borderWidth: 0.75, + borderColor: Colors.neutral90.color, + }, + inputSearchStyle: { + fontSize: 14, + ...FontFamily.notoSansRegular, + includeFontPadding: false, + }, + searchContainer: { + margin: 16, + }, }); export default TextInputComponent; diff --git a/src/data/DropdownData/CountryData.tsx b/src/data/DropdownData/CountryData.tsx new file mode 100644 index 0000000..0b45ca6 --- /dev/null +++ b/src/data/DropdownData/CountryData.tsx @@ -0,0 +1,253 @@ +const countryData = [ + { + value: '1', + label: 'Indonesia', + image: {uri: 'https://flagcdn.com/w320/id.png'}, + }, + { + value: '2', + label: 'United States', + image: {uri: 'https://flagcdn.com/w320/us.png'}, + }, + {value: '3', label: 'Japan', image: {uri: 'https://flagcdn.com/w320/jp.png'}}, + { + value: '4', + label: 'Germany', + image: {uri: 'https://flagcdn.com/w320/de.png'}, + }, + { + value: '5', + label: 'Australia', + image: {uri: 'https://flagcdn.com/w320/au.png'}, + }, + { + value: '6', + label: 'United Kingdom', + image: {uri: 'https://flagcdn.com/w320/gb.png'}, + }, + { + value: '7', + label: 'Canada', + image: {uri: 'https://flagcdn.com/w320/ca.png'}, + }, + { + value: '8', + label: 'South Korea', + image: {uri: 'https://flagcdn.com/w320/kr.png'}, + }, + { + value: '9', + label: 'France', + image: {uri: 'https://flagcdn.com/w320/fr.png'}, + }, + { + value: '10', + label: 'India', + image: {uri: 'https://flagcdn.com/w320/in.png'}, + }, + { + value: '11', + label: 'China', + image: {uri: 'https://flagcdn.com/w320/cn.png'}, + }, + { + value: '12', + label: 'Brazil', + image: {uri: 'https://flagcdn.com/w320/br.png'}, + }, + { + value: '13', + label: 'Russia', + image: {uri: 'https://flagcdn.com/w320/ru.png'}, + }, + { + value: '14', + label: 'Mexico', + image: {uri: 'https://flagcdn.com/w320/mx.png'}, + }, + { + value: '15', + label: 'Italy', + image: {uri: 'https://flagcdn.com/w320/it.png'}, + }, + { + value: '16', + label: 'Spain', + image: {uri: 'https://flagcdn.com/w320/es.png'}, + }, + { + value: '17', + label: 'Netherlands', + image: {uri: 'https://flagcdn.com/w320/nl.png'}, + }, + { + value: '18', + label: 'Sweden', + image: {uri: 'https://flagcdn.com/w320/se.png'}, + }, + { + value: '19', + label: 'Switzerland', + image: {uri: 'https://flagcdn.com/w320/ch.png'}, + }, + { + value: '20', + label: 'Norway', + image: {uri: 'https://flagcdn.com/w320/no.png'}, + }, + { + value: '21', + label: 'Denmark', + image: {uri: 'https://flagcdn.com/w320/dk.png'}, + }, + { + value: '22', + label: 'Finland', + image: {uri: 'https://flagcdn.com/w320/fi.png'}, + }, + { + value: '23', + label: 'New Zealand', + image: {uri: 'https://flagcdn.com/w320/nz.png'}, + }, + { + value: '24', + label: 'Argentina', + image: {uri: 'https://flagcdn.com/w320/ar.png'}, + }, + { + value: '25', + label: 'South Africa', + image: {uri: 'https://flagcdn.com/w320/za.png'}, + }, + { + value: '26', + label: 'Thailand', + image: {uri: 'https://flagcdn.com/w320/th.png'}, + }, + { + value: '27', + label: 'Malaysia', + image: {uri: 'https://flagcdn.com/w320/my.png'}, + }, + { + value: '28', + label: 'Philippines', + image: {uri: 'https://flagcdn.com/w320/ph.png'}, + }, + { + value: '29', + label: 'Vietnam', + image: {uri: 'https://flagcdn.com/w320/vn.png'}, + }, + { + value: '30', + label: 'Turkey', + image: {uri: 'https://flagcdn.com/w320/tr.png'}, + }, + { + value: '31', + label: 'Saudi Arabia', + image: {uri: 'https://flagcdn.com/w320/sa.png'}, + }, + { + value: '32', + label: 'United Arab Emirates', + image: {uri: 'https://flagcdn.com/w320/ae.png'}, + }, + { + value: '33', + label: 'Qatar', + image: {uri: 'https://flagcdn.com/w320/qa.png'}, + }, + { + value: '34', + label: 'Egypt', + image: {uri: 'https://flagcdn.com/w320/eg.png'}, + }, + { + value: '35', + label: 'Pakistan', + image: {uri: 'https://flagcdn.com/w320/pk.png'}, + }, + { + value: '36', + label: 'Bangladesh', + image: {uri: 'https://flagcdn.com/w320/bd.png'}, + }, + { + value: '37', + label: 'Nepal', + image: {uri: 'https://flagcdn.com/w320/np.png'}, + }, + { + value: '38', + label: 'Sri Lanka', + image: {uri: 'https://flagcdn.com/w320/lk.png'}, + }, + {value: '39', label: 'Iraq', image: {uri: 'https://flagcdn.com/w320/iq.png'}}, + {value: '40', label: 'Iran', image: {uri: 'https://flagcdn.com/w320/ir.png'}}, + { + value: '41', + label: 'Greece', + image: {uri: 'https://flagcdn.com/w320/gr.png'}, + }, + { + value: '42', + label: 'Portugal', + image: {uri: 'https://flagcdn.com/w320/pt.png'}, + }, + { + value: '43', + label: 'Poland', + image: {uri: 'https://flagcdn.com/w320/pl.png'}, + }, + { + value: '44', + label: 'Czech Republic', + image: {uri: 'https://flagcdn.com/w320/cz.png'}, + }, + { + value: '45', + label: 'Ukraine', + image: {uri: 'https://flagcdn.com/w320/ua.png'}, + }, + { + value: '46', + label: 'Hungary', + image: {uri: 'https://flagcdn.com/w320/hu.png'}, + }, + { + value: '47', + label: 'Austria', + image: {uri: 'https://flagcdn.com/w320/at.png'}, + }, + { + value: '48', + label: 'Belgium', + image: {uri: 'https://flagcdn.com/w320/be.png'}, + }, + { + value: '49', + label: 'Chile', + image: {uri: 'https://flagcdn.com/w320/cl.png'}, + }, + { + value: '50', + label: 'Colombia', + image: {uri: 'https://flagcdn.com/w320/co.png'}, + }, + {value: '51', label: 'Peru', image: {uri: 'https://flagcdn.com/w320/pe.png'}}, + { + value: '52', + label: 'Nigeria', + image: {uri: 'https://flagcdn.com/w320/ng.png'}, + }, + { + value: '53', + label: 'Kenya', + image: {uri: 'https://flagcdn.com/w320/ke.png'}, + }, +]; + +export default countryData; diff --git a/src/data/DropdownData/JobData.tsx b/src/data/DropdownData/JobData.tsx new file mode 100644 index 0000000..d6a38c8 --- /dev/null +++ b/src/data/DropdownData/JobData.tsx @@ -0,0 +1,9 @@ +const jobData = [ + {label: 'Software Engineer', value: '1'}, + {label: 'Product Manager', value: '2'}, + {label: 'UI/UX Designer', value: '3'}, + {label: 'Data Analyst', value: '4'}, + {label: 'Digital Marketer', value: '5'}, +]; + +export default jobData; diff --git a/src/data/DropdownData/NationalityData.tsx b/src/data/DropdownData/NationalityData.tsx new file mode 100644 index 0000000..4b0cd9c --- /dev/null +++ b/src/data/DropdownData/NationalityData.tsx @@ -0,0 +1,6 @@ +const nationalityData = [ + {label: 'Warga Negara Indonesia (WNI)', value: '1'}, + {label: 'Warga Negara Asing (WNA)', value: '2'}, +]; + +export default nationalityData; diff --git a/src/screens/regularPassport/steps/Step2SupportingDocs/Step2SupportingDocsSubStep7.tsx b/src/screens/regularPassport/steps/Step2SupportingDocs/Step2SupportingDocsSubStep7.tsx index 49dfe71..e6ab6c8 100644 --- a/src/screens/regularPassport/steps/Step2SupportingDocs/Step2SupportingDocsSubStep7.tsx +++ b/src/screens/regularPassport/steps/Step2SupportingDocs/Step2SupportingDocsSubStep7.tsx @@ -6,8 +6,8 @@ import styles from '../styles'; import TextInputComponent from '../../../../components/TextInput'; import RadioButtonOptionComponent from '../../../../components/RadioButtonOption'; import destinationCountryOptions from '../../../../data/Options/DestinationCountryOptions'; -import destinationCountryData from '../../../../data/DropdownData/DestinationCountryData'; import Colors from '../../../../../assets/styles/Colors'; +import countryData from '../../../../data/DropdownData/CountryData'; type Step2SupportingDocsSubStep7Props = { setSubStep: (step: number) => void; @@ -39,8 +39,8 @@ const Step2SupportingDocsSubStep7 = ({ {destinationCountryOptions.map(option => ( [ + style={({pressed}) => [ styles.subStepButtonBackWrapper, { - transform: [{ scale: pressed ? 0.99 : 1 }], + transform: [{scale: pressed ? 0.99 : 1}], marginBottom: 8, }, - ]} - > + ]}> Kembali - Data di bawah ini harus sesuai dengan keterangan pada KTP pemohon. Data yang bertanda ( - *) wajib diisi. + Data di bawah ini harus sesuai dengan keterangan pada KTP pemohon. + Data yang bertanda ( + *) wajib + diisi. - - Keterangan Pemohon - - + + + Keterangan Pemohon + + + - - Keterangan Ibu Pemohon - - + + + Keterangan Ibu Pemohon + + + - - Keterangan Ayah Pemohon (Opsional) - - + + + Keterangan Ayah Pemohon (Opsional) + + + - - Keterangan Pasangan Pemohon (Opsional) - - + + + Keterangan Pasangan Pemohon (Opsional) + + + setStep(5)} - style={[styles.subStepButtonContained, { marginBottom: 8 }]} - textColor={Colors.neutral100.color} - > + style={[styles.subStepButtonContained, {marginBottom: 8}]} + textColor={Colors.neutral100.color}> Simpan Draft