Integrasi API: Investment:

Add:
- screens/Invesment/BoxBerandaSection.tsx

Fix:
- app/(application)/(user)/investment/(tabs)/index.tsx
- screens/Donation/BoxPublish.tsx
- screens/Invesment/BoxProgressSection.tsx
- screens/Invesment/DetailDataPublishSection.tsx

### No Issue
This commit is contained in:
2025-10-30 16:38:24 +08:00
parent f23cfe1107
commit ebd6107c36
5 changed files with 147 additions and 98 deletions

View File

@@ -11,6 +11,7 @@ import {
import NoDataText from "@/components/_ShareComponent/NoDataText";
import API_STRORAGE from "@/constants/base-url-api-strorage";
import DUMMY_IMAGE from "@/constants/dummy-image-value";
import Investment_BoxBerandaSection from "@/screens/Invesment/BoxBerandaSection";
import { apiInvestmentGetAll } from "@/service/api-client/api-investment";
import { Ionicons } from "@expo/vector-icons";
import dayjs from "dayjs";
@@ -34,7 +35,7 @@ export default function InvestmentBursa() {
try {
setLoadingList(true);
const response = await apiInvestmentGetAll();
console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
// console.log("[DATA LIST]", JSON.stringify(response.data, null, 2));
setList(response.data);
} catch (error) {
console.log("[ERROR]", error);
@@ -56,92 +57,9 @@ export default function InvestmentBursa() {
<NoDataText />
) : (
list?.map((item: any, index: number) => (
<BaseBox
key={index}
paddingTop={7}
paddingBottom={7}
href={`/investment/${item.id}`}
>
<Grid>
<Grid.Col span={5}>
<Image
source={
item && item.imageId
? API_STRORAGE.GET({ fileId: item.imageId })
: DUMMY_IMAGE.background
}
style={{ width: "auto", height: 100, borderRadius: 10 }}
/>
</Grid.Col>
<Grid.Col span={1}>
<View />
</Grid.Col>
<Grid.Col span={6}>
<StackCustom>
<TextCustom truncate={2}>{item.title}</TextCustom>
<ProgressCustom
label={`${item.progress}%`}
value={item.progress}
size="lg"
/>
{Number(item?.pencarianInvestor) -
dayjs().diff(dayjs(item.countDown), "days") <=
0 ? (
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: 5,
}}
>
<Ionicons
name="alert-circle-outline"
size={16}
color="red"
/>
<TextCustom color="red" size="small">
Periode Investasi Selesai
</TextCustom>
</View>
) : (
<TextCustom>
Sisa waktu:{" "}
{Number(item?.pencarianInvestor) -
dayjs().diff(dayjs(item.countDown), "days")}{" "}
hari
</TextCustom>
)}
</StackCustom>
</Grid.Col>
</Grid>
</BaseBox>
<Investment_BoxBerandaSection id={item.id} data={item} key={index} />
))
)}
</ViewWrapper>
);
}
// <View style={{ padding: 20, gap: 16 }}>
// <TextCustom>Progress 70%</TextCustom>
// <ProgressCustom value={70} color="primary" size="md" />
// <TextCustom>Success Progress</TextCustom>
// <ProgressCustom value={40} color="success" size="lg" />
// <TextCustom>Warning Progress (small)</TextCustom>
// <ProgressCustom value={90} color="warning" size="sm" />
// <TextCustom>Error Indeterminate</TextCustom>
// <ProgressCustom value={null} color="error" size="md" />
// <TextCustom>Custom Radius</TextCustom>
// <ProgressCustom value={60} color="info" size="xl" radius={4} />
// <ProgressCustom value={70} color="primary" size="lg" />
// <ProgressCustom value={45} color="success" size="md" label="Halfway!" />
// <ProgressCustom value={90} color="warning" size="lg" showLabel={false} />
// <ProgressCustom value={null} color="error" size="sm" label="Loading..." />
// </View>;

View File

@@ -22,7 +22,7 @@ export default function Donation_BoxPublish({
sisa: 0,
reminder: false,
});
useEffect(() => {
updateCountDown();
}, [data]);

View File

@@ -0,0 +1,97 @@
/* eslint-disable react-hooks/exhaustive-deps */
import {
BaseBox,
Grid,
StackCustom,
TextCustom,
ProgressCustom,
} from "@/components";
import API_STRORAGE from "@/constants/base-url-api-strorage";
import DUMMY_IMAGE from "@/constants/dummy-image-value";
import { countDownAndCondition } from "@/utils/countDownAndCondition";
import { Ionicons } from "@expo/vector-icons";
import dayjs from "dayjs";
import { Image } from "expo-image";
import { useEffect, useState } from "react";
import { View } from "react-native";
export default function Investment_BoxBerandaSection({
id,
data,
}: {
id: string;
data: any;
}) {
// console.log("[DATA By one]", JSON.stringify(data, null, 2));
const [value, setValue] = useState({
sisa: 0,
reminder: false,
});
useEffect(() => {
updateCountDown();
}, [data]);
const updateCountDown = () => {
const countDown = countDownAndCondition({
duration: data?.pencarianInvestor,
publishTime: data?.countDown,
});
setValue({
sisa: countDown.durationDay,
reminder: countDown.reminder,
});
};
return (
<>
<BaseBox paddingTop={7} paddingBottom={7} href={`/investment/${id}`}>
<Grid>
<Grid.Col span={5}>
<Image
source={
data && data.imageId
? API_STRORAGE.GET({ fileId: data.imageId })
: DUMMY_IMAGE.background
}
style={{ width: "auto", height: 100, borderRadius: 10 }}
/>
</Grid.Col>
<Grid.Col span={1}>
<View />
</Grid.Col>
<Grid.Col span={6}>
<StackCustom>
<TextCustom truncate={2}>{data.title}</TextCustom>
<ProgressCustom
label={`${data.progress}%`}
value={data.progress}
size="lg"
/>
{value.reminder ? (
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: 5,
}}
>
<Ionicons name="alert-circle-outline" size={16} color="red" />
<TextCustom truncate color="red" size="small">
Periode Investasi Berakhir
</TextCustom>
</View>
) : (
<TextCustom>
Sisa waktu: {value.sisa} hari
</TextCustom>
)}
</StackCustom>
</Grid.Col>
</Grid>
</BaseBox>
</>
);
}

View File

@@ -7,7 +7,7 @@ export default function Invesment_BoxProgressSection({progress, status}: {progre
<BaseBox>
<StackCustom>
<TextCustom bold>Progress Saham</TextCustom>
<ProgressCustom label={progress + "%"} value={progress} size="lg" />
<ProgressCustom label={(progress || 0) + "%"} value={progress || 0} size="lg" />
</StackCustom>
</BaseBox>
)}

View File

@@ -1,13 +1,15 @@
import { Spacing, StackCustom } from "@/components";
/* eslint-disable react-hooks/exhaustive-deps */
import { ButtonCustom, Spacing, StackCustom, TextCustom } from "@/components";
import {
listDataNotPublishInvesment,
listDataPublishInvesment,
} from "@/lib/dummy-data/investment/dummy-data-not-publish";
import React from "react";
import React, { useEffect, useState } from "react";
import Invesment_BoxDetailDataSection from "./BoxDetailDataSection";
import Invesment_BoxProgressSection from "./BoxProgressSection";
import Investment_ButtonStatusSection from "./ButtonStatusSection";
import ReportBox from "@/components/Box/ReportBox";
import { countDownAndCondition } from "@/utils/countDownAndCondition";
export default function Invesment_DetailDataPublishSection({
status,
@@ -20,14 +22,39 @@ export default function Invesment_DetailDataPublishSection({
bottomSection?: React.ReactNode;
buttonSection?: React.ReactNode;
}) {
const [value, setValue] = useState({
sisa: 0,
reminder: false,
});
useEffect(() => {
updateCountDown();
}, [data]);
const updateCountDown = () => {
const countDown = countDownAndCondition({
duration: data?.durasiDonasi,
publishTime: data?.publishTime,
});
setValue({
sisa: countDown.durationDay,
reminder: countDown.reminder,
});
};
return (
<>
<StackCustom gap={"sm"}>
{data && data?.catatan && (status === "draft" || status === "reject") && (
<ReportBox text={data?.catatan} />
)}
<Invesment_BoxProgressSection progress={data?.progress} status={status as string} />
{data &&
data?.catatan &&
(status === "draft" || status === "reject") && (
<ReportBox text={data?.catatan} />
)}
<Invesment_BoxProgressSection
progress={data?.progress}
status={status as string}
/>
<Invesment_BoxDetailDataSection
title={data?.title}
author={data?.author}
@@ -39,11 +66,18 @@ export default function Invesment_DetailDataPublishSection({
}
bottomSection={bottomSection}
/>
<Investment_ButtonStatusSection
id={data?.id}
status={status as string}
buttonPublish={buttonSection}
/>
{value.reminder ? (
<ButtonCustom disabled>
Periode Investasi Berakhir
</ButtonCustom>
) : (
<Investment_ButtonStatusSection
id={data?.id}
status={status as string}
buttonPublish={buttonSection}
/>
)}
</StackCustom>
<Spacing />
</>