Compare commits
5 Commits
apple-reje
...
qc/4-dec-2
| Author | SHA1 | Date | |
|---|---|---|---|
| ab5733f336 | |||
| f5e30087ed | |||
| a93f97ed6a | |||
| 858b441a8c | |||
| 98aaa126a1 |
@@ -19,7 +19,7 @@ export default {
|
|||||||
"NSLocationWhenInUseUsageDescription": "Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
"NSLocationWhenInUseUsageDescription": "Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
||||||
},
|
},
|
||||||
associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
|
associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
|
||||||
buildNumber: "9",
|
buildNumber: "12",
|
||||||
},
|
},
|
||||||
|
|
||||||
android: {
|
android: {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export default function CollaborationCreate() {
|
|||||||
<TextAreaCustom
|
<TextAreaCustom
|
||||||
required
|
required
|
||||||
label="Keuntungan Proyek"
|
label="Keuntungan Proyek"
|
||||||
placeholder="Masukan keuntungan proyek"
|
placeholder="Masukan keuntungan proyek, contoh: Meningkatkan relasi bisnis , menjamin kualitas produk, meningkatkan kinerja dan lain lain"
|
||||||
showCount
|
showCount
|
||||||
maxLength={1000}
|
maxLength={1000}
|
||||||
value={data?.benefit}
|
value={data?.benefit}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import { apiMasterEventType } from "@/service/api-client/api-master";
|
import { apiMasterEventType } from "@/service/api-client/api-master";
|
||||||
import { DateTimePickerEvent } from "@react-native-community/datetimepicker";
|
import { DateTimePickerEvent } from "@react-native-community/datetimepicker";
|
||||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function EventEdit() {
|
export default function EventEdit() {
|
||||||
@@ -55,6 +55,7 @@ export default function EventEdit() {
|
|||||||
try {
|
try {
|
||||||
setIsLoadData(true);
|
setIsLoadData(true);
|
||||||
const response = await apiEventGetOne({ id: id as string });
|
const response = await apiEventGetOne({ id: id as string });
|
||||||
|
console.log("[DATA BY ID]", JSON.stringify(response, null, 2));
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
setSelectedDate(new Date(response.data.tanggal));
|
setSelectedDate(new Date(response.data.tanggal));
|
||||||
@@ -209,7 +210,7 @@ export default function EventEdit() {
|
|||||||
minimumDate={new Date(Date.now())}
|
minimumDate={new Date(Date.now())}
|
||||||
label="Tanggal & Waktu Mulai"
|
label="Tanggal & Waktu Mulai"
|
||||||
required
|
required
|
||||||
value={selectedDate as any}
|
value={selectedDate}
|
||||||
onChange={(date: any) => {
|
onChange={(date: any) => {
|
||||||
setSelectedDate(date as any);
|
setSelectedDate(date as any);
|
||||||
}}
|
}}
|
||||||
@@ -254,7 +255,6 @@ export default function EventEdit() {
|
|||||||
placeholder="Masukkan deskripsi event"
|
placeholder="Masukkan deskripsi event"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
maxLength={100}
|
|
||||||
value={data?.deskripsi}
|
value={data?.deskripsi}
|
||||||
onChangeText={(value) => setData({ ...data, deskripsi: value })}
|
onChangeText={(value) => setData({ ...data, deskripsi: value })}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -110,13 +110,14 @@ export default function EventCreate() {
|
|||||||
const response = await apiEventCreate(newData);
|
const response = await apiEventCreate(newData);
|
||||||
console.log("Response", JSON.stringify(response, null, 2));
|
console.log("Response", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
router.navigate("/event/status");
|
router.replace("/event/status");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
@@ -191,7 +192,7 @@ export default function EventCreate() {
|
|||||||
placeholder="Masukkan deskripsi event"
|
placeholder="Masukkan deskripsi event"
|
||||||
required
|
required
|
||||||
showCount
|
showCount
|
||||||
maxLength={1000}
|
value={data?.deskripsi || ""}
|
||||||
onChangeText={(value: any) =>
|
onChangeText={(value: any) =>
|
||||||
setData({ ...data, deskripsi: value })
|
setData({ ...data, deskripsi: value })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import Investment_ButtonInvestasiSection from "@/screens/Invesment/ButtonInvesta
|
|||||||
import Invesment_ComponentBoxOnBottomDetail from "@/screens/Invesment/ComponentBoxOnBottomDetail";
|
import Invesment_ComponentBoxOnBottomDetail from "@/screens/Invesment/ComponentBoxOnBottomDetail";
|
||||||
import Invesment_DetailDataPublishSection from "@/screens/Invesment/DetailDataPublishSection";
|
import Invesment_DetailDataPublishSection from "@/screens/Invesment/DetailDataPublishSection";
|
||||||
import { apiInvestmentGetOne } from "@/service/api-client/api-investment";
|
import { apiInvestmentGetOne } from "@/service/api-client/api-investment";
|
||||||
|
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||||
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
import { AntDesign, MaterialIcons } from "@expo/vector-icons";
|
||||||
import {
|
import {
|
||||||
router,
|
router,
|
||||||
@@ -23,7 +24,7 @@ import {
|
|||||||
useLocalSearchParams,
|
useLocalSearchParams,
|
||||||
} from "expo-router";
|
} from "expo-router";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function InvestmentDetail() {
|
export default function InvestmentDetail() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
@@ -62,6 +63,31 @@ export default function InvestmentDetail() {
|
|||||||
setOpenDrawerPublish(false);
|
setOpenDrawerPublish(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [value, setValue] = useState({
|
||||||
|
sisa: 0,
|
||||||
|
reminder: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateCountDown();
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
console.log("[DATA DETAIL]", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
|
const updateCountDown = () => {
|
||||||
|
const countDown = countDownAndCondition({
|
||||||
|
duration: data?.MasterPencarianInvestor.name,
|
||||||
|
publishTime: data?.countDown,
|
||||||
|
});
|
||||||
|
|
||||||
|
setValue({
|
||||||
|
sisa: countDown.durationDay,
|
||||||
|
reminder: countDown.reminder,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const bottomSection = (
|
const bottomSection = (
|
||||||
<Invesment_ComponentBoxOnBottomDetail
|
<Invesment_ComponentBoxOnBottomDetail
|
||||||
id={id as string}
|
id={id as string}
|
||||||
@@ -71,7 +97,7 @@ export default function InvestmentDetail() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const buttonSection = (
|
const buttonSection = (
|
||||||
<Investment_ButtonInvestasiSection id={id as string} isMine={user?.id === data?.author?.id} />
|
<Investment_ButtonInvestasiSection id={id as string} isMine={user?.id === data?.author?.id} reminder={value.reminder} />
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export default function ProfileBlockedList() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NewWrapper
|
<NewWrapper
|
||||||
headerComponent={renderHeader()}
|
// headerComponent={renderHeader()}
|
||||||
listData={listData}
|
listData={listData}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
onEndReached={loadMore}
|
onEndReached={loadMore}
|
||||||
|
|||||||
@@ -64,14 +64,18 @@ export default function Profile() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onLoadPortofolio = async (id: string) => {
|
const onLoadPortofolio = async (id: string) => {
|
||||||
const response = await apiGetPortofolio({ id: id });
|
try {
|
||||||
const lastTwoByDate = response.data
|
const response = await apiGetPortofolio({ id: id });
|
||||||
.sort(
|
const lastTwoByDate = response.data
|
||||||
(a: any, b: any) =>
|
.sort(
|
||||||
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
(a: any, b: any) =>
|
||||||
) // urut desc
|
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||||
.slice(0, 2);
|
) // urut desc
|
||||||
setListPortofolio(lastTwoByDate);
|
.slice(0, 2);
|
||||||
|
setListPortofolio(lastTwoByDate);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
TextCustom,
|
TextCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import Voting_BoxPublishSection from "@/screens/Voting/BoxPublishSection";
|
import Voting_BoxPublishSection from "@/screens/Voting/BoxPublishSection";
|
||||||
import { apiVotingGetAll } from "@/service/api-client/api-voting";
|
import { apiVotingGetAll } from "@/service/api-client/api-voting";
|
||||||
import { router, useFocusEffect } from "expo-router";
|
import { router, useFocusEffect } from "expo-router";
|
||||||
@@ -13,6 +14,7 @@ import _ from "lodash";
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export default function VotingBeranda() {
|
export default function VotingBeranda() {
|
||||||
|
const { user } = useAuth();
|
||||||
const [listData, setListData] = useState<any>([]);
|
const [listData, setListData] = useState<any>([]);
|
||||||
const [loadingGetData, setLoadingGetData] = useState(false);
|
const [loadingGetData, setLoadingGetData] = useState(false);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
@@ -29,6 +31,7 @@ export default function VotingBeranda() {
|
|||||||
const response = await apiVotingGetAll({
|
const response = await apiVotingGetAll({
|
||||||
search,
|
search,
|
||||||
category: "beranda",
|
category: "beranda",
|
||||||
|
userLoginId: user?.id,
|
||||||
});
|
});
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setListData(response.data);
|
setListData(response.data);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export default function VotingDetailStatus() {
|
|||||||
|
|
||||||
{data &&
|
{data &&
|
||||||
data?.catatan &&
|
data?.catatan &&
|
||||||
(status === "draft" || status === "rejected") && (
|
(status === "draft" || status === "reject") && (
|
||||||
<ReportBox text={data?.catatan} />
|
<ReportBox text={data?.catatan} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
ButtonCenteredOnly,
|
ButtonCenteredOnly,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
InformationBox,
|
InformationBox,
|
||||||
|
NewWrapper,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
@@ -12,6 +13,7 @@ import { useAuth } from "@/hooks/use-auth";
|
|||||||
import { apiUser } from "@/service/api-client/api-user";
|
import { apiUser } from "@/service/api-client/api-user";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
|
import { RefreshControl } from "react-native";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function WaitingRoom() {
|
export default function WaitingRoom() {
|
||||||
@@ -33,7 +35,7 @@ export default function WaitingRoom() {
|
|||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
text1: "Akun anda telah aktif", // text2: "Anda berhasil login",
|
text1: "Selamat ! Akun anda telah aktif", // text2: "Anda berhasil login",
|
||||||
});
|
});
|
||||||
router.replace(`/(application)/(user)/profile/create`);
|
router.replace(`/(application)/(user)/profile/create`);
|
||||||
}
|
}
|
||||||
@@ -82,10 +84,18 @@ export default function WaitingRoom() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper footerComponent={logoutButton()}>
|
<NewWrapper
|
||||||
|
footerComponent={logoutButton()}
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl refreshing={isLoading} onRefresh={handleCheck} />
|
||||||
|
}
|
||||||
|
>
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
<InformationBox text="Permohonan akses Anda sedang dalam proses verifikasi oleh admin. Harap tunggu, Anda akan menerima pemberitahuan melalui Whatsapp setelah disetujui." />
|
<InformationBox
|
||||||
<ButtonCenteredOnly
|
text="Akun Anda sedang menunggu aktivasi.
|
||||||
|
Silakan tunggu beberapa saat. Untuk memperbarui status, tarik layar ke bawah."
|
||||||
|
/>
|
||||||
|
{/* <ButtonCenteredOnly
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
handleCheck();
|
handleCheck();
|
||||||
@@ -93,9 +103,9 @@ export default function WaitingRoom() {
|
|||||||
icon="refresh-ccw"
|
icon="refresh-ccw"
|
||||||
>
|
>
|
||||||
Check
|
Check
|
||||||
</ButtonCenteredOnly>
|
</ButtonCenteredOnly> */}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</NewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,56 @@
|
|||||||
import {
|
import {
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
TextInputCustom,
|
TextInputCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { apiAdminMasterDonationCategoryCreate } from "@/service/api-admin/api-master-admin";
|
||||||
import { useRouter } from "expo-router";
|
import { useRouter } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Switch } from "react-native-paper";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function AdminDonationCategoryCreate() {
|
export default function AdminDonationCategoryCreate() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [data, setData] = useState({
|
||||||
|
name: "",
|
||||||
|
active: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminMasterDonationCategoryCreate({ data });
|
||||||
|
if (response.success) {
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text2: "Data berhasil disimpan",
|
||||||
|
});
|
||||||
|
router.back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Gagal menyimpan data",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[Error]", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom onPress={() => router.back()}>Simpan</ButtonCustom>
|
<ButtonCustom isLoading={loading} onPress={onSubmit}>
|
||||||
|
Simpan
|
||||||
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -20,7 +59,23 @@ export default function AdminDonationCategoryCreate() {
|
|||||||
headerComponent={<AdminBackButtonAntTitle title="Tambah Kategori" />}
|
headerComponent={<AdminBackButtonAntTitle title="Tambah Kategori" />}
|
||||||
footerComponent={buttonSubmit}
|
footerComponent={buttonSubmit}
|
||||||
>
|
>
|
||||||
<TextInputCustom placeholder="Masukkan Kategori" />
|
<TextInputCustom
|
||||||
|
label=""
|
||||||
|
placeholder="Masukkan Kategori"
|
||||||
|
value={data.name}
|
||||||
|
onChangeText={(text) => setData({ ...data, name: text })}
|
||||||
|
/>
|
||||||
|
<StackCustom gap={"sm"}>
|
||||||
|
<TextCustom>Status</TextCustom>
|
||||||
|
<Switch
|
||||||
|
style={{
|
||||||
|
alignSelf: "flex-start",
|
||||||
|
}}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
value={data.active}
|
||||||
|
onValueChange={(value) => setData({ ...data, active: value })}
|
||||||
|
/>
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,21 +1,76 @@
|
|||||||
import {
|
import {
|
||||||
|
AlertDefaultSystem,
|
||||||
BoxButtonOnFooter,
|
BoxButtonOnFooter,
|
||||||
ButtonCustom,
|
ButtonCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
TextInputCustom,
|
TextInputCustom,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import {
|
||||||
|
apiAdminMasterDonationCategoryById,
|
||||||
|
apiAdminMasterDonationCategoryUpdate,
|
||||||
|
} from "@/service/api-admin/api-master-admin";
|
||||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import { Switch } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminDonationCategoryUpdate() {
|
export default function AdminDonationCategoryUpdate() {
|
||||||
|
const router = useRouter();
|
||||||
const { id } = useLocalSearchParams();
|
const { id } = useLocalSearchParams();
|
||||||
const [value, setValue] = useState(id);
|
const [value, setValue] = useState(id);
|
||||||
|
|
||||||
const router = useRouter();
|
const [data, setData] = useState<any>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
const response = await apiAdminMasterDonationCategoryById({
|
||||||
|
id: id as any,
|
||||||
|
});
|
||||||
|
console.log(JSON.stringify(response.data, null, 2));
|
||||||
|
|
||||||
|
setData(response.data);
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await apiAdminMasterDonationCategoryUpdate({
|
||||||
|
id: id as any,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
console.log(JSON.stringify(response.data, null, 2));
|
||||||
|
router.back();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buttonSubmit = (
|
const buttonSubmit = (
|
||||||
<BoxButtonOnFooter>
|
<BoxButtonOnFooter>
|
||||||
<ButtonCustom onPress={() => router.back()}>Update</ButtonCustom>
|
<ButtonCustom
|
||||||
|
disabled={isLoading || data?.name === ""}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => {
|
||||||
|
AlertDefaultSystem({
|
||||||
|
title: "Update Data",
|
||||||
|
message: "Apakah anda yakin ingin mengupdate data ini?",
|
||||||
|
textLeft: "Batal",
|
||||||
|
textRight: "Ya",
|
||||||
|
onPressLeft: () => {},
|
||||||
|
onPressRight: () => handlerSubmit(),
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</ButtonCustom>
|
||||||
</BoxButtonOnFooter>
|
</BoxButtonOnFooter>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -25,10 +80,28 @@ export default function AdminDonationCategoryUpdate() {
|
|||||||
footerComponent={buttonSubmit}
|
footerComponent={buttonSubmit}
|
||||||
>
|
>
|
||||||
<TextInputCustom
|
<TextInputCustom
|
||||||
|
label="Nama Kategori"
|
||||||
placeholder="Masukkan Kategori"
|
placeholder="Masukkan Kategori"
|
||||||
value={value as any}
|
value={data?.name}
|
||||||
onChangeText={setValue}
|
onChangeText={(value) => setData({ ...data, name: value })}
|
||||||
/>
|
/>
|
||||||
|
<StackCustom
|
||||||
|
gap={"sm"}
|
||||||
|
style={{
|
||||||
|
alignContent: "flex-start",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextCustom>Status</TextCustom>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
style={{
|
||||||
|
alignSelf: "flex-start",
|
||||||
|
}}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
value={data?.active}
|
||||||
|
onValueChange={(value) => setData({ ...data, active: value })}
|
||||||
|
/>
|
||||||
|
</StackCustom>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
BaseBox,
|
BadgeCustom,
|
||||||
CenterCustom,
|
BaseBox,
|
||||||
Spacing,
|
CenterCustom,
|
||||||
StackCustom,
|
ClickableCustom,
|
||||||
TextCustom,
|
DividerCustom,
|
||||||
ViewWrapper,
|
Grid,
|
||||||
|
Spacing,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import { IconEdit } from "@/components/_Icon";
|
import { IconEdit } from "@/components/_Icon";
|
||||||
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus";
|
||||||
@@ -14,14 +18,56 @@ import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage";
|
|||||||
import { GridView_3_3_6 } from "@/components/_ShareComponent/GridView_3_3_6";
|
import { GridView_3_3_6 } from "@/components/_ShareComponent/GridView_3_3_6";
|
||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
|
||||||
import { View } from "react-native";
|
import { RefreshControl, View } from "react-native";
|
||||||
import { Divider, Switch } from "react-native-paper";
|
import { Divider, Switch } from "react-native-paper";
|
||||||
import { router } from "expo-router";
|
import { router, useFocusEffect } from "expo-router";
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import { apiAdminMasterDonationCategory } from "@/service/api-admin/api-master-admin";
|
||||||
|
import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8";
|
||||||
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
||||||
|
|
||||||
export default function AdminDonationCategory() {
|
export default function AdminDonationCategory() {
|
||||||
|
const [listData, setListData] = useState<any[]>([]);
|
||||||
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
fetchMaster();
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
const fetchMaster = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const response = await apiAdminMasterDonationCategory();
|
||||||
|
if (response.success) {
|
||||||
|
console.log(JSON.stringify(response.data, null, 2));
|
||||||
|
setListData(response.data);
|
||||||
|
} else {
|
||||||
|
setListData([]);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[Error]", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRefresh = async () => {
|
||||||
|
setRefreshing(true);
|
||||||
|
await fetchMaster();
|
||||||
|
setRefreshing(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper headerComponent={<AdminTitlePage title="Donasi" />}>
|
<ViewWrapper
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
|
||||||
|
}
|
||||||
|
headerComponent={<AdminTitlePage title="Donasi" />}
|
||||||
|
>
|
||||||
<AdminComp_BoxTitle
|
<AdminComp_BoxTitle
|
||||||
title="Kategori"
|
title="Kategori"
|
||||||
rightComponent={
|
rightComponent={
|
||||||
@@ -33,81 +79,50 @@ export default function AdminDonationCategory() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BaseBox>
|
<View>
|
||||||
<GridView_3_3_6
|
<Grid>
|
||||||
component1={
|
<Grid.Col style={{paddingLeft: 10}} span={4}>
|
||||||
<TextCustom bold align="center">
|
<TextCustom bold>Status</TextCustom>
|
||||||
Aksi
|
</Grid.Col>
|
||||||
</TextCustom>
|
<Grid.Col span={8}>
|
||||||
}
|
<TextCustom bold>Kategori</TextCustom>
|
||||||
component2={<TextCustom bold>Status</TextCustom>}
|
</Grid.Col>
|
||||||
component3={<TextCustom bold>Kategori</TextCustom>}
|
</Grid>
|
||||||
/>
|
|
||||||
<Divider />
|
<Divider />
|
||||||
<Spacing />
|
<Spacing />
|
||||||
|
|
||||||
<StackCustom>
|
<StackCustom>
|
||||||
{listData.map((item, index) => (
|
{listData.map((item, index) => (
|
||||||
<View key={index}>
|
<ClickableCustom
|
||||||
<GridView_3_3_6
|
onPress={() => {
|
||||||
component1={
|
router.push(`/admin/donation/category-update?id=${item.id}`);
|
||||||
|
}}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
<Grid containerStyle={{ paddingBottom: 10 }}>
|
||||||
|
<Grid.Col
|
||||||
|
span={4}
|
||||||
|
style={{paddingLeft: 10}}
|
||||||
|
>
|
||||||
<CenterCustom>
|
<CenterCustom>
|
||||||
<ActionIcon
|
<BadgeCustom
|
||||||
icon={
|
color={item.active ? MainColor.green : MainColor.red}
|
||||||
<IconEdit size={ICON_SIZE_BUTTON} color="black" />
|
>
|
||||||
}
|
{item.active ? "Aktif" : "Tidak Aktif"}
|
||||||
onPress={() => {
|
</BadgeCustom>
|
||||||
router.push(`/admin/donation/category-update?id=${index}`);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</CenterCustom>
|
</CenterCustom>
|
||||||
}
|
</Grid.Col>
|
||||||
component2={
|
<Grid.Col span={8}>
|
||||||
<Switch
|
<TextCustom bold>{item.name}</TextCustom>
|
||||||
value={true}
|
</Grid.Col>
|
||||||
onValueChange={(item) => {
|
</Grid>
|
||||||
console.log(item);
|
|
||||||
}}
|
|
||||||
color={MainColor.yellow}
|
|
||||||
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
component3={<TextCustom bold>{item.label}</TextCustom>}
|
|
||||||
/>
|
|
||||||
<Spacing height={10} />
|
|
||||||
<Divider />
|
<Divider />
|
||||||
</View>
|
</ClickableCustom>
|
||||||
))}
|
))}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</BaseBox>
|
</View>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const listData = [
|
|
||||||
{
|
|
||||||
label: "Kegiatan Sosial",
|
|
||||||
value: "kegiatan_sosial",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Pendidikan",
|
|
||||||
value: "pendidikan",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kesehatan",
|
|
||||||
value: "kesehatan",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kebudayaan",
|
|
||||||
value: "kebudayaan",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Bencana Alami",
|
|
||||||
value: "bencana_alami",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Lainnya",
|
|
||||||
value: "lainnya",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default function TermsAgreement() {
|
|||||||
<>
|
<>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
options={{
|
options={{
|
||||||
title: "Terms Agreement",
|
title: "Terms & Conditions",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ViewWrapper footerComponent={footerComponent}>
|
<ViewWrapper footerComponent={footerComponent}>
|
||||||
@@ -87,6 +87,7 @@ export default function TermsAgreement() {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
|
paddingInline: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
|
<CheckboxCustom value={term} onChange={() => setTerm(!term)} />
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
fab: {
|
fab: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
margin: 16,
|
margin: "auto",
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: 0,
|
// bottom: 10,
|
||||||
|
top: -20,
|
||||||
backgroundColor: AccentColor.softblue, // Warna Twitter biru
|
backgroundColor: AccentColor.softblue, // Warna Twitter biru
|
||||||
borderRadius: 50,
|
borderRadius: 50,
|
||||||
borderColor: AccentColor.blue,
|
borderColor: AccentColor.blue,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
@@ -6,7 +7,9 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
useColorScheme,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
import { PlaceholderColor } from "@/constants/color-palet";
|
||||||
|
|
||||||
type IconType = React.ReactNode | string;
|
type IconType = React.ReactNode | string;
|
||||||
|
|
||||||
@@ -48,7 +51,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
minRows = 4,
|
minRows = 4,
|
||||||
maxRows = 6,
|
maxRows = 6,
|
||||||
showCount = false,
|
showCount = false,
|
||||||
maxLength,
|
maxLength = 1000,
|
||||||
value,
|
value,
|
||||||
onChangeText,
|
onChangeText,
|
||||||
height = 100,
|
height = 100,
|
||||||
@@ -78,6 +81,9 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = PlaceholderColor[colorScheme || "light"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[GStyles.inputContainerArea]}>
|
<View style={[GStyles.inputContainerArea]}>
|
||||||
{label && (
|
{label && (
|
||||||
@@ -109,6 +115,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
|
|||||||
GStyles.textAreaInput,
|
GStyles.textAreaInput,
|
||||||
{ color: fontColor },
|
{ color: fontColor },
|
||||||
]}
|
]}
|
||||||
|
placeholderTextColor={theme.placeholder}
|
||||||
editable={!disabled}
|
editable={!disabled}
|
||||||
value={value as string}
|
value={value as string}
|
||||||
onChangeText={onChangeText}
|
onChangeText={onChangeText}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PlaceholderColor } from "@/constants/color-palet";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import Ionicons from "@expo/vector-icons/Ionicons";
|
import Ionicons from "@expo/vector-icons/Ionicons";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
@@ -8,8 +9,10 @@ import {
|
|||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
useColorScheme
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
|
||||||
|
|
||||||
type IconType = React.ReactNode | string;
|
type IconType = React.ReactNode | string;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -74,6 +77,9 @@ const TextInputCustom = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = PlaceholderColor[colorScheme || "light"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[GStyles.inputContainerArea, containerStyle]}>
|
<View style={[GStyles.inputContainerArea, containerStyle]}>
|
||||||
{label && (
|
{label && (
|
||||||
@@ -100,12 +106,14 @@ const TextInputCustom = ({
|
|||||||
{ color: fontColor },
|
{ color: fontColor },
|
||||||
disabled && GStyles.inputPlaceholderDisabled, // <-- placeholder saat disabled
|
disabled && GStyles.inputPlaceholderDisabled, // <-- placeholder saat disabled
|
||||||
]}
|
]}
|
||||||
|
placeholderTextColor={theme.placeholder}
|
||||||
editable={!disabled}
|
editable={!disabled}
|
||||||
secureTextEntry={secureTextEntry && !isPasswordVisible}
|
secureTextEntry={secureTextEntry && !isPasswordVisible}
|
||||||
keyboardType={keyboardType}
|
keyboardType={keyboardType}
|
||||||
onChangeText={handleTextChange}
|
onChangeText={handleTextChange}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
{secureTextEntry && (
|
{secureTextEntry && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
import Grid from "@/components/Grid/GridCustom";
|
import Grid from "@/components/Grid/GridCustom";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { View } from "react-native";
|
import { StyleProp, View, ViewStyle } from "react-native";
|
||||||
import { Divider } from "react-native-paper";
|
import { Divider } from "react-native-paper";
|
||||||
|
|
||||||
export default function AdminTableValue({
|
export default function AdminTableValue({
|
||||||
value1,
|
value1,
|
||||||
value2,
|
value2,
|
||||||
value3,
|
value3,
|
||||||
|
style1,
|
||||||
|
style2,
|
||||||
|
style3,
|
||||||
bottomLine = false,
|
bottomLine = false,
|
||||||
}: {
|
}: {
|
||||||
value1: React.ReactNode;
|
value1: React.ReactNode;
|
||||||
value2: React.ReactNode;
|
value2: React.ReactNode;
|
||||||
value3: React.ReactNode;
|
value3: React.ReactNode;
|
||||||
|
style1?: ViewStyle;
|
||||||
|
style2?: ViewStyle;
|
||||||
|
style3?: ViewStyle;
|
||||||
bottomLine?: boolean;
|
bottomLine?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -25,6 +31,7 @@ export default function AdminTableValue({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
|
...style1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value1}
|
{value1}
|
||||||
@@ -36,6 +43,7 @@ export default function AdminTableValue({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
|
...style2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value2}
|
{value2}
|
||||||
@@ -44,9 +52,10 @@ export default function AdminTableValue({
|
|||||||
span={6}
|
span={6}
|
||||||
style={{
|
style={{
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "flex-start",
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
|
...style3,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value3}
|
{value3}
|
||||||
|
|||||||
@@ -45,3 +45,23 @@ export const AdminColor = {
|
|||||||
// Warna Asli: #002e59
|
// Warna Asli: #002e59
|
||||||
// Warna Lebih Gelap: #001f3b
|
// Warna Lebih Gelap: #001f3b
|
||||||
// Warna Tergelap: #001323
|
// Warna Tergelap: #001323
|
||||||
|
|
||||||
|
|
||||||
|
export const PlaceholderColor = {
|
||||||
|
light: {
|
||||||
|
text: "#000",
|
||||||
|
placeholder: "#666",
|
||||||
|
border: "#ccc",
|
||||||
|
background: "#fff",
|
||||||
|
error: "#d00",
|
||||||
|
icon: "#555",
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
text: "#fff",
|
||||||
|
placeholder: "#aaa",
|
||||||
|
border: "#444",
|
||||||
|
background: "#1a1a1a",
|
||||||
|
error: "#ff4d4d",
|
||||||
|
icon: "#ccc",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -72,8 +72,31 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
const loginWithNomor = async (nomor: string) => {
|
const loginWithNomor = async (nomor: string) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
|
console.log("[Masuk provider]", nomor);
|
||||||
const response = await apiLogin({ nomor: nomor });
|
const response = await apiLogin({ nomor: nomor });
|
||||||
await AsyncStorage.setItem("kode_otp", response.kodeId);
|
console.log("[RESPONSE AUTH]", JSON.stringify(response));
|
||||||
|
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
console.log("[Keluar provider]", nomor);
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "Sukses",
|
||||||
|
text2: "Kode OTP berhasil dikirim",
|
||||||
|
});
|
||||||
|
|
||||||
|
await AsyncStorage.setItem("kode_otp", response.kodeId);
|
||||||
|
router.push(`/verification?nomor=${nomor}`);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
router.push(`/register?nomor=${nomor}`);
|
||||||
|
Toast.show({
|
||||||
|
type: "info",
|
||||||
|
text1: "Info",
|
||||||
|
text2: "Silahkan mendaftar",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -81,13 +104,26 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const loginWithNomor = async (nomor: string) => {
|
||||||
|
// setIsLoading(true);
|
||||||
|
// try {
|
||||||
|
// const response = await apiLogin({ nomor: nomor });
|
||||||
|
// await AsyncStorage.setItem("kode_otp", response.kodeId);
|
||||||
|
// } catch (error: any) {
|
||||||
|
// throw new Error(error.response?.data?.message || "Gagal kirim OTP");
|
||||||
|
// } finally {
|
||||||
|
// setIsLoading(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
// --- 2. Validasi OTP & cek user ---
|
// --- 2. Validasi OTP & cek user ---
|
||||||
const validateOtp = async (nomor: string) => {
|
const validateOtp = async (nomor: string) => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiValidationCode({ nomor: nomor });
|
const response = await apiValidationCode({ nomor: nomor });
|
||||||
|
|
||||||
const { token } = response;
|
const { token } = response;
|
||||||
|
console.log("[RESPONSE VALIDASI OTP]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setToken(token);
|
setToken(token);
|
||||||
await AsyncStorage.setItem("authToken", token);
|
await AsyncStorage.setItem("authToken", token);
|
||||||
@@ -104,20 +140,23 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
|
|
||||||
if (response.active) {
|
if (response.active) {
|
||||||
if (response.roleId === "1") {
|
if (response.roleId === "1") {
|
||||||
return "/(application)/(user)/home";
|
router.replace("/(application)/(user)/home");
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return "/(application)/admin/dashboard";
|
router.replace("/(application)/admin/dashboard");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "/(application)/(user)/waiting-room";
|
router.replace("/(application)/(user)/waiting-room");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "info",
|
type: "info",
|
||||||
text1: "Anda belum terdaftar",
|
text1: "Terjadi kesalahan",
|
||||||
text2: "Silahkan daftar terlebih dahulu",
|
text2: "Silahkan coba lagi",
|
||||||
});
|
});
|
||||||
return `/register?nomor=${nomor}`;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("Error validasi otp >>", (error as Error).message || error);
|
console.log("Error validasi otp >>", (error as Error).message || error);
|
||||||
@@ -132,6 +171,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
// --- 3. Ambil data user ---
|
// --- 3. Ambil data user ---
|
||||||
const userData = async (token: string) => {
|
const userData = async (token: string) => {
|
||||||
try {
|
try {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("Token tidak ditemukan");
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await apiConfig.get(`/mobile?token=${token}`, {
|
const response = await apiConfig.get(`/mobile?token=${token}`, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -145,7 +188,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
await AsyncStorage.setItem("userData", JSON.stringify(dataUser));
|
await AsyncStorage.setItem("userData", JSON.stringify(dataUser));
|
||||||
return dataUser;
|
return dataUser;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("[LOAD USER DATA]",error.response?.data?.message + "user" || "Gagal mengambil data user");
|
console.log(
|
||||||
|
"[LOAD USER DATA]",
|
||||||
|
error.response?.data?.message + "user" || "Gagal mengambil data user"
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -160,9 +206,8 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await apiRegister({ data: userData });
|
const response = await apiRegister({ data: userData });
|
||||||
console.log("response", response);
|
console.log("[REGISTER FETCH]", JSON.stringify(response, null, 2));
|
||||||
|
|
||||||
const { token } = response;
|
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "info",
|
type: "info",
|
||||||
@@ -173,23 +218,63 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setToken(token);
|
|
||||||
await AsyncStorage.setItem("authToken", token);
|
|
||||||
Toast.show({
|
Toast.show({
|
||||||
type: "success",
|
type: "success",
|
||||||
text1: "Sukses",
|
text1: "Sukses",
|
||||||
text2: "Anda berhasil terdaftar",
|
text2: "Anda berhasil terdaftar",
|
||||||
});
|
});
|
||||||
router.replace("/(application)/(user)/waiting-room");
|
router.replace(`/verification?nomor=${userData.nomor}`);
|
||||||
return;
|
return;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
Toast.show({
|
||||||
|
type: "error",
|
||||||
|
text1: "Error",
|
||||||
|
text2: error.response?.data?.message || "Gagal mendaftar",
|
||||||
|
});
|
||||||
console.log("Error register", error);
|
console.log("Error register", error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// const registerUser = async (userData: {
|
||||||
|
// username: string;
|
||||||
|
// nomor: string;
|
||||||
|
// termsOfServiceAccepted: boolean;
|
||||||
|
// }) => {
|
||||||
|
// setIsLoading(true);
|
||||||
|
// try {
|
||||||
|
// const response = await apiRegister({ data: userData });
|
||||||
|
// console.log("response", response);
|
||||||
|
|
||||||
|
// const { token } = response;
|
||||||
|
// if (!response.success) {
|
||||||
|
// Toast.show({
|
||||||
|
// type: "info",
|
||||||
|
// text1: "Info",
|
||||||
|
// text2: response.message,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// setToken(token);
|
||||||
|
// await AsyncStorage.setItem("authToken", token);
|
||||||
|
// Toast.show({
|
||||||
|
// type: "success",
|
||||||
|
// text1: "Sukses",
|
||||||
|
// text2: "Anda berhasil terdaftar",
|
||||||
|
// });
|
||||||
|
// router.replace("/(application)/(user)/waiting-room");
|
||||||
|
// return;
|
||||||
|
// } catch (error: any) {
|
||||||
|
// console.log("Error register", error);
|
||||||
|
// } finally {
|
||||||
|
// setIsLoading(false);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
// --- 5. Logout ---
|
// --- 5. Logout ---
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|||||||
@@ -422,7 +422,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBadungConnect;
|
PRODUCT_NAME = "HIPMIBadungConnect";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -454,7 +454,7 @@
|
|||||||
);
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile";
|
||||||
PRODUCT_NAME = HIPMIBadungConnect;
|
PRODUCT_NAME = "HIPMIBadungConnect";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>9</string>
|
<string>12</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { NewWrapper } from "@/components";
|
||||||
import ButtonCustom from "@/components/Button/ButtonCustom";
|
import ButtonCustom from "@/components/Button/ButtonCustom";
|
||||||
import Spacing from "@/components/_ShareComponent/Spacing";
|
import Spacing from "@/components/_ShareComponent/Spacing";
|
||||||
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
@@ -5,9 +6,11 @@ import { MainColor } from "@/constants/color-palet";
|
|||||||
import { useAuth } from "@/hooks/use-auth";
|
import { useAuth } from "@/hooks/use-auth";
|
||||||
import { apiVersion } from "@/service/api-config";
|
import { apiVersion } from "@/service/api-config";
|
||||||
import { GStyles } from "@/styles/global-styles";
|
import { GStyles } from "@/styles/global-styles";
|
||||||
import { Redirect, router } from "expo-router";
|
import versionBadge from "@/utils/viersionBadge";
|
||||||
|
import VersionBadge from "@/utils/viersionBadge";
|
||||||
|
import { Redirect } from "expo-router";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Text, View } from "react-native";
|
import { RefreshControl, Text, View } from "react-native";
|
||||||
import PhoneInput, { ICountry } from "react-native-international-phone-number";
|
import PhoneInput, { ICountry } from "react-native-international-phone-number";
|
||||||
import Toast from "react-native-toast-message";
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
@@ -16,6 +19,7 @@ export default function LoginView() {
|
|||||||
const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
|
const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
|
||||||
const [inputValue, setInputValue] = useState<string>("");
|
const [inputValue, setInputValue] = useState<string>("");
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
const [refreshing, setRefreshing] = useState<boolean>(false);
|
||||||
|
|
||||||
const { loginWithNomor, token, isAdmin, isUserActive } = useAuth();
|
const { loginWithNomor, token, isAdmin, isUserActive } = useAuth();
|
||||||
|
|
||||||
@@ -25,7 +29,18 @@ export default function LoginView() {
|
|||||||
|
|
||||||
async function onLoadVersion() {
|
async function onLoadVersion() {
|
||||||
const res = await apiVersion();
|
const res = await apiVersion();
|
||||||
setVersion(res.data);
|
|
||||||
|
if (res.success) {
|
||||||
|
setVersion(versionBadge());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRefresh() {
|
||||||
|
setRefreshing(true);
|
||||||
|
await onLoadVersion();
|
||||||
|
setInputValue("");
|
||||||
|
setLoading(false);
|
||||||
|
setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInputValue(phoneNumber: string) {
|
function handleInputValue(phoneNumber: string) {
|
||||||
@@ -66,21 +81,13 @@ export default function LoginView() {
|
|||||||
if (!isValid) return;
|
if (!isValid) return;
|
||||||
|
|
||||||
const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
|
const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || "";
|
||||||
const fixNumber = inputValue.replace(/\s+/g, "");
|
let fixNumber = inputValue.replace(/\s+/g, "").replace(/^0+/, "");
|
||||||
|
|
||||||
const realNumber = callingCode + fixNumber;
|
const realNumber = callingCode + fixNumber;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
// const response = await apiLogin({ nomor: realNumber });
|
|
||||||
await loginWithNomor(realNumber);
|
await loginWithNomor(realNumber);
|
||||||
|
|
||||||
Toast.show({
|
|
||||||
type: "success",
|
|
||||||
text1: "Sukses",
|
|
||||||
text2: "Kode OTP berhasil dikirim",
|
|
||||||
});
|
|
||||||
|
|
||||||
router.navigate(`/verification?nomor=${realNumber}`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error login", error);
|
console.log("Error login", error);
|
||||||
Toast.show({
|
Toast.show({
|
||||||
@@ -91,6 +98,30 @@ export default function LoginView() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// setLoading(true);
|
||||||
|
// // const response = await apiLogin({ nomor: realNumber });
|
||||||
|
// const response = await loginWithNomor(realNumber);
|
||||||
|
// console.log("[RESPONSE]", response);
|
||||||
|
|
||||||
|
// Toast.show({
|
||||||
|
// type: "success",
|
||||||
|
// text1: "Sukses",
|
||||||
|
// text2: "Kode OTP berhasil dikirim",
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // router.navigate(`/verification?nomor=${realNumber}`);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log("Error login", error);
|
||||||
|
// Toast.show({
|
||||||
|
// type: "error",
|
||||||
|
// text1: "Error",
|
||||||
|
// text2: error as string,
|
||||||
|
// });
|
||||||
|
// } finally {
|
||||||
|
// setLoading(false);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token && token !== "" && !isUserActive) {
|
if (token && token !== "" && !isUserActive) {
|
||||||
@@ -110,7 +141,12 @@ export default function LoginView() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewWrapper withBackground>
|
<NewWrapper
|
||||||
|
withBackground
|
||||||
|
refreshControl={
|
||||||
|
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
|
||||||
|
}
|
||||||
|
>
|
||||||
<View style={GStyles.authContainer}>
|
<View style={GStyles.authContainer}>
|
||||||
<View>
|
<View>
|
||||||
<View style={GStyles.authContainerTitle}>
|
<View style={GStyles.authContainerTitle}>
|
||||||
@@ -154,6 +190,6 @@ export default function LoginView() {
|
|||||||
Coba
|
Coba
|
||||||
</ButtonCustom> */}
|
</ButtonCustom> */}
|
||||||
</View>
|
</View>
|
||||||
</ViewWrapper>
|
</NewWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import Toast from "react-native-toast-message";
|
|||||||
export default function VerificationView() {
|
export default function VerificationView() {
|
||||||
const { nomor } = useLocalSearchParams<{ nomor: string }>();
|
const { nomor } = useLocalSearchParams<{ nomor: string }>();
|
||||||
|
|
||||||
|
console.log("[NOMOR]", nomor);
|
||||||
|
|
||||||
const [inputOtp, setInputOtp] = useState<string>("");
|
const [inputOtp, setInputOtp] = useState<string>("");
|
||||||
const [userNumber, setUserNumber] = useState<string>("");
|
const [userNumber, setUserNumber] = useState<string>("");
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
@@ -52,7 +54,7 @@ export default function VerificationView() {
|
|||||||
try {
|
try {
|
||||||
const response = await apiCheckCodeOtp({ kodeId });
|
const response = await apiCheckCodeOtp({ kodeId });
|
||||||
console.log(
|
console.log(
|
||||||
"Response check code otp >>",
|
"[OTP] >>",
|
||||||
JSON.stringify(response.otp, null, 2)
|
JSON.stringify(response.otp, null, 2)
|
||||||
);
|
);
|
||||||
// Kita tidak perlu simpan codeOtp di state karena verifikasi dilakukan di backend
|
// Kita tidak perlu simpan codeOtp di state karena verifikasi dilakukan di backend
|
||||||
@@ -89,8 +91,9 @@ export default function VerificationView() {
|
|||||||
// ✅ VERIFIKASI OTOMATIS UNTUK APPLE REVIEW
|
// ✅ VERIFIKASI OTOMATIS UNTUK APPLE REVIEW
|
||||||
if (inputOtp === "1234") {
|
if (inputOtp === "1234") {
|
||||||
try {
|
try {
|
||||||
const response = await validateOtp(nomor as string);
|
await validateOtp(nomor as string);
|
||||||
router.replace(response);
|
|
||||||
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error verification", error);
|
console.log("Error verification", error);
|
||||||
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
||||||
@@ -103,16 +106,8 @@ export default function VerificationView() {
|
|||||||
|
|
||||||
// 🔁 VERIFIKASI NORMAL (untuk pengguna sungguhan)
|
// 🔁 VERIFIKASI NORMAL (untuk pengguna sungguhan)
|
||||||
try {
|
try {
|
||||||
const response = await validateOtp(nomor as string);
|
await validateOtp(nomor as string);
|
||||||
// registerForPushNotificationsAsync().then((token) => {
|
return
|
||||||
// if (token) {
|
|
||||||
// console.log("Expo Push Token:", token);
|
|
||||||
// // TODO: Kirim token ke backend kamu
|
|
||||||
// } else {
|
|
||||||
// console.log("Failed to get Expo Push Token");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
router.replace(response);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error verification", error);
|
console.log("Error verification", error);
|
||||||
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
Toast.show({ type: "error", text1: "Gagal verifikasi" });
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import {
|
import {
|
||||||
BaseBox,
|
BaseBox,
|
||||||
Grid,
|
Grid,
|
||||||
ProgressCustom,
|
ProgressCustom,
|
||||||
StackCustom,
|
StackCustom,
|
||||||
TextCustom,
|
TextCustom,
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import API_STRORAGE from "@/constants/base-url-api-strorage";
|
import API_STRORAGE from "@/constants/base-url-api-strorage";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
||||||
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
import { countDownAndCondition } from "@/utils/countDownAndCondition";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
@@ -21,7 +22,7 @@ export default function Investment_BoxBerandaSection({
|
|||||||
id: string;
|
id: string;
|
||||||
data: any;
|
data: any;
|
||||||
}) {
|
}) {
|
||||||
// console.log("[DATA By one]", JSON.stringify(data, null, 2));
|
// console.log("[DATA By one]", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
const [value, setValue] = useState({
|
const [value, setValue] = useState({
|
||||||
sisa: 0,
|
sisa: 0,
|
||||||
@@ -32,6 +33,8 @@ export default function Investment_BoxBerandaSection({
|
|||||||
updateCountDown();
|
updateCountDown();
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
console.log("[DATA BERANDA]", JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
const updateCountDown = () => {
|
const updateCountDown = () => {
|
||||||
const countDown = countDownAndCondition({
|
const countDown = countDownAndCondition({
|
||||||
duration: data?.pencarianInvestor,
|
duration: data?.pencarianInvestor,
|
||||||
@@ -66,8 +69,10 @@ export default function Investment_BoxBerandaSection({
|
|||||||
<TextCustom truncate={2}>{data.title}</TextCustom>
|
<TextCustom truncate={2}>{data.title}</TextCustom>
|
||||||
<ProgressCustom
|
<ProgressCustom
|
||||||
label={`${data.progress}%`}
|
label={`${data.progress}%`}
|
||||||
value={data.progress}
|
value={Number(data.progress)}
|
||||||
size="lg"
|
size="lg"
|
||||||
|
animated
|
||||||
|
color="primary"
|
||||||
/>
|
/>
|
||||||
{value.reminder ? (
|
{value.reminder ? (
|
||||||
<View
|
<View
|
||||||
@@ -79,13 +84,11 @@ export default function Investment_BoxBerandaSection({
|
|||||||
>
|
>
|
||||||
<Ionicons name="alert-circle-outline" size={16} color="red" />
|
<Ionicons name="alert-circle-outline" size={16} color="red" />
|
||||||
<TextCustom truncate color="red" size="small">
|
<TextCustom truncate color="red" size="small">
|
||||||
Periode Investasi Berakhir
|
Periode Berakhir
|
||||||
</TextCustom>
|
</TextCustom>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<TextCustom>
|
<TextCustom>Sisa waktu: {value.sisa} hari</TextCustom>
|
||||||
Sisa waktu: {value.sisa} hari
|
|
||||||
</TextCustom>
|
|
||||||
)}
|
)}
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { router } from "expo-router";
|
|||||||
export default function Investment_ButtonInvestasiSection({
|
export default function Investment_ButtonInvestasiSection({
|
||||||
id,
|
id,
|
||||||
isMine,
|
isMine,
|
||||||
|
reminder,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
isMine: boolean;
|
isMine: boolean;
|
||||||
|
reminder: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -14,11 +16,12 @@ export default function Investment_ButtonInvestasiSection({
|
|||||||
<ButtonCustom disabled>Investasi ini milik Anda</ButtonCustom>
|
<ButtonCustom disabled>Investasi ini milik Anda</ButtonCustom>
|
||||||
) : (
|
) : (
|
||||||
<ButtonCustom
|
<ButtonCustom
|
||||||
|
disabled={reminder}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
router.navigate(`/investment/${id}/(transaction-flow)`);
|
router.navigate(`/investment/${id}/(transaction-flow)`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Beli Saham
|
{reminder ? "Periode Investasi Berakhir" : "Beli Saham"}
|
||||||
</ButtonCustom>
|
</ButtonCustom>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default function Invesment_DetailDataPublishSection({
|
|||||||
<ReportBox text={data?.catatan} />
|
<ReportBox text={data?.catatan} />
|
||||||
)}
|
)}
|
||||||
<Invesment_BoxProgressSection
|
<Invesment_BoxProgressSection
|
||||||
progress={data?.progress}
|
progress={Number(data?.progress)}
|
||||||
status={status as string}
|
status={status as string}
|
||||||
/>
|
/>
|
||||||
<Invesment_BoxDetailDataSection
|
<Invesment_BoxDetailDataSection
|
||||||
|
|||||||
@@ -5,16 +5,6 @@ import { Ionicons } from "@expo/vector-icons";
|
|||||||
|
|
||||||
export default function Portofolio_SocialMediaSection({ data }: { data: any }) {
|
export default function Portofolio_SocialMediaSection({ data }: { data: any }) {
|
||||||
const listData = [
|
const listData = [
|
||||||
{
|
|
||||||
label: data && data?.facebook ? data.facebook : "-",
|
|
||||||
icon: (
|
|
||||||
<Ionicons
|
|
||||||
name="logo-facebook"
|
|
||||||
size={ICON_SIZE_SMALL}
|
|
||||||
color={MainColor.white}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: data && data?.tiktok ? data.tiktok : "-",
|
label: data && data?.tiktok ? data.tiktok : "-",
|
||||||
icon: (
|
icon: (
|
||||||
@@ -35,6 +25,16 @@ export default function Portofolio_SocialMediaSection({ data }: { data: any }) {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: data && data?.facebook ? data.facebook : "-",
|
||||||
|
icon: (
|
||||||
|
<Ionicons
|
||||||
|
name="logo-facebook"
|
||||||
|
size={ICON_SIZE_SMALL}
|
||||||
|
color={MainColor.white}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: data && data?.twitter ? data.twitter : "-",
|
label: data && data?.twitter ? data.twitter : "-",
|
||||||
icon: (
|
icon: (
|
||||||
|
|||||||
@@ -22,9 +22,11 @@ export default function Voting_BoxDetailHasilVotingSection({
|
|||||||
<Grid>
|
<Grid>
|
||||||
{listData?.map((item: any, i: number) => (
|
{listData?.map((item: any, i: number) => (
|
||||||
<Grid.Col span={12 / listData?.length} style={{ alignItems: "center" }} key={i}>
|
<Grid.Col span={12 / listData?.length} style={{ alignItems: "center" }} key={i}>
|
||||||
<StackCustom>
|
<StackCustom style={{
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
<CircleContainer value={item?.jumlah} />
|
<CircleContainer value={item?.jumlah} />
|
||||||
<TextCustom align="center" size="small">{item?.value}</TextCustom>
|
<TextCustom truncate={2} align="center" size="small">{item?.value}</TextCustom>
|
||||||
</StackCustom>
|
</StackCustom>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -167,3 +167,56 @@ export async function apiAdminMasterTypeOfEventUpdate({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ================== END EVENT ================== //
|
// ================== END EVENT ================== //
|
||||||
|
|
||||||
|
// ================== START DONATION ================== //
|
||||||
|
|
||||||
|
export async function apiAdminMasterDonationCategory() {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.get(`/mobile/admin/master/donation`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function apiAdminMasterDonationCategoryById({ id }: { id: string }) {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.get(`/mobile/admin/master/donation/${id}`);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function apiAdminMasterDonationCategoryUpdate({
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
data: any;
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.put(
|
||||||
|
`/mobile/admin/master/donation/${id}`,
|
||||||
|
{
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function apiAdminMasterDonationCategoryCreate({ data }: { data: any }) {
|
||||||
|
try {
|
||||||
|
const response = await apiConfig.post(`/mobile/admin/master/donation`, {
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================== END DONATION ================== //
|
||||||
@@ -79,12 +79,14 @@ export async function apiVotingUpdateData({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apiVotingGetAll({ search, category, authorId }: { search?: string, category: "beranda" | "contribution" | "all-history" | "my-history", authorId?: string }) {
|
export async function apiVotingGetAll({ search, category, authorId, userLoginId }: { search?: string, category: "beranda" | "contribution" | "all-history" | "my-history", authorId?: string, userLoginId?: string }) {
|
||||||
try {
|
try {
|
||||||
|
console.log("userLoginId", userLoginId);
|
||||||
const categoryQuery = category ? `?category=${category}` : "";
|
const categoryQuery = category ? `?category=${category}` : "";
|
||||||
const searchQuery = search ? `&search=${search}` : "";
|
const searchQuery = search ? `&search=${search}` : "";
|
||||||
const authorIdQuery = authorId ? `&authorId=${authorId}` : "";
|
const authorIdQuery = authorId ? `&authorId=${authorId}` : "";
|
||||||
const response = await apiConfig.get(`/mobile/voting${categoryQuery}${searchQuery}${authorIdQuery}`);
|
const userLoginIdQuery = userLoginId ? `&userLoginId=${userLoginId}` : "";
|
||||||
|
const response = await apiConfig.get(`/mobile/voting${categoryQuery}${searchQuery}${authorIdQuery}${userLoginIdQuery}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ apiConfig.interceptors.request.use(
|
|||||||
async (config) => {
|
async (config) => {
|
||||||
console.log("API_BASE_URL >>", API_BASE_URL);
|
console.log("API_BASE_URL >>", API_BASE_URL);
|
||||||
const token = await AsyncStorage.getItem("authToken");
|
const token = await AsyncStorage.getItem("authToken");
|
||||||
|
// console.log("[TOKEN] >>", token);
|
||||||
if (token) {
|
if (token) {
|
||||||
// config.timeout = 10000;
|
// config.timeout = 10000;
|
||||||
config.headers["Content-Type"] = "application/json";
|
config.headers["Content-Type"] = "application/json";
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("config", JSON.stringify(config, null, 2));
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
@@ -29,16 +29,15 @@ apiConfig.interceptors.request.use(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export async function apiVersion() {
|
export async function apiVersion() {
|
||||||
// console.log("API_BASE_URL", API_BASE_URL);
|
|
||||||
const response = await apiConfig.get("/version");
|
const response = await apiConfig.get("/version");
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apiLogin({ nomor }: { nomor: string }) {
|
export async function apiLogin({ nomor }: { nomor: string }) {
|
||||||
const response = await apiConfig.post("/auth/login", {
|
const response = await apiConfig.post("/auth/mobile-login", {
|
||||||
nomor: nomor,
|
nomor: nomor,
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apiCheckCodeOtp({ kodeId }: { kodeId: string }) {
|
export async function apiCheckCodeOtp({ kodeId }: { kodeId: string }) {
|
||||||
@@ -47,7 +46,7 @@ export async function apiCheckCodeOtp({ kodeId }: { kodeId: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function apiValidationCode({ nomor }: { nomor: string }) {
|
export async function apiValidationCode({ nomor }: { nomor: string }) {
|
||||||
const response = await apiConfig.post(`/auth/validasi`, {
|
const response = await apiConfig.post(`/auth/mobile-validasi`, {
|
||||||
nomor: nomor,
|
nomor: nomor,
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -58,7 +57,7 @@ export async function apiRegister({
|
|||||||
}: {
|
}: {
|
||||||
data: { nomor: string; username: string; termsOfServiceAccepted: boolean };
|
data: { nomor: string; username: string; termsOfServiceAccepted: boolean };
|
||||||
}) {
|
}) {
|
||||||
const response = await apiConfig.post(`/auth/register`, {
|
const response = await apiConfig.post(`/auth/mobile-register`, {
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
18
utils/viersionBadge.ts
Normal file
18
utils/viersionBadge.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// VersionBadge.tsx
|
||||||
|
import Constants from "expo-constants";
|
||||||
|
import { Platform } from "react-native";
|
||||||
|
|
||||||
|
export default function versionBadge() {
|
||||||
|
const expoConfig = Constants.expoConfig;
|
||||||
|
|
||||||
|
const version = expoConfig?.version; // "1.0.1"
|
||||||
|
const iosBuild = expoConfig?.ios?.buildNumber; // "10"
|
||||||
|
const androidBuild = expoConfig?.android?.versionCode; // 2
|
||||||
|
|
||||||
|
const build =
|
||||||
|
Platform.OS === "ios" ? iosBuild : androidBuild;
|
||||||
|
|
||||||
|
const result = `${version} ( ${build} )`;
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user