Browse Source
Reviewed-on: #14 Co-authored-by: YaroslavBerkuta <yaroslavberkuta@gmail.com> Co-committed-by: YaroslavBerkuta <yaroslavberkuta@gmail.com>pull/17/head
17 changed files with 326 additions and 72 deletions
@ -1,7 +1,8 @@
@@ -1,7 +1,8 @@
|
||||
export * from './confirm-modal.smart-component'; |
||||
export * from './info-modal.smart-component'; |
||||
export * from './confirm-modal.smart-component' |
||||
export * from './info-modal.smart-component' |
||||
export * from './date-picker.smart-component' |
||||
export * from './done-task.smart-component' |
||||
export * from './modal-picker-with-pagination.smart-component' |
||||
export * from './fancybox.smart-component' |
||||
export * from './fullscreen-video.smart-component' |
||||
export * from './fullscreen-video.smart-component' |
||||
export * from './select-country-phone.smart-component' |
||||
|
@ -0,0 +1,157 @@
@@ -0,0 +1,157 @@
|
||||
import { |
||||
BottomModal, |
||||
CheckBox, |
||||
SearchForm, |
||||
useEventsListener, |
||||
useTheme, |
||||
} from '@/shared' |
||||
import { PartialTheme } from '@/shared/themes/interfaces' |
||||
import React, { useCallback, useRef, useState } from 'react' |
||||
import { |
||||
StyleSheet, |
||||
Dimensions, |
||||
TouchableOpacity, |
||||
Text, |
||||
View, |
||||
FlatList, |
||||
} from 'react-native' |
||||
import countries, { Countries, Country } from 'world-countries' |
||||
import { $size, cutLongText } from '@/shared/helpers' |
||||
import CountryFlag from 'react-native-country-flag' |
||||
import RBSheet from 'react-native-raw-bottom-sheet' |
||||
|
||||
const screenHeight = Dimensions.get('screen').height |
||||
|
||||
export const SelectCountryPhone = () => { |
||||
const [list, setList] = useState<Countries | null>(null) |
||||
const sheetRef = useRef<RBSheet>(null) |
||||
const { styles } = useTheme(createStyles) |
||||
const [currentIso, setCurrentIso] = useState<string>('') |
||||
const settingsRef = useRef({ |
||||
send: null, |
||||
}).current |
||||
|
||||
const search = useCallback((searchTerm: string) => { |
||||
if (!!searchTerm && searchTerm.length > 0) { |
||||
setList(prev => |
||||
prev?.filter((it: Country) => |
||||
it.name.common |
||||
.toLowerCase() |
||||
.includes(searchTerm.toLowerCase()), |
||||
), |
||||
) |
||||
} else { |
||||
setList(countries) |
||||
} |
||||
}, []) |
||||
|
||||
useEventsListener( |
||||
'selectCountryCode', |
||||
data => { |
||||
sheetRef.current.open() |
||||
settingsRef.send = data.onSelect |
||||
setCurrentIso(data.currentIso) |
||||
setList(countries) |
||||
}, |
||||
[sheetRef.current, settingsRef], |
||||
) |
||||
|
||||
const close = useCallback(() => { |
||||
sheetRef.current.close() |
||||
}, []) |
||||
|
||||
const select = useCallback( |
||||
(iso: string, code: string) => { |
||||
setCurrentIso(iso) |
||||
settingsRef.send({ iso, code }) |
||||
close() |
||||
}, |
||||
[close], |
||||
) |
||||
|
||||
const renderItem = ({ item }: { item: Country }) => ( |
||||
<TouchableOpacity |
||||
style={styles.item} |
||||
key={item.cca2} |
||||
onPress={() => |
||||
select(item.cca2, item.idd.root + item.idd.suffixes[0]) |
||||
}> |
||||
<View style={styles.flagWrapper}> |
||||
<CountryFlag |
||||
isoCode={item.cca2} |
||||
size={$size(18)} |
||||
style={{ marginRight: 10 }} |
||||
/> |
||||
<Text style={styles.code}> |
||||
{cutLongText( |
||||
`${item?.idd?.root}${item?.idd?.suffixes[0] || ''}`, |
||||
5, |
||||
)} |
||||
</Text> |
||||
</View> |
||||
<Text style={styles.label}> |
||||
{cutLongText(item.name.common, 20)} |
||||
</Text> |
||||
<CheckBox |
||||
isChecked={item.cca2 === currentIso} |
||||
onPress={() => |
||||
select(item.cca2, item.idd.root + item.idd.suffixes[0]) |
||||
} |
||||
/> |
||||
</TouchableOpacity> |
||||
) |
||||
|
||||
return ( |
||||
<BottomModal |
||||
wrapperStyle={{ justifyContent: 'flex-start' }} |
||||
closeOnPressMask |
||||
sheetRef={ref => (sheetRef.current = ref)} |
||||
height={screenHeight - 250} |
||||
containerStyle={{ paddingHorizontal: 0 }}> |
||||
<View style={{ width: '100%' }}> |
||||
<SearchForm |
||||
searchValue={''} |
||||
containerStyle={styles.searchContainer} |
||||
placeholder="Знайдіть свою країну" |
||||
onChange={search} |
||||
/> |
||||
<FlatList data={list} renderItem={renderItem} /> |
||||
</View> |
||||
</BottomModal> |
||||
) |
||||
} |
||||
const createStyles = (theme: PartialTheme) => |
||||
StyleSheet.create({ |
||||
container: { |
||||
backgroundColor: theme.$layoutBg, |
||||
paddingHorizontal: $size(20), |
||||
}, |
||||
searchContainer: {}, |
||||
item: { |
||||
backgroundColor: '#fff', |
||||
marginHorizontal: $size(20), |
||||
marginVertical: $size(8), |
||||
padding: $size(12), |
||||
borderRadius: $size(10), |
||||
flexDirection: 'row', |
||||
alignItems: 'center', |
||||
}, |
||||
label: { |
||||
marginRight: 'auto', |
||||
fontSize: $size(16), |
||||
}, |
||||
flag: { |
||||
fontSize: 24, |
||||
marginRight: $size(5), |
||||
}, |
||||
code: { |
||||
marginRight: $size(24), |
||||
fontSize: $size(16), |
||||
overflow: 'hidden', |
||||
}, |
||||
flagWrapper: { |
||||
width: 90, |
||||
flexDirection: 'row', |
||||
alignItems: 'center', |
||||
}, |
||||
}) |
@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
|
||||
export const cutLongText = (txt: string, length: number): string => { |
||||
if (txt.length > length) { |
||||
const cuttingTxt = txt.slice(0, length) |
||||
if (txt.length > length) { |
||||
const cuttingTxt = txt.slice(0, length) |
||||
|
||||
return `${cuttingTxt}...` |
||||
} |
||||
return `${cuttingTxt}...` |
||||
} |
||||
|
||||
return txt |
||||
return txt |
||||
} |
||||
|
||||
export const getLinksFromTxt = (txt: string) => |
||||
txt?.match(/\bhttp(s)?:(:)?\/\/\S+/gi) |
||||
txt?.match(/\bhttp(s)?:(:)?\/\/\S+/gi) |
||||
|
Loading…
Reference in new issue