Merge pull request 'amalia/23-jan-26' (#10) from amalia/23-jan-26 into join
Reviewed-on: http://wibugit.wibudev.com/wibu/mobile-darmasaba/pulls/10
This commit is contained in:
@@ -30,7 +30,7 @@ export default function DetailAnnouncement() {
|
|||||||
const { token, decryptToken } = useAuthSession()
|
const { token, decryptToken } = useAuthSession()
|
||||||
const [data, setData] = useState<Props>({ id: '', title: '', desc: '' })
|
const [data, setData] = useState<Props>({ id: '', title: '', desc: '' })
|
||||||
const [dataMember, setDataMember] = useState<any>({})
|
const [dataMember, setDataMember] = useState<any>({})
|
||||||
const [dataFile, setDataFile] = useState<{ id:string; idStorage: string; name: string; extension: string }[]>([])
|
const [dataFile, setDataFile] = useState<{ id: string; idStorage: string; name: string; extension: string }[]>([])
|
||||||
const update = useSelector((state: any) => state.announcementUpdate)
|
const update = useSelector((state: any) => state.announcementUpdate)
|
||||||
const entityUser = useSelector((state: any) => state.user)
|
const entityUser = useSelector((state: any) => state.user)
|
||||||
const contentWidth = Dimensions.get('window').width
|
const contentWidth = Dimensions.get('window').width
|
||||||
@@ -149,8 +149,8 @@ export default function DetailAnnouncement() {
|
|||||||
:
|
:
|
||||||
<>
|
<>
|
||||||
<View style={[Styles.rowItemsCenter, { alignItems: 'flex-start' }]}>
|
<View style={[Styles.rowItemsCenter, { alignItems: 'flex-start' }]}>
|
||||||
<MaterialIcons name="campaign" size={30} color="black" style={Styles.mr05} />
|
<MaterialIcons name="campaign" size={25} color="black" style={[Styles.mr05]} />
|
||||||
<Text style={[Styles.textDefaultSemiBold, Styles.w90]}>{data?.title}</Text>
|
<Text style={[Styles.textDefaultSemiBold, Styles.w90, Styles.mt02]}>{data?.title}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[Styles.mt10]}>
|
<View style={[Styles.mt10]}>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { router, Stack } from "expo-router"
|
|||||||
import * as Sharing from 'expo-sharing'
|
import * as Sharing from 'expo-sharing'
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import { Alert, Image, Platform, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
import { Alert, Image, Platform, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
||||||
|
import ImageViewing from 'react-native-image-viewing'
|
||||||
import * as mime from 'react-native-mime-types'
|
import * as mime from 'react-native-mime-types'
|
||||||
import Toast from "react-native-toast-message"
|
import Toast from "react-native-toast-message"
|
||||||
import { useDispatch, useSelector } from "react-redux"
|
import { useDispatch, useSelector } from "react-redux"
|
||||||
@@ -38,12 +39,13 @@ export default function BannerList() {
|
|||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const [refreshing, setRefreshing] = useState(false)
|
const [refreshing, setRefreshing] = useState(false)
|
||||||
const [loadingOpen, setLoadingOpen] = useState(false)
|
const [loadingOpen, setLoadingOpen] = useState(false)
|
||||||
|
const [viewImg, setViewImg] = useState(false)
|
||||||
|
|
||||||
const handleDeleteEntity = async () => {
|
const handleDeleteEntity = async () => {
|
||||||
try {
|
try {
|
||||||
const hasil = await decryptToken(String(token?.current));
|
const hasil = await decryptToken(String(token?.current));
|
||||||
const deletedEntity = await apiDeleteBanner({ user: hasil }, dataId);
|
const deletedEntity = await apiDeleteBanner({ user: hasil }, dataId);
|
||||||
if (deletedEntity.success ) {
|
if (deletedEntity.success) {
|
||||||
Toast.show({ type: 'small', text1: 'Berhasil menghapus data', })
|
Toast.show({ type: 'small', text1: 'Berhasil menghapus data', })
|
||||||
apiGetBanner({ user: hasil }).then((data) =>
|
apiGetBanner({ user: hasil }).then((data) =>
|
||||||
dispatch(setEntities(data.data))
|
dispatch(setEntities(data.data))
|
||||||
@@ -167,8 +169,14 @@ export default function BannerList() {
|
|||||||
/>
|
/>
|
||||||
<MenuItemRow
|
<MenuItemRow
|
||||||
icon={<MaterialCommunityIcons name="file-eye" color="black" size={25} />}
|
icon={<MaterialCommunityIcons name="file-eye" color="black" size={25} />}
|
||||||
title="Lihat / Share"
|
title="Lihat"
|
||||||
onPress={() => { openFile() }}
|
onPress={() => {
|
||||||
|
setModal(false)
|
||||||
|
setTimeout(() => {
|
||||||
|
setViewImg(true);
|
||||||
|
}, 1000);
|
||||||
|
// openFile()
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<MenuItemRow
|
<MenuItemRow
|
||||||
icon={<Ionicons name="trash" color="black" size={25} />}
|
icon={<Ionicons name="trash" color="black" size={25} />}
|
||||||
@@ -184,6 +192,14 @@ export default function BannerList() {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</DrawerBottom>
|
</DrawerBottom>
|
||||||
|
|
||||||
|
<ImageViewing
|
||||||
|
images={[{ uri: `${ConstEnv.url_storage}/files/${selectFile?.image}` }]}
|
||||||
|
imageIndex={0}
|
||||||
|
visible={viewImg}
|
||||||
|
onRequestClose={() => setViewImg(false)}
|
||||||
|
doubleTapToZoomEnabled
|
||||||
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,7 @@ export default function EditProfile() {
|
|||||||
type="numeric"
|
type="numeric"
|
||||||
placeholder="8XX-XXX-XXX"
|
placeholder="8XX-XXX-XXX"
|
||||||
required
|
required
|
||||||
itemLeft={<Text>+62</Text>}
|
itemLeft={<Text style={[Platform.OS === 'ios' && Styles.mt02]}>+62</Text>}
|
||||||
value={data?.phone}
|
value={data?.phone}
|
||||||
error={error.phone}
|
error={error.phone}
|
||||||
errorText="Nomor Telepon tidak valid"
|
errorText="Nomor Telepon tidak valid"
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ import LabelStatus from "@/components/labelStatus";
|
|||||||
import HeaderRightMemberDetail from "@/components/member/headerMemberDetail";
|
import HeaderRightMemberDetail from "@/components/member/headerMemberDetail";
|
||||||
import Skeleton from "@/components/skeleton";
|
import Skeleton from "@/components/skeleton";
|
||||||
import Text from "@/components/Text";
|
import Text from "@/components/Text";
|
||||||
|
import { assetUserImage } from "@/constants/AssetsError";
|
||||||
import { ConstEnv } from "@/constants/ConstEnv";
|
import { ConstEnv } from "@/constants/ConstEnv";
|
||||||
import { valueRoleUser } from "@/constants/RoleUser";
|
import { valueRoleUser } from "@/constants/RoleUser";
|
||||||
import Styles from "@/constants/Styles";
|
import Styles from "@/constants/Styles";
|
||||||
import { apiGetProfile } from "@/lib/api";
|
import { apiGetProfile } from "@/lib/api";
|
||||||
import { router, Stack, useLocalSearchParams } from "expo-router";
|
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native";
|
import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native";
|
||||||
|
import ImageViewing from 'react-native-image-viewing';
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
@@ -32,12 +34,13 @@ type Props = {
|
|||||||
export default function MemberDetail() {
|
export default function MemberDetail() {
|
||||||
const { id } = useLocalSearchParams<{ id: string }>();
|
const { id } = useLocalSearchParams<{ id: string }>();
|
||||||
const [data, setData] = useState<Props>()
|
const [data, setData] = useState<Props>()
|
||||||
const [error, setError] = useState(false)
|
const [errorImg, setErrorImg] = useState(false)
|
||||||
const entityUser = useSelector((state: any) => state.user)
|
const entityUser = useSelector((state: any) => state.user)
|
||||||
const [isEdit, setEdit] = useState(true)
|
const [isEdit, setEdit] = useState(true)
|
||||||
const arrSkeleton = Array.from({ length: 5 }, (_, index) => index)
|
const arrSkeleton = Array.from({ length: 5 }, (_, index) => index)
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [refreshing, setRefreshing] = useState(false)
|
const [refreshing, setRefreshing] = useState(false)
|
||||||
|
const [preview, setPreview] = useState(false)
|
||||||
|
|
||||||
async function handleLoad(loading: boolean) {
|
async function handleLoad(loading: boolean) {
|
||||||
try {
|
try {
|
||||||
@@ -100,7 +103,9 @@ export default function MemberDetail() {
|
|||||||
</>
|
</>
|
||||||
:
|
:
|
||||||
<>
|
<>
|
||||||
<ImageUser src={`${ConstEnv.url_storage}/files/${data?.img}`} size="lg" />
|
<Pressable onPress={() => setPreview(true)}>
|
||||||
|
<ImageUser src={`${ConstEnv.url_storage}/files/${data?.img}`} size="lg" onError={setErrorImg} />
|
||||||
|
</Pressable>
|
||||||
<Text style={[Styles.textSubtitle, Styles.cWhite, Styles.mt10, { textAlign: 'center' }]}>{data?.name}</Text>
|
<Text style={[Styles.textSubtitle, Styles.cWhite, Styles.mt10, { textAlign: 'center' }]}>{data?.name}</Text>
|
||||||
<Text style={[Styles.textMediumNormal, Styles.cWhite]}>{data?.role}</Text>
|
<Text style={[Styles.textMediumNormal, Styles.cWhite]}>{data?.role}</Text>
|
||||||
</>
|
</>
|
||||||
@@ -136,6 +141,14 @@ export default function MemberDetail() {
|
|||||||
|
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
<ImageViewing
|
||||||
|
images={[{ uri: errorImg ? assetUserImage.uri : `${ConstEnv.url_storage}/files/${data?.img}` }]}
|
||||||
|
imageIndex={0}
|
||||||
|
visible={preview}
|
||||||
|
onRequestClose={() => setPreview(false)}
|
||||||
|
doubleTapToZoomEnabled
|
||||||
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -331,7 +331,7 @@ export default function CreateMember() {
|
|||||||
type="numeric"
|
type="numeric"
|
||||||
placeholder="8XX-XXX-XXX"
|
placeholder="8XX-XXX-XXX"
|
||||||
required
|
required
|
||||||
itemLeft={<Text>+62</Text>}
|
itemLeft={<Text style={[Platform.OS === 'ios' && Styles.mt02]}>+62</Text>}
|
||||||
error={error.phone}
|
error={error.phone}
|
||||||
errorText="Nomor Telepon tidak valid"
|
errorText="Nomor Telepon tidak valid"
|
||||||
onChange={val => {
|
onChange={val => {
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ export default function EditMember() {
|
|||||||
type="numeric"
|
type="numeric"
|
||||||
placeholder="8XX-XXX-XXX"
|
placeholder="8XX-XXX-XXX"
|
||||||
required
|
required
|
||||||
itemLeft={<Text>+62</Text>}
|
itemLeft={<Text style={[Platform.OS === 'ios' && Styles.mt02]}>+62</Text>}
|
||||||
value={data?.phone}
|
value={data?.phone}
|
||||||
error={error.phone}
|
error={error.phone}
|
||||||
errorText="Nomor Telepon tidak valid"
|
errorText="Nomor Telepon tidak valid"
|
||||||
|
|||||||
@@ -3,19 +3,22 @@ import ButtonBackHeader from "@/components/buttonBackHeader";
|
|||||||
import { ButtonHeader } from "@/components/buttonHeader";
|
import { ButtonHeader } from "@/components/buttonHeader";
|
||||||
import ItemDetailMember from "@/components/itemDetailMember";
|
import ItemDetailMember from "@/components/itemDetailMember";
|
||||||
import Text from "@/components/Text";
|
import Text from "@/components/Text";
|
||||||
|
import { assetUserImage } from "@/constants/AssetsError";
|
||||||
import { ConstEnv } from "@/constants/ConstEnv";
|
import { ConstEnv } from "@/constants/ConstEnv";
|
||||||
import Styles from "@/constants/Styles";
|
import Styles from "@/constants/Styles";
|
||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
import { AntDesign } from "@expo/vector-icons";
|
import { AntDesign } from "@expo/vector-icons";
|
||||||
import { router, Stack } from "expo-router";
|
import { router, Stack } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Image, SafeAreaView, ScrollView, View } from "react-native";
|
import { Image, Pressable, SafeAreaView, ScrollView, View } from "react-native";
|
||||||
|
import ImageViewing from 'react-native-image-viewing';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
export default function Profile() {
|
export default function Profile() {
|
||||||
const { signOut } = useAuthSession()
|
const { signOut } = useAuthSession()
|
||||||
const entities = useSelector((state: any) => state.entities)
|
const entities = useSelector((state: any) => state.entities)
|
||||||
const [error, setError] = useState(false)
|
const [error, setError] = useState(false)
|
||||||
|
const [preview, setPreview] = useState(false)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -41,11 +44,13 @@ export default function Profile() {
|
|||||||
<ScrollView style={[Styles.h100]}>
|
<ScrollView style={[Styles.h100]}>
|
||||||
<View style={{ flexDirection: 'column' }}>
|
<View style={{ flexDirection: 'column' }}>
|
||||||
<View style={[Styles.wrapHeadViewMember]}>
|
<View style={[Styles.wrapHeadViewMember]}>
|
||||||
<Image
|
<Pressable onPress={() => setPreview(true)}>
|
||||||
source={error ? require("../../assets/images/user.jpg") : { uri: `${ConstEnv.url_storage}/files/${entities.img}` }}
|
<Image
|
||||||
onError={() => { setError(true) }}
|
source={error ? require("../../assets/images/user.jpg") : { uri: `${ConstEnv.url_storage}/files/${entities.img}` }}
|
||||||
style={[Styles.userProfileBig]}
|
onError={() => { setError(true) }}
|
||||||
/>
|
style={[Styles.userProfileBig]}
|
||||||
|
/>
|
||||||
|
</Pressable>
|
||||||
<Text style={[Styles.textSubtitle, Styles.cWhite, Styles.mt10]}>{entities.name}</Text>
|
<Text style={[Styles.textSubtitle, Styles.cWhite, Styles.mt10]}>{entities.name}</Text>
|
||||||
<Text style={[Styles.textMediumNormal, Styles.cWhite]}>{entities.role}</Text>
|
<Text style={[Styles.textMediumNormal, Styles.cWhite]}>{entities.role}</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -65,6 +70,13 @@ export default function Profile() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
<ImageViewing
|
||||||
|
images={[{ uri: error ? assetUserImage.uri : `${ConstEnv.url_storage}/files/${entities.img}` }]}
|
||||||
|
imageIndex={0}
|
||||||
|
visible={preview}
|
||||||
|
onRequestClose={() => setPreview(false)}
|
||||||
|
doubleTapToZoomEnabled
|
||||||
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,10 @@ export default function ViewLogin({ onValidate }: Props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Toast.show({ type: 'small', text1: response.message, position: 'top' })
|
return Toast.show({ type: 'small', text1: response.message, position: 'bottom' })
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Toast.show({ type: 'small', text1: `Terjadi kesalahan, coba lagi`, position: 'top' })
|
return Toast.show({ type: 'small', text1: `Terjadi kesalahan, coba lagi`, position: 'bottom' })
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingLogin(false)
|
setLoadingLogin(false)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ export default function ViewLogin({ onValidate }: Props) {
|
|||||||
type="numeric"
|
type="numeric"
|
||||||
placeholder="XXX-XXX-XXXX"
|
placeholder="XXX-XXX-XXXX"
|
||||||
round
|
round
|
||||||
itemLeft={<Text>+62</Text>}
|
itemLeft={<Text style={[Platform.OS === 'ios' && Styles.mt02]}>+62</Text>}
|
||||||
info="Kami akan mengirim kode verifikasi melalui WhatsApp, guna mengonfirmasikan nomor Anda." />
|
info="Kami akan mengirim kode verifikasi melalui WhatsApp, guna mengonfirmasikan nomor Anda." />
|
||||||
<ButtonForm
|
<ButtonForm
|
||||||
text="MASUK"
|
text="MASUK"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
const encrypted = await encryptToken(valueUser);
|
const encrypted = await encryptToken(valueUser);
|
||||||
signIn(encrypted);
|
signIn(encrypted);
|
||||||
} else {
|
} else {
|
||||||
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', position: 'top' })
|
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', position: 'bottom' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
if (value === otpFix.toString()) {
|
if (value === otpFix.toString()) {
|
||||||
login()
|
login()
|
||||||
} else {
|
} else {
|
||||||
return Toast.show({ type: 'small', text1: 'Kode OTP tidak sesuai', position: 'top' });
|
return Toast.show({ type: 'small', text1: 'Kode OTP tidak sesuai', position: 'bottom' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,19 @@ type Props = {
|
|||||||
src: string,
|
src: string,
|
||||||
size?: 'sm' | 'xs' | 'lg'
|
size?: 'sm' | 'xs' | 'lg'
|
||||||
border?: boolean
|
border?: boolean
|
||||||
|
onError?: (val:boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ImageUser({ src, size }: Props) {
|
export default function ImageUser({ src, size, onError }: Props) {
|
||||||
const [error, setError] = useState(false)
|
const [error, setError] = useState(false)
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
source={error ? require('../assets/images/user.jpg') : { uri: src }}
|
source={error ? require('../assets/images/user.jpg') : { uri: src }}
|
||||||
style={[size == 'xs' ? Styles.userProfileExtraSmall : size == 'lg' ? Styles.userProfileBig : Styles.userProfileSmall, Styles.borderAll]}
|
style={[size == 'xs' ? Styles.userProfileExtraSmall : size == 'lg' ? Styles.userProfileBig : Styles.userProfileSmall, Styles.borderAll]}
|
||||||
onError={() =>
|
onError={() => {
|
||||||
setError(true)
|
setError(true)
|
||||||
}
|
onError?.(true)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
5
constants/AssetsError.ts
Normal file
5
constants/AssetsError.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { Image } from "react-native";
|
||||||
|
|
||||||
|
export const assetUserImage = Image.resolveAssetSource(
|
||||||
|
require('@/assets/images/user.jpg')
|
||||||
|
);
|
||||||
@@ -394,7 +394,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
||||||
PRODUCT_NAME = "Desa";
|
PRODUCT_NAME = Desa;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
PRODUCT_BUNDLE_IDENTIFIER = mobiledarmasaba.app;
|
||||||
PRODUCT_NAME = "Desa";
|
PRODUCT_NAME = Desa;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Desa/Desa-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
@@ -75,6 +75,7 @@
|
|||||||
"react-native-gesture-handler": "~2.24.0",
|
"react-native-gesture-handler": "~2.24.0",
|
||||||
"react-native-gifted-charts": "^1.4.57",
|
"react-native-gifted-charts": "^1.4.57",
|
||||||
"react-native-image-picker": "^8.2.1",
|
"react-native-image-picker": "^8.2.1",
|
||||||
|
"react-native-image-viewing": "^0.2.2",
|
||||||
"react-native-mime-types": "^2.5.0",
|
"react-native-mime-types": "^2.5.0",
|
||||||
"react-native-modal": "^14.0.0-rc.1",
|
"react-native-modal": "^14.0.0-rc.1",
|
||||||
"react-native-modal-datetime-picker": "^18.0.0",
|
"react-native-modal-datetime-picker": "^18.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user