Compare commits
25 Commits
amalia/22-
...
amalia/02-
| Author | SHA1 | Date | |
|---|---|---|---|
| 1122e51047 | |||
| 265656413d | |||
| db0f0ecd6c | |||
| 24e1ace521 | |||
| 019c0a5e33 | |||
| 4250ca3057 | |||
| c775b06dc3 | |||
| 77cd07ad7a | |||
| c35e2e65bd | |||
| 6a24b95cdd | |||
| 92c58524f6 | |||
| 7d5ec511f5 | |||
| 3de8e628b6 | |||
| e9f1b14bd6 | |||
| 9607774056 | |||
| 07caea8ae5 | |||
| 94c48889c6 | |||
| d0849143f2 | |||
| a7aeb3d3f9 | |||
| e755273ab1 | |||
| d460653408 | |||
| bb242c9be8 | |||
| c01a1885c2 | |||
| 2651e4bd18 | |||
| 171c5f0eeb |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -44,4 +44,4 @@ x.ts
|
||||
x.sh
|
||||
|
||||
google-services.json
|
||||
mobile-darmasaba-firebase-adminsdk-fbsvc-f5abb292b5.json
|
||||
service-account.json
|
||||
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
expo: {
|
||||
name: "mobile-darmasaba",
|
||||
slug: "mobile-darmasaba",
|
||||
version: "1.0.0",
|
||||
version: "1.0.1",
|
||||
jsEngine: "jsc",
|
||||
orientation: "portrait",
|
||||
icon: "./assets/images/icon.png",
|
||||
@@ -21,6 +21,7 @@ export default {
|
||||
},
|
||||
android: {
|
||||
package: "mobiledarmasaba.app",
|
||||
versionCode: 2,
|
||||
adaptiveIcon: {
|
||||
foregroundImage: "./assets/images/splash-icon.png",
|
||||
backgroundColor: "#ffffff"
|
||||
|
||||
@@ -148,7 +148,7 @@ export default function RootLayout() {
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<StatusBar style="light" translucent={false} backgroundColor="black" />
|
||||
<StatusBar style="inverted" translucent={false} backgroundColor="black" />
|
||||
<ToastCustom />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
@@ -99,7 +99,7 @@ export default function CreateAnnouncement() {
|
||||
headerTitleAlign: "center",
|
||||
headerRight: () => (
|
||||
<ButtonSaveHeader
|
||||
disable={disableBtn || loading ? true : false}
|
||||
disable={disableBtn || divisionMember.length == 0 || loading ? true : false}
|
||||
category="create"
|
||||
onPress={() => {
|
||||
divisionMember.length == 0
|
||||
|
||||
@@ -114,7 +114,7 @@ export default function Announcement() {
|
||||
</View>
|
||||
}
|
||||
title={item.title}
|
||||
desc={item.desc.replace(/<[^>]*>?/gm, '')}
|
||||
desc={item.desc.replace(/<[^>]*>?/gm, '').replace(/\r?\n|\r/g, ' ')}
|
||||
rightTopInfo={item.createdAt}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -153,7 +153,7 @@ export default function Discussion() {
|
||||
status != "false" && <LabelStatus category={item.status === 1 ? "success" : "error"} text={item.status === 1 ? "BUKA" : "TUTUP"} size="small" />
|
||||
}
|
||||
rightTopInfo={item.createdAt}
|
||||
desc={item.desc}
|
||||
desc={item.desc.replace(/<[^>]*>?/gm, ' ').replace(/\r?\n|\r/g, ' ')}
|
||||
leftBottomInfo={
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
<Ionicons name="chatbox-ellipses-outline" size={18} color="grey" style={Styles.mr05} />
|
||||
@@ -176,34 +176,6 @@ export default function Discussion() {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
// data.map((item: any, i: number) => {
|
||||
// return (
|
||||
// <BorderBottomItem
|
||||
// key={i}
|
||||
// onPress={() => { router.push(`/discussion/${item.id}`) }}
|
||||
// borderType="bottom"
|
||||
// icon={
|
||||
// <View style={[Styles.iconContent, ColorsStatus.lightGreen]}>
|
||||
// <MaterialIcons name="chat" size={25} color={'#384288'} />
|
||||
// </View>
|
||||
// }
|
||||
// title={item.title}
|
||||
// subtitle={
|
||||
// status != "false" && <LabelStatus category={item.status === 1 ? "success" : "error"} text={item.status === 1 ? "BUKA" : "TUTUP"} size="small" />
|
||||
// }
|
||||
// rightTopInfo={item.createdAt}
|
||||
// desc={item.desc}
|
||||
// leftBottomInfo={
|
||||
// <View style={[Styles.rowItemsCenter]}>
|
||||
// <Ionicons name="chatbox-ellipses-outline" size={18} color="grey" style={Styles.mr05} />
|
||||
// <Text style={[Styles.textInformation, Styles.cGray, Styles.mb05]}>Diskusikan</Text>
|
||||
// </View>
|
||||
// }
|
||||
// rightBottomInfo={`${item.total_komentar} Komentar`}
|
||||
|
||||
// />
|
||||
// )
|
||||
// })
|
||||
:
|
||||
<Text style={[Styles.textDefault, Styles.cGray, { textAlign: 'center' }]}>Tidak ada data</Text>
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ import { apiDeleteCalendarMember, apiGetCalendarOne, apiGetDivisionOneFeature }
|
||||
import { setUpdateCalendar } from "@/lib/calendarUpdate"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import { MaterialCommunityIcons } from "@expo/vector-icons"
|
||||
import Clipboard from "@react-native-clipboard/clipboard"
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router"
|
||||
import { useEffect, useState } from "react"
|
||||
import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
||||
import { Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native"
|
||||
import Toast from "react-native-toast-message"
|
||||
import { useDispatch, useSelector } from "react-redux"
|
||||
|
||||
@@ -115,6 +116,11 @@ export default function DetailEventCalendar() {
|
||||
handleLoadMember();
|
||||
}, [update.member]);
|
||||
|
||||
const handleCopy = (text: string) => {
|
||||
Clipboard.setString(text);
|
||||
Toast.show({ type: 'small', text1: 'Berhasil menyalin link', })
|
||||
};
|
||||
|
||||
async function handleDeleteUser() {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
@@ -216,10 +222,14 @@ export default function DetailEventCalendar() {
|
||||
loading ?
|
||||
<Skeleton width={80} height={10} borderRadius={10} widthType="percent" />
|
||||
:
|
||||
<Text style={[Styles.textDefault]}>{data?.linkMeet ? data.linkMeet : '-'}</Text>
|
||||
data?.linkMeet ?
|
||||
<Pressable onPress={() => { handleCopy(data.linkMeet) }}>
|
||||
<Text style={[Styles.textDefault]}>{data.linkMeet}</Text>
|
||||
</Pressable>
|
||||
: <Text style={[Styles.textDefault]}>-</Text>
|
||||
}
|
||||
</View>
|
||||
<View style={[Styles.rowItemsCenter, Styles.mt10, {alignItems:'flex-start'}]}>
|
||||
<View style={[Styles.rowItemsCenter, Styles.mt10, { alignItems: 'flex-start' }]}>
|
||||
<MaterialCommunityIcons name="card-text-outline" size={30} color="black" style={Styles.mr10} />
|
||||
{
|
||||
loading ?
|
||||
|
||||
@@ -65,6 +65,7 @@ type PropsPath = {
|
||||
};
|
||||
|
||||
export default function DocumentDivision() {
|
||||
const [loadingRename, setLoadingRename] = useState(false)
|
||||
const [isShare, setShare] = useState(false)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const { id } = useLocalSearchParams<{ id: string }>()
|
||||
@@ -201,6 +202,7 @@ export default function DocumentDivision() {
|
||||
|
||||
async function handleRename() {
|
||||
try {
|
||||
setLoadingRename(true)
|
||||
const hasil = await decryptToken(String(token?.current));
|
||||
const response = await apiDocumentRename({ user: hasil, ...bodyRename });
|
||||
if (response.success) {
|
||||
@@ -214,7 +216,8 @@ export default function DocumentDivision() {
|
||||
console.error(error);
|
||||
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||
} finally {
|
||||
setRename(false);
|
||||
setLoadingRename(false)
|
||||
setRename(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,25 +363,20 @@ export default function DocumentDivision() {
|
||||
<View style={[Styles.p15, Styles.mb100]}>
|
||||
<View style={[Styles.rowItemsCenter]}>
|
||||
{
|
||||
loading ?
|
||||
arrSkeleton.map((item, index) => (
|
||||
<Skeleton key={index} width={60} height={10} borderRadius={10} style={[Styles.mr05]} />
|
||||
))
|
||||
:
|
||||
dataJalur.map((item, index) => (
|
||||
<Pressable
|
||||
key={index}
|
||||
style={[Styles.rowItemsCenter]}
|
||||
onPress={() => {
|
||||
setPath(item.id);
|
||||
}}
|
||||
>
|
||||
{item.id != "home" && (
|
||||
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} color="black" />
|
||||
)}
|
||||
<Text> {item.name} </Text>
|
||||
</Pressable>
|
||||
))
|
||||
dataJalur.map((item, index) => (
|
||||
<Pressable
|
||||
key={index}
|
||||
style={[Styles.rowItemsCenter]}
|
||||
onPress={() => {
|
||||
setPath(item.id);
|
||||
}}
|
||||
>
|
||||
{item.id != "home" && (
|
||||
<AntDesign name="right" style={[Styles.mh05, Styles.mt02]} color="black" />
|
||||
)}
|
||||
<Text> {item.name} </Text>
|
||||
</Pressable>
|
||||
))
|
||||
}
|
||||
</View>
|
||||
<View>
|
||||
@@ -538,7 +536,7 @@ export default function DocumentDivision() {
|
||||
isVisible={isRename}
|
||||
setVisible={() => { setRename(false) }}
|
||||
onSubmit={() => { handleRename() }}
|
||||
disableSubmit={bodyRename.name == ""}
|
||||
disableSubmit={bodyRename.name == "" || loadingRename}
|
||||
>
|
||||
<View>
|
||||
<InputForm
|
||||
|
||||
@@ -7,6 +7,7 @@ import ImageUser from "@/components/imageNew"
|
||||
import SectionCancel from "@/components/sectionCancel"
|
||||
import Skeleton from "@/components/skeleton"
|
||||
import SkeletonTwoItem from "@/components/skeletonTwoItem"
|
||||
import Text from "@/components/Text"
|
||||
import { ColorsStatus } from "@/constants/ColorsStatus"
|
||||
import { ConstEnv } from "@/constants/ConstEnv"
|
||||
import Styles from "@/constants/Styles"
|
||||
@@ -15,7 +16,7 @@ import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import { Feather, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"
|
||||
import { router, Stack, useLocalSearchParams } from "expo-router"
|
||||
import { useEffect, useState } from "react"
|
||||
import { Pressable, SafeAreaView, ScrollView, Text, View } from "react-native"
|
||||
import { Pressable, SafeAreaView, ScrollView, View } from "react-native"
|
||||
import Toast from "react-native-toast-message"
|
||||
import { useSelector } from "react-redux"
|
||||
|
||||
|
||||
@@ -51,9 +51,8 @@ export default function CreateDivisionAddAdmin() {
|
||||
async function handleAddMember() {
|
||||
try {
|
||||
setLoading(true)
|
||||
dispatch(setFormCreateDivision({ ...update, admin: selectMember }))
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreateDivision({ ...update, user: hasil })
|
||||
const response = await apiCreateDivision({ ...update, admin: selectMember, user: hasil })
|
||||
if (response.success) {
|
||||
Toast.show({ type: 'small', text1: 'Berhasil membuat divisi', })
|
||||
dispatch(setFormCreateDivision({ admin: [], member: [], data: { idGroup: '', name: '', desc: '' } }))
|
||||
|
||||
@@ -122,7 +122,7 @@ export default function EditProfile() {
|
||||
}
|
||||
} else if (cat == "phone") {
|
||||
setData({ ...data, phone: val });
|
||||
if (val == "" || !(val.length >= 10 && val.length <= 15)) {
|
||||
if (val == "" || !(val.length >= 9 && val.length <= 16)) {
|
||||
setError({ ...error, phone: true });
|
||||
} else {
|
||||
setError({ ...error, phone: false });
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function Index() {
|
||||
const arrSkeleton = Array.from({ length: 5 }, (_, index) => index)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [status, setStatus] = useState<'true' | 'false'>('true')
|
||||
|
||||
const [loadingSubmit, setLoadingSubmit] = useState(false)
|
||||
const [idChoose, setIdChoose] = useState('')
|
||||
const [activeChoose, setActiveChoose] = useState(true)
|
||||
const [titleChoose, setTitleChoose] = useState('')
|
||||
@@ -49,12 +49,14 @@ export default function Index() {
|
||||
|
||||
async function handleEdit() {
|
||||
try {
|
||||
setLoadingSubmit(true)
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiEditGroup({ user: hasil, name: titleChoose }, idChoose)
|
||||
dispatch(setUpdateGroup(!update))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setLoadingSubmit(false)
|
||||
setVisibleEdit(false)
|
||||
setModal(false)
|
||||
Toast.show({ type: 'small', text1: 'Berhasil mengupdate data', })
|
||||
@@ -234,7 +236,7 @@ export default function Index() {
|
||||
onChange={(val) => { validationForm(val, 'title') }} />
|
||||
</View>
|
||||
<View>
|
||||
<ButtonForm text="SIMPAN" disabled={Object.values(error).some((v) => v == true) || titleChoose == ""} onPress={() => { handleEdit() }} />
|
||||
<ButtonForm text="SIMPAN" disabled={Object.values(error).some((v) => v == true) || titleChoose == "" || loadingSubmit} onPress={() => { handleEdit() }} />
|
||||
</View>
|
||||
</View>
|
||||
</DrawerBottom>
|
||||
|
||||
@@ -22,8 +22,8 @@ import { useDispatch, useSelector } from "react-redux";
|
||||
export default function Home() {
|
||||
const entities = useSelector((state: any) => state.entities)
|
||||
const dispatch = useDispatch()
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const insets = useSafeAreaInsets();
|
||||
const { token, decryptToken, signOut } = useAuthSession()
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
useEffect(() => {
|
||||
handleUserLogin()
|
||||
@@ -31,7 +31,11 @@ export default function Home() {
|
||||
|
||||
async function handleUserLogin() {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
apiGetProfile({ id: hasil }).then((data) => dispatch(setEntities(data.data)));
|
||||
apiGetProfile({ id: hasil })
|
||||
.then((data) => dispatch(setEntities(data.data)))
|
||||
.catch((error) => {
|
||||
signOut()
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function CreateMember() {
|
||||
}
|
||||
} else if (cat == "phone") {
|
||||
setDataForm({ ...dataForm, phone: val });
|
||||
if (val == "" || !(val.length >= 10 && val.length <= 15)) {
|
||||
if (val == "" || !(val.length >= 9 && val.length <= 16)) {
|
||||
setError({ ...error, phone: true });
|
||||
} else {
|
||||
setError({ ...error, phone: false });
|
||||
|
||||
@@ -149,7 +149,7 @@ export default function EditMember() {
|
||||
}
|
||||
} else if (cat == "phone") {
|
||||
setData({ ...data, phone: val });
|
||||
if (val == "" || !(val.length >= 10 && val.length <= 15)) {
|
||||
if (val == "" || !(val.length >= 9 && val.length <= 16)) {
|
||||
setError({ ...error, phone: true });
|
||||
} else {
|
||||
setError({ ...error, phone: false });
|
||||
|
||||
@@ -40,6 +40,7 @@ export default function Index() {
|
||||
const [data, setData] = useState<Props[]>([])
|
||||
const [search, setSearch] = useState('')
|
||||
const [nameGroup, setNameGroup] = useState('')
|
||||
const [loadingSubmit, setLoadingSubmit] = useState(false)
|
||||
const [chooseData, setChooseData] = useState({ name: '', id: '', active: false, idGroup: '' })
|
||||
const [error, setError] = useState({
|
||||
name: false,
|
||||
@@ -94,15 +95,20 @@ export default function Index() {
|
||||
|
||||
async function handleEdit() {
|
||||
try {
|
||||
setLoadingSubmit(true)
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiEditPosition({ user: hasil, name: chooseData.name, idGroup: chooseData.idGroup }, chooseData.id)
|
||||
dispatch(setUpdatePosition(!update))
|
||||
if (response.success) {
|
||||
dispatch(setUpdatePosition(!update))
|
||||
} else {
|
||||
Toast.show({ type: 'small', text1: response.message, })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setLoadingSubmit(false)
|
||||
setVisibleEdit(false)
|
||||
setModal(false)
|
||||
Toast.show({ type: 'small', text1: 'Berhasil mengupdate data', })
|
||||
}
|
||||
|
||||
}
|
||||
@@ -251,7 +257,7 @@ export default function Index() {
|
||||
/>
|
||||
</View>
|
||||
<View style={Styles.mb30}>
|
||||
<ButtonForm text="SIMPAN" onPress={() => { checkForm() }} />
|
||||
<ButtonForm text="SIMPAN" onPress={() => { handleEdit() }} disabled={Object.values(error).some((v) => v == true) || chooseData.name == "" || loadingSubmit} />
|
||||
</View>
|
||||
</View>
|
||||
</DrawerBottom>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import ViewLogin from "@/components/auth/viewLogin";
|
||||
import ViewVerification from "@/components/auth/viewVerification";
|
||||
import Text from '@/components/Text';
|
||||
import ToastCustom from "@/components/toastCustom";
|
||||
import { requestPermission } from "@/lib/useNotification";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { Redirect } from "expo-router";
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiCheckPhoneLogin, apiSendOtp } from "@/lib/api"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage"
|
||||
import { StatusBar } from "expo-status-bar"
|
||||
import { useState } from "react"
|
||||
import { Image, SafeAreaView, View } from "react-native"
|
||||
import { Image, Platform, SafeAreaView, View } from "react-native"
|
||||
import Toast from "react-native-toast-message"
|
||||
import { ButtonForm } from "../buttonForm"
|
||||
import { InputForm } from "../inputForm"
|
||||
@@ -10,7 +12,6 @@ import ModalLoading from "../modalLoading"
|
||||
import Text from "../Text"
|
||||
import ToastCustom from "../toastCustom"
|
||||
|
||||
|
||||
type Props = {
|
||||
onValidate: ({ phone, otp }: { phone: string, otp: number }) => void
|
||||
}
|
||||
@@ -19,23 +20,29 @@ export default function ViewLogin({ onValidate }: Props) {
|
||||
const [loadingLogin, setLoadingLogin] = useState(false)
|
||||
const [disableLogin, setDisableLogin] = useState(true)
|
||||
const [phone, setPhone] = useState('')
|
||||
const { signIn, encryptToken } = useAuthSession();
|
||||
|
||||
const handleCheckPhone = async () => {
|
||||
try {
|
||||
setLoadingLogin(true)
|
||||
const response = await apiCheckPhoneLogin({ phone: `62${phone}` });
|
||||
const response = await apiCheckPhoneLogin({ phone: `62${phone}` })
|
||||
if (response.success) {
|
||||
const otp = Math.floor(1000 + Math.random() * 9000)
|
||||
const responseOtp = await apiSendOtp({ phone: `62${phone}`, otp })
|
||||
if (responseOtp == 200) {
|
||||
// localStorage.setItem('user', response.id)
|
||||
await AsyncStorage.setItem('user', response.id);
|
||||
return onValidate({ phone: `62${phone}`, otp })
|
||||
if (response.isWithoutOTP) {
|
||||
const encrypted = await encryptToken(response.id)
|
||||
signIn(encrypted)
|
||||
} else {
|
||||
const otp = Math.floor(1000 + Math.random() * 9000)
|
||||
const responseOtp = await apiSendOtp({ phone: `62${phone}`, otp })
|
||||
if (responseOtp == 200) {
|
||||
await AsyncStorage.setItem('user', response.id)
|
||||
return onValidate({ phone: `62${phone}`, otp })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Toast.show({ type: 'small', text1: response.message, position: 'top' })
|
||||
}
|
||||
return Toast.show({ type: 'small', text1: response.message, })
|
||||
} catch (error) {
|
||||
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', position: 'top' })
|
||||
} finally {
|
||||
setLoadingLogin(false)
|
||||
}
|
||||
@@ -43,6 +50,7 @@ export default function ViewLogin({ onValidate }: Props) {
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<StatusBar style={Platform.OS === 'ios' ? 'auto' : 'light'} translucent={false} backgroundColor="black" />
|
||||
<ToastCustom />
|
||||
<View style={[Styles.p20, Styles.h100]}>
|
||||
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||
|
||||
@@ -2,8 +2,9 @@ import Styles from "@/constants/Styles";
|
||||
import { apiSendOtp } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import { useState } from "react";
|
||||
import { Image, View } from "react-native";
|
||||
import { Image, Platform, View } from "react-native";
|
||||
import { OtpInput } from "react-native-otp-entry";
|
||||
import Toast from 'react-native-toast-message';
|
||||
import { ButtonForm } from "../buttonForm";
|
||||
@@ -27,7 +28,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
||||
const encrypted = await encryptToken(valueUser);
|
||||
signIn(encrypted);
|
||||
} else {
|
||||
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', position: 'top' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +36,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
||||
if (value === otpFix.toString()) {
|
||||
login()
|
||||
} else {
|
||||
return Toast.show({ type: 'small', text1: 'Kode OTP tidak sesuai' });
|
||||
return Toast.show({ type: 'small', text1: 'Kode OTP tidak sesuai', position: 'top' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +57,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<StatusBar style={Platform.OS === 'ios' ? 'auto' : 'light'} translucent={false} backgroundColor="black"/>
|
||||
<ToastCustom />
|
||||
<View style={Styles.wrapLogin} >
|
||||
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||
|
||||
@@ -48,7 +48,7 @@ export default function BorderBottomItem({ title, subtitle, icon, desc, onPress,
|
||||
</View>
|
||||
|
||||
</View>
|
||||
{desc && <Text style={[Styles.textDefault, Styles.mt05, { textAlign: 'justify', color: textColorFix }]} numberOfLines={descEllipsize == false ? 0 : 2} ellipsizeMode='tail'>{desc}</Text>}
|
||||
{desc && <Text style={[Styles.textDefault, Styles.mt05, { textAlign: 'left', color: textColorFix }]} numberOfLines={descEllipsize == false ? 0 : 2} ellipsizeMode='tail'>{desc}</Text>}
|
||||
{
|
||||
(leftBottomInfo || rightBottomInfo) &&
|
||||
(
|
||||
|
||||
@@ -24,9 +24,11 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.dokumenUpdate)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [loadingFolder, setLoadingFolder] = useState(false)
|
||||
|
||||
async function handleCreateFolder() {
|
||||
try {
|
||||
setLoadingFolder(true)
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreateFolderDocument({ data: { user: hasil, name, path, idDivision: id } })
|
||||
if (response.success) {
|
||||
@@ -39,6 +41,7 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
||||
console.error(error)
|
||||
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||
} finally {
|
||||
setLoadingFolder(false)
|
||||
setNewFolder(false)
|
||||
}
|
||||
}
|
||||
@@ -148,7 +151,7 @@ export default function HeaderRightDocument({ path }: { path: string }) {
|
||||
title="Buat Folder Baru"
|
||||
isVisible={newFolder}
|
||||
setVisible={() => { setNewFolder(false) }}
|
||||
disableSubmit={name == ""}
|
||||
disableSubmit={name == "" || loadingFolder}
|
||||
onSubmit={() => { handleCreateFolder() }}
|
||||
>
|
||||
<View>
|
||||
|
||||
65
components/document/modalNewFolder.tsx
Normal file
65
components/document/modalNewFolder.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import Styles from "@/constants/Styles";
|
||||
import { apiCreateFolderDocument } from "@/lib/api";
|
||||
import { useAuthSession } from "@/providers/AuthProvider";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { Pressable, View } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
import Text from "../Text";
|
||||
import { InputForm } from "../inputForm";
|
||||
import ModalFloat from "../modalFloat";
|
||||
|
||||
export function ModalNewFolder({ path, onCreated }: { path: string, onCreated: () => void }) {
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const [newFolder, setNewFolder] = useState(false)
|
||||
const [name, setName] = useState("")
|
||||
const [loadingFolder, setLoadingFolder] = useState(false)
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
|
||||
|
||||
async function handleCreateFolder() {
|
||||
try {
|
||||
setLoadingFolder(true)
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreateFolderDocument({ data: { user: hasil, name, path, idDivision: id } })
|
||||
if (response.success) {
|
||||
Toast.show({ type: 'small', text1: 'Berhasil membuat folder baru', })
|
||||
} else {
|
||||
Toast.show({ type: 'small', text1: response.message, })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||
} finally {
|
||||
onCreated()
|
||||
setLoadingFolder(false)
|
||||
setNewFolder(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => setNewFolder(true)}>
|
||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>FOLDER BARU</Text>
|
||||
</Pressable>
|
||||
|
||||
<ModalFloat
|
||||
title="Buat Folder Baru"
|
||||
isVisible={newFolder}
|
||||
setVisible={() => { setNewFolder(false) }}
|
||||
disableSubmit={name == "" || loadingFolder}
|
||||
onSubmit={() => { handleCreateFolder() }}
|
||||
>
|
||||
<View>
|
||||
<InputForm
|
||||
type="default"
|
||||
placeholder="Nama Folder"
|
||||
required
|
||||
label="Nama Folder"
|
||||
onChange={(value: string) => { setName(value) }}
|
||||
/>
|
||||
</View>
|
||||
</ModalFloat>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { Pressable, View } from "react-native"
|
||||
import BorderBottomItem from "../borderBottomItem"
|
||||
import DrawerBottom from "../drawerBottom"
|
||||
import Text from "../Text"
|
||||
import { ModalNewFolder } from "./modalNewFolder"
|
||||
|
||||
type Props = {
|
||||
open: boolean
|
||||
@@ -106,9 +107,7 @@ export default function ModalSalinMove({ open, close, category, onConfirm, dataC
|
||||
}
|
||||
</View>
|
||||
<View style={[Styles.rowOnly, Styles.mt15, Styles.absolute0]}>
|
||||
<Pressable style={[Styles.pv05, Styles.borderRight, { width: '50%' }]} onPress={() => close(false)}>
|
||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>BATAL</Text>
|
||||
</Pressable>
|
||||
<ModalNewFolder path={path} onCreated={() => getData()} />
|
||||
<Pressable style={[Styles.pv05, { width: '50%' }]} onPress={() => onConfirm(path)}>
|
||||
<Text style={[Styles.textDefaultSemiBold, { textAlign: 'center' }]}>{category == 'copy' ? 'SALIN' : 'PINDAH'}</Text>
|
||||
</Pressable>
|
||||
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
|
||||
export default function ImageWithLabel({ src, label, onClick }: Props) {
|
||||
return (
|
||||
<TouchableOpacity style={[Styles.contentItemCenter, Styles.mh05, { width: 70 }]} onPress={onClick}>
|
||||
<TouchableOpacity style={[Styles.contentItemCenter, Styles.mh03, { width: 55 }]} onPress={onClick}>
|
||||
<ImageUser src={src} border />
|
||||
<Text numberOfLines={1} ellipsizeMode="tail" style={[{ textAlign: 'center' }]}>{label}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -28,7 +28,7 @@ type Props = {
|
||||
export function InputDate({ label, value, placeholder, onChange, info, disable, error, errorText, required, mode, round, width, }: Props) {
|
||||
const [modal, setModal] = useState(false);
|
||||
const [valueFix, setValueFix] = useState(new Date())
|
||||
const [valueFirst, setValueFirst] = useState("")
|
||||
const [valueFirst, setValueFirst] = useState(mode == "date" ? dayjs(new Date()).format("DD-MM-YYYY") : mode == "time" ? dayjs(new Date()).format("HH:mm") : "")
|
||||
|
||||
const onChangeDate = (type: string, selectedDate: any) => {
|
||||
if (type === "set") {
|
||||
@@ -45,6 +45,8 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
||||
onChange(formatted)
|
||||
setModal(false)
|
||||
}
|
||||
} else if (type === "dismissed") {
|
||||
setModal(false)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -100,11 +102,8 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
||||
value={valueFix}
|
||||
mode={mode}
|
||||
display="spinner"
|
||||
onChange={(event, date) => {
|
||||
onChangeDate(event.type, date)
|
||||
}}
|
||||
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||
onTouchCancel={() => setModal(false)}
|
||||
|
||||
/>
|
||||
</ModalFloat>
|
||||
)
|
||||
@@ -115,7 +114,7 @@ export function InputDate({ label, value, placeholder, onChange, info, disable,
|
||||
mode={mode}
|
||||
display="inline"
|
||||
onChange={(event, date) => { onChangeDate(event.type, date) }}
|
||||
onTouchCancel={() => setModal(false)}
|
||||
onTouchCancel={() => { setModal(false) }}
|
||||
/>
|
||||
)
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ export function InputForm({ label, value, placeholder, onChange, info, disable,
|
||||
round && Styles.round30,
|
||||
{ backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' },
|
||||
error && { borderColor: "red" },
|
||||
Platform.OS == 'ios' && { paddingVertical: 10 },
|
||||
Platform.OS == 'ios' ? { paddingVertical: 10 } : { paddingVertical: 0 },
|
||||
]}>
|
||||
{itemRight != undefined ? itemRight : itemLeft}
|
||||
<TextInput
|
||||
@@ -53,7 +53,7 @@ export function InputForm({ label, value, placeholder, onChange, info, disable,
|
||||
keyboardType={type}
|
||||
onChangeText={onChange}
|
||||
placeholderTextColor={'gray'}
|
||||
style={[Styles.mh05, { width: width ? lebar * width / 100 : lebar * 0.78, color: 'black' }]}
|
||||
style={[Styles.mh05, { width: width ? lebar * width / 100 : lebar * 0.78, color: 'black' }, Platform.OS == 'ios' ? { paddingVertical: 1 } : { paddingVertical: 5 }]}
|
||||
/>
|
||||
</View>
|
||||
{error && (<Text style={[Styles.textInformation, Styles.cError, Styles.mt05]}>{errorText}</Text>)}
|
||||
@@ -79,7 +79,7 @@ export function InputForm({ label, value, placeholder, onChange, info, disable,
|
||||
placeholder={placeholder}
|
||||
keyboardType={type}
|
||||
editable={!disable}
|
||||
style={[Styles.inputRoundForm, error && { borderColor: "red" }, round && Styles.round30, { backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' }, { color: 'black' }, multiline && { height: 150, textAlignVertical: 'top' }]}
|
||||
style={[Styles.inputRoundForm, Platform.OS == 'ios' ? { paddingVertical: 11 } : { paddingVertical: 6 }, error && { borderColor: "red" }, round && Styles.round30, { backgroundColor: bg && bg == 'white' ? 'white' : 'transparent' }, { color: 'black' }, multiline && { height: 150, textAlignVertical: 'top' }]}
|
||||
onChangeText={onChange}
|
||||
placeholderTextColor={'gray'}
|
||||
multiline={multiline}
|
||||
|
||||
@@ -1,96 +1,19 @@
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiCreatePosition } from "@/lib/api"
|
||||
import { setUpdatePosition } from "@/lib/positionSlice"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import { AntDesign } from "@expo/vector-icons"
|
||||
import { useState } from "react"
|
||||
import { View } from "react-native"
|
||||
import Toast from "react-native-toast-message"
|
||||
import { useDispatch, useSelector } from "react-redux"
|
||||
import { ButtonForm } from "../buttonForm"
|
||||
import { useSelector } from "react-redux"
|
||||
import ButtonMenuHeader from "../buttonMenuHeader"
|
||||
import DrawerBottom from "../drawerBottom"
|
||||
import { InputForm } from "../inputForm"
|
||||
import MenuItemRow from "../menuItemRow"
|
||||
import ModalFilter from "../modalFilter"
|
||||
import ModalSelect from "../modalSelect"
|
||||
import SelectForm from "../selectForm"
|
||||
import ModalFormCreatePosition from "./modalFormCreatePosition"
|
||||
|
||||
export default function HeaderRightPositionList() {
|
||||
const dispatch = useDispatch()
|
||||
const update = useSelector((state: any) => state.positionUpdate)
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const entityUser = useSelector((state: any) => state.user)
|
||||
const [isVisible, setVisible] = useState(false)
|
||||
const [isVisibleTambah, setVisibleTambah] = useState(false)
|
||||
const [isFilter, setFilter] = useState(false)
|
||||
const [isSelect, setSelect] = useState(false)
|
||||
const [choose, setChoose] = useState({ val: '', label: '' })
|
||||
const [dataForm, setDataForm] = useState({
|
||||
name: "",
|
||||
idGroup: "",
|
||||
})
|
||||
const [error, setError] = useState({
|
||||
name: false,
|
||||
idGroup: false
|
||||
});
|
||||
|
||||
function validationForm(val: any, cat: 'name' | 'idGroup') {
|
||||
if (cat === 'name') {
|
||||
setDataForm({ ...dataForm, name: val })
|
||||
if (val == "") {
|
||||
setError({ ...error, name: true })
|
||||
} else {
|
||||
setError({ ...error, name: false })
|
||||
}
|
||||
} else if (cat === "idGroup") {
|
||||
setDataForm({ ...dataForm, idGroup: val })
|
||||
if (val == "") {
|
||||
setError({ ...error, idGroup: true })
|
||||
} else {
|
||||
setError({ ...error, idGroup: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkAll() {
|
||||
let nilai = true
|
||||
if (dataForm.name == "") {
|
||||
setError(error => ({ ...error, name: true }))
|
||||
nilai = false
|
||||
}
|
||||
|
||||
if ((entityUser.role == "supadmin" || entityUser.role == "developer") && (dataForm.idGroup == "" || String(dataForm.idGroup) == "null")) {
|
||||
setError(error => ({ ...error, idGroup: true }))
|
||||
nilai = false
|
||||
}
|
||||
|
||||
return nilai
|
||||
}
|
||||
|
||||
function onCheck() {
|
||||
const check = checkAll()
|
||||
if (!check)
|
||||
return false
|
||||
handleTambah()
|
||||
}
|
||||
|
||||
|
||||
async function handleTambah() {
|
||||
try {
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreatePosition({ user: hasil, name: dataForm.name, idGroup: dataForm.idGroup })
|
||||
dispatch(setUpdatePosition(!update))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setVisibleTambah(false)
|
||||
setVisible(false)
|
||||
Toast.show({ type: 'small', text1: 'Berhasil menambahkan data', })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -124,61 +47,13 @@ export default function HeaderRightPositionList() {
|
||||
</DrawerBottom>
|
||||
|
||||
<DrawerBottom animation="slide" height={45} keyboard isVisible={isVisibleTambah} setVisible={() => setVisibleTambah(false)} title="Tambah Jabatan">
|
||||
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
||||
<View>
|
||||
{
|
||||
(entityUser.role == 'supadmin' || entityUser.role == 'developer') &&
|
||||
<SelectForm
|
||||
label="Lembaga Desa"
|
||||
placeholder="Pilih Lembaga Desa"
|
||||
value={choose.label}
|
||||
required
|
||||
onPress={() => {
|
||||
setVisibleTambah(false)
|
||||
setTimeout(() => {
|
||||
setSelect(true)
|
||||
}, 600)
|
||||
}}
|
||||
error={error.idGroup}
|
||||
errorText="Lembaga Desa harus diisi"
|
||||
/>
|
||||
}
|
||||
<InputForm
|
||||
type="default"
|
||||
placeholder="Nama Jabatan"
|
||||
required
|
||||
label="Jabatan"
|
||||
onChange={(value) => { validationForm(value, 'name') }}
|
||||
error={error.name}
|
||||
errorText="Nama jabatan harus diisi"
|
||||
value={dataForm.name}
|
||||
/>
|
||||
</View>
|
||||
<View style={Styles.mb30}>
|
||||
<ButtonForm text="SIMPAN" onPress={() => { onCheck() }} />
|
||||
</View>
|
||||
</View>
|
||||
<ModalFormCreatePosition onClose={() => setVisibleTambah(false)} />
|
||||
</DrawerBottom>
|
||||
|
||||
<ModalFilter close={() => {
|
||||
setFilter(false)
|
||||
setVisible(false)
|
||||
}} open={isFilter} page="position" />
|
||||
|
||||
<ModalSelect
|
||||
category="group"
|
||||
close={setSelect}
|
||||
onSelect={(value) => {
|
||||
validationForm(value.val, 'idGroup')
|
||||
setChoose(value)
|
||||
setSelect(false)
|
||||
setTimeout(() => {
|
||||
setVisibleTambah(true)
|
||||
}, 600)
|
||||
}}
|
||||
title="Lembaga Desa"
|
||||
open={isSelect}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
133
components/position/modalFormCreatePosition.tsx
Normal file
133
components/position/modalFormCreatePosition.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import Styles from "@/constants/Styles"
|
||||
import { apiCreatePosition } from "@/lib/api"
|
||||
import { setUpdatePosition } from "@/lib/positionSlice"
|
||||
import { useAuthSession } from "@/providers/AuthProvider"
|
||||
import { update } from "@react-native-firebase/database"
|
||||
import { useEffect, useState } from "react"
|
||||
import { View } from "react-native"
|
||||
import Toast from "react-native-toast-message"
|
||||
import { useDispatch, useSelector } from "react-redux"
|
||||
import { ButtonForm } from "../buttonForm"
|
||||
import { InputForm } from "../inputForm"
|
||||
import SelectForm from "../selectForm"
|
||||
import ModalSelect from "../modalSelect"
|
||||
|
||||
export default function ModalFormCreatePosition({ onClose }: { onClose: () => void }) {
|
||||
const dispatch = useDispatch()
|
||||
const { token, decryptToken } = useAuthSession()
|
||||
const entityUser = useSelector((state: any) => state.user)
|
||||
const [choose, setChoose] = useState({ val: '', label: '' })
|
||||
const [isSelect, setSelect] = useState(false)
|
||||
const [disable, setDisable] = useState(true)
|
||||
const [dataForm, setDataForm] = useState({
|
||||
name: "",
|
||||
idGroup: "",
|
||||
})
|
||||
const [error, setError] = useState({
|
||||
name: false,
|
||||
idGroup: false
|
||||
});
|
||||
|
||||
function validationForm(val: any, cat: 'name' | 'idGroup') {
|
||||
if (cat === 'name') {
|
||||
setDataForm({ ...dataForm, name: val })
|
||||
if (val == "") {
|
||||
setError({ ...error, name: true })
|
||||
} else {
|
||||
setError({ ...error, name: false })
|
||||
}
|
||||
} else if (cat === "idGroup") {
|
||||
setDataForm({ ...dataForm, idGroup: val })
|
||||
if (val == "") {
|
||||
setError({ ...error, idGroup: true })
|
||||
} else {
|
||||
setError({ ...error, idGroup: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkAll() {
|
||||
let nilai = false
|
||||
if (dataForm.name == "") {
|
||||
nilai = true
|
||||
}
|
||||
|
||||
if ((entityUser.role == "supadmin" || entityUser.role == "developer") && (dataForm.idGroup == "" || String(dataForm.idGroup) == "null")) {
|
||||
nilai = true
|
||||
}
|
||||
|
||||
setDisable(nilai)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkAll()
|
||||
}, [dataForm])
|
||||
|
||||
async function handleTambah() {
|
||||
try {
|
||||
setDisable(true)
|
||||
const hasil = await decryptToken(String(token?.current))
|
||||
const response = await apiCreatePosition({ user: hasil, name: dataForm.name, idGroup: dataForm.idGroup })
|
||||
dispatch(setUpdatePosition(!update))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setDisable(false)
|
||||
Toast.show({ type: 'small', text1: 'Berhasil menambahkan data', })
|
||||
onClose()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
||||
<View>
|
||||
{
|
||||
(entityUser.role == 'supadmin' || entityUser.role == 'developer') &&
|
||||
<SelectForm
|
||||
label="Lembaga Desa"
|
||||
placeholder="Pilih Lembaga Desa"
|
||||
value={choose.label}
|
||||
required
|
||||
onPress={() => {
|
||||
setSelect(true)
|
||||
}}
|
||||
error={error.idGroup}
|
||||
errorText="Lembaga Desa harus diisi"
|
||||
/>
|
||||
}
|
||||
<InputForm
|
||||
type="default"
|
||||
placeholder="Nama Jabatan"
|
||||
required
|
||||
label="Jabatan"
|
||||
onChange={(value) => { validationForm(value, 'name') }}
|
||||
error={error.name}
|
||||
errorText="Nama jabatan harus diisi"
|
||||
value={dataForm.name}
|
||||
/>
|
||||
</View>
|
||||
<View style={Styles.mb30}>
|
||||
<ButtonForm
|
||||
text="SIMPAN"
|
||||
onPress={() => { handleTambah() }}
|
||||
disabled={disable} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<ModalSelect
|
||||
category="group"
|
||||
close={setSelect}
|
||||
onSelect={(value) => {
|
||||
validationForm(value.val, 'idGroup')
|
||||
setChoose(value)
|
||||
setSelect(false)
|
||||
}}
|
||||
title="Lembaga Desa"
|
||||
open={isSelect}
|
||||
valChoose={choose.val}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -3,9 +3,9 @@ import { View } from "react-native";
|
||||
import Toast from "react-native-toast-message";
|
||||
import Text from "./Text";
|
||||
|
||||
export default function ToastCustom() {
|
||||
export default function ToastCustom({ position }: { position?: 'top' | 'bottom' }) {
|
||||
return (
|
||||
<Toast autoHide onPress={() => Toast.hide()} visibilityTime={1500} position="bottom" config={{
|
||||
<Toast autoHide onPress={() => Toast.hide()} visibilityTime={1500} position={position || 'bottom'} config={{
|
||||
small: ({ text1 }) => (
|
||||
<View style={[Styles.toastContainer]}>
|
||||
<Text style={{ fontSize: 12 }}>{text1}</Text>
|
||||
|
||||
@@ -94,6 +94,9 @@ const Styles = StyleSheet.create({
|
||||
mv15: {
|
||||
marginVertical: 15
|
||||
},
|
||||
mh03: {
|
||||
marginHorizontal: 3
|
||||
},
|
||||
mh05: {
|
||||
marginHorizontal: 5
|
||||
},
|
||||
|
||||
40
eas.json
40
eas.json
@@ -5,20 +5,52 @@
|
||||
},
|
||||
"build": {
|
||||
"development": {
|
||||
"developmentClient": true,
|
||||
"distribution": "internal"
|
||||
"distribution": "internal",
|
||||
"android": {
|
||||
"buildType": "apk"
|
||||
},
|
||||
"ios": {
|
||||
"simulator": true
|
||||
}
|
||||
},
|
||||
"preview": {
|
||||
"distribution": "internal",
|
||||
"android": {
|
||||
"buildType": "apk"
|
||||
},
|
||||
"ios": {
|
||||
"simulator": false
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"autoIncrement": true
|
||||
"distribution": "store",
|
||||
"android": {
|
||||
"buildType": "app-bundle"
|
||||
},
|
||||
"ios": {
|
||||
"simulator": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"submit": {
|
||||
"production": {}
|
||||
"production": {
|
||||
"android": {
|
||||
"serviceAccountKeyPath": "./service-account.json",
|
||||
"track": "production"
|
||||
}
|
||||
},
|
||||
"beta": {
|
||||
"android": {
|
||||
"serviceAccountKeyPath": "./service-account.json",
|
||||
"track": "beta",
|
||||
"releaseStatus": "completed"
|
||||
}
|
||||
},
|
||||
"internal": {
|
||||
"android": {
|
||||
"serviceAccountKeyPath": "./service-account.json",
|
||||
"track": "internal"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2027,6 +2027,8 @@ PODS:
|
||||
- React-utils (= 0.79.5)
|
||||
- RNCAsyncStorage (2.1.2):
|
||||
- React-Core
|
||||
- RNCClipboard (1.16.3):
|
||||
- React-Core
|
||||
- RNDateTimePicker (8.4.1):
|
||||
- React-Core
|
||||
- RNFBApp (22.4.0):
|
||||
@@ -2328,6 +2330,7 @@ DEPENDENCIES:
|
||||
- ReactCodegen (from `build/generated/ios`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
|
||||
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
||||
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
|
||||
- "RNFBDatabase (from `../node_modules/@react-native-firebase/database`)"
|
||||
@@ -2570,6 +2573,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCClipboard:
|
||||
:path: "../node_modules/@react-native-clipboard/clipboard"
|
||||
RNDateTimePicker:
|
||||
:path: "../node_modules/@react-native-community/datetimepicker"
|
||||
RNFBApp:
|
||||
@@ -2712,6 +2717,7 @@ SPEC CHECKSUMS:
|
||||
ReactCodegen: 272c9bc1a8a917bf557bd9d032a4b3e181c6abfe
|
||||
ReactCommon: 7eb76fcd5133313d8c6a138a5c7dd89f80f189d5
|
||||
RNCAsyncStorage: b9f5f78da5d16a853fe3dc22e8268d932fc45a83
|
||||
RNCClipboard: f6679d470d0da2bce2a37b0af7b9e0bf369ecda5
|
||||
RNDateTimePicker: 60f9e986d61e42169a2716c1b51f1f93dfa82665
|
||||
RNFBApp: 12884d3bf9b3a0223efe4a0adce516edf72c4102
|
||||
RNFBDatabase: 1e5c4bda4bb47a48820089ddef498f9af21cb52b
|
||||
|
||||
11
lib/api.ts
11
lib/api.ts
@@ -2,9 +2,6 @@ import axios from 'axios';
|
||||
import Constants from 'expo-constants';
|
||||
|
||||
const api = axios.create({
|
||||
// baseURL: 'http://10.0.2.2:3000/api',
|
||||
// baseURL: 'https://stg-darmasaba.wibudev.com/api',
|
||||
// baseURL: 'http://192.168.154.198:3000/api',
|
||||
baseURL: Constants?.expoConfig?.extra?.URL_API
|
||||
});
|
||||
|
||||
@@ -138,12 +135,8 @@ export const apiDeletePosition = async (data: { user: string, isActive: boolean
|
||||
};
|
||||
|
||||
export const apiEditPosition = async (data: { user: string, name: string, idGroup: string }, id: string) => {
|
||||
await api.put(`mobile/position/${id}`, data).then(response => {
|
||||
return response.data;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
const response = await api.put(`mobile/position/${id}`, data)
|
||||
return response.data
|
||||
};
|
||||
|
||||
export const apiGetUser = async ({ user, active, search, group, page }: { user: string, active: string, search: string, group?: string, page?: number }) => {
|
||||
|
||||
@@ -7,7 +7,9 @@ const divisionCreate = createSlice({
|
||||
idGroup: "",
|
||||
name: "",
|
||||
desc: "",
|
||||
}, member: [], admin: [],
|
||||
},
|
||||
member: [],
|
||||
admin: [],
|
||||
},
|
||||
reducers: {
|
||||
setFormCreateDivision: (state, action) => {
|
||||
|
||||
@@ -41,6 +41,7 @@ export const requestPermission = async () => {
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else if (Platform.OS === 'ios') {
|
||||
const { status } = await Notifications.requestPermissionsAsync();
|
||||
return status === 'granted';
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"@expo/vector-icons": "^14.0.2",
|
||||
"@formatjs/intl-getcanonicallocales": "^2.5.5",
|
||||
"@react-native-async-storage/async-storage": "2.1.2",
|
||||
"@react-native-clipboard/clipboard": "^1.16.3",
|
||||
"@react-native-community/cli": "^19.1.0",
|
||||
"@react-native-community/datetimepicker": "8.4.1",
|
||||
"@react-native-firebase/app": "^22.4.0",
|
||||
|
||||
@@ -61,6 +61,8 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
||||
if (Platform.OS === 'android') {
|
||||
const tokenDevice = await getToken()
|
||||
const register = await apiRegisteredToken({ user: hasil, token: String(tokenDevice) })
|
||||
}else{
|
||||
const register = await apiRegisteredToken({ user: hasil, token: "" })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
@@ -84,6 +86,8 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
||||
if (Platform.OS === 'android') {
|
||||
const token = await getToken()
|
||||
const response = await apiUnregisteredToken({ user: hasil, token: String(token) })
|
||||
}else{
|
||||
const response = await apiUnregisteredToken({ user: hasil, token: "" })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
Reference in New Issue
Block a user