Investasi
Add: - lib/dummy-data/investment : list master - app/(application)/(user)/investment/(tabs) Main Layout: Fix: - app/(application)/(user)/investment/create.tsx Component Add: - Progress ## No Issue
This commit is contained in:
@@ -193,6 +193,13 @@ export default function UserLayout() {
|
|||||||
{/* ========== End Crowdfunding Section ========= */}
|
{/* ========== End Crowdfunding Section ========= */}
|
||||||
|
|
||||||
{/* ========== Investment Section ========= */}
|
{/* ========== Investment Section ========= */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="investment/(tabs)"
|
||||||
|
options={{
|
||||||
|
title: "Investasi",
|
||||||
|
headerLeft: () => <BackButton path="/crowdfunding" />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="investment/create"
|
name="investment/create"
|
||||||
options={{
|
options={{
|
||||||
@@ -202,7 +209,7 @@ export default function UserLayout() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* ========== End Investment Section ========= */}
|
{/* ========== End Investment Section ========= */}
|
||||||
|
|
||||||
{/* ========== Donation Section ========= */}
|
{/* ========== Donation Section ========= */}
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="donation/create"
|
name="donation/create"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function Crowdfunding() {
|
|||||||
{
|
{
|
||||||
title: "Investasi",
|
title: "Investasi",
|
||||||
desc: "Buat investasi dan jual beli saham lebih mudah dengan pengguna lain.",
|
desc: "Buat investasi dan jual beli saham lebih mudah dengan pengguna lain.",
|
||||||
path: "investment/create",
|
path: "investment/(tabs)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Donasi",
|
title: "Donasi",
|
||||||
|
|||||||
59
app/(application)/(user)/investment/(tabs)/_layout.tsx
Normal file
59
app/(application)/(user)/investment/(tabs)/_layout.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
||||||
|
import { TabsStyles } from "@/styles/tabs-styles";
|
||||||
|
import { Feather, FontAwesome6, Ionicons } from "@expo/vector-icons";
|
||||||
|
import { Tabs } from "expo-router";
|
||||||
|
|
||||||
|
export default function InvestmentTabsLayout() {
|
||||||
|
return (
|
||||||
|
<Tabs screenOptions={TabsStyles}>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="index"
|
||||||
|
options={{
|
||||||
|
title: "Bursa",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<Ionicons
|
||||||
|
name="bar-chart-outline"
|
||||||
|
color={color}
|
||||||
|
size={ICON_SIZE_SMALL}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="portofolio"
|
||||||
|
options={{
|
||||||
|
title: "Portofolio",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<Feather name="pie-chart" color={color} size={ICON_SIZE_SMALL} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="my-holding"
|
||||||
|
options={{
|
||||||
|
title: "Saham Saya",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome6
|
||||||
|
name="hand-holding-dollar"
|
||||||
|
color={color}
|
||||||
|
size={ICON_SIZE_SMALL}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="transaction"
|
||||||
|
options={{
|
||||||
|
title: "Transaksi",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome6
|
||||||
|
name="money-bill-transfer"
|
||||||
|
color={color}
|
||||||
|
size={ICON_SIZE_SMALL}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
}
|
||||||
81
app/(application)/(user)/investment/(tabs)/index.tsx
Normal file
81
app/(application)/(user)/investment/(tabs)/index.tsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import {
|
||||||
|
BaseBox,
|
||||||
|
FloatingButton,
|
||||||
|
Grid,
|
||||||
|
ProgressCustom,
|
||||||
|
StackCustom,
|
||||||
|
TextCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import DUMMY_IMAGE from "@/constants/dummy-image-value";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { Image } from "expo-image";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { View } from "react-native";
|
||||||
|
|
||||||
|
export default function InvestmentBursa() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper
|
||||||
|
hideFooter
|
||||||
|
floatingButton={
|
||||||
|
<FloatingButton onPress={() => router.push("/investment/create")} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{Array.from({ length: 10 }).map((_, index) => (
|
||||||
|
<BaseBox key={index} paddingTop={7} paddingBottom={7}>
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={5}>
|
||||||
|
<Image
|
||||||
|
source={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}>
|
||||||
|
Title here : Lorem ipsum dolor sit amet consectetur
|
||||||
|
adipisicing elit. Omnis, exercitationem, sequi enim quod
|
||||||
|
distinctio maiores laudantium amet, quidem atque repellat sit
|
||||||
|
vitae qui aliquam est veritatis laborum eum voluptatum totam!
|
||||||
|
</TextCustom>
|
||||||
|
<ProgressCustom value={index % 5 * 20} size="lg" />
|
||||||
|
<TextCustom>
|
||||||
|
Sisa waktu: {dayjs().diff(dayjs(), "day")} hari
|
||||||
|
</TextCustom>
|
||||||
|
</StackCustom>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</BaseBox>
|
||||||
|
))}
|
||||||
|
</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>;
|
||||||
11
app/(application)/(user)/investment/(tabs)/my-holding.tsx
Normal file
11
app/(application)/(user)/investment/(tabs)/my-holding.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ViewWrapper, TextCustom } from "@/components";
|
||||||
|
|
||||||
|
export default function InvestmentMyHolding() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<TextCustom bold size="large">
|
||||||
|
My Holding
|
||||||
|
</TextCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
app/(application)/(user)/investment/(tabs)/portofolio.tsx
Normal file
11
app/(application)/(user)/investment/(tabs)/portofolio.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ViewWrapper, TextCustom } from "@/components";
|
||||||
|
|
||||||
|
export default function InvestmentPortofolio() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<TextCustom bold size="large">
|
||||||
|
Portofolio
|
||||||
|
</TextCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
app/(application)/(user)/investment/(tabs)/transaction.tsx
Normal file
11
app/(application)/(user)/investment/(tabs)/transaction.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ViewWrapper, TextCustom } from "@/components";
|
||||||
|
|
||||||
|
export default function InvestmentTransaction() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<TextCustom bold size="large">
|
||||||
|
Transaction
|
||||||
|
</TextCustom>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,11 +1,197 @@
|
|||||||
import { TextCustom, ViewWrapper } from "@/components";
|
import {
|
||||||
|
BaseBox,
|
||||||
|
ButtonCenteredOnly,
|
||||||
|
ButtonCustom,
|
||||||
|
CenterCustom,
|
||||||
|
InformationBox,
|
||||||
|
LandscapeFrameUploaded,
|
||||||
|
SelectCustom,
|
||||||
|
Spacing,
|
||||||
|
StackCustom,
|
||||||
|
TextInputCustom,
|
||||||
|
ViewWrapper,
|
||||||
|
} from "@/components";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import dummyPembagianDeviden from "@/lib/dummy-data/investment/pembagian-deviden";
|
||||||
|
import dummyListPencarianInvestor from "@/lib/dummy-data/investment/pencarian-investor";
|
||||||
|
import dummyPeriodeDeviden from "@/lib/dummy-data/investment/periode-deviden";
|
||||||
|
import { FontAwesome5 } from "@expo/vector-icons";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
export default function InvestmentCreate() {
|
export default function InvestmentCreate() {
|
||||||
|
const [data, setData] = useState({
|
||||||
|
title: "",
|
||||||
|
targetDana: 0,
|
||||||
|
hargaPerLembar: 0,
|
||||||
|
totalLembar: 0,
|
||||||
|
rasioKeuntungan: 0,
|
||||||
|
pencarianInvestor: "",
|
||||||
|
periodeDeviden: "",
|
||||||
|
pembagianDeviden: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
// const [coba, setCoba] = useState("");
|
||||||
return (
|
return (
|
||||||
<ViewWrapper>
|
<ViewWrapper>
|
||||||
<TextCustom bold size="large">
|
<StackCustom gap={"xs"}>
|
||||||
Buat Investasi
|
{/* <View style={GStyles.inputContainerInput}>
|
||||||
</TextCustom>
|
<TextInput
|
||||||
|
style={{
|
||||||
|
...GStyles.inputText,
|
||||||
|
}}
|
||||||
|
onChangeText={(value) => setCoba(value)}
|
||||||
|
value={coba}
|
||||||
|
keyboardType="decimal-pad"
|
||||||
|
/>
|
||||||
|
</View> */}
|
||||||
|
|
||||||
|
<InformationBox text="Gambar investasi bisa berupa ilustrasi, poster atau foto terkait investasi." />
|
||||||
|
<LandscapeFrameUploaded />
|
||||||
|
<ButtonCenteredOnly
|
||||||
|
icon="upload"
|
||||||
|
onPress={() => router.push("/take-picture/1")}
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</ButtonCenteredOnly>
|
||||||
|
|
||||||
|
<Spacing />
|
||||||
|
|
||||||
|
<InformationBox text="File prospektus wajib untuk diupload, agar calon investor paham dengan prospek investasi yang akan anda jalankan kedepannya." />
|
||||||
|
|
||||||
|
<BaseBox>
|
||||||
|
<CenterCustom>
|
||||||
|
<FontAwesome5
|
||||||
|
name="file-pdf"
|
||||||
|
size={30}
|
||||||
|
color={MainColor.disabled}
|
||||||
|
/>
|
||||||
|
</CenterCustom>
|
||||||
|
</BaseBox>
|
||||||
|
<ButtonCenteredOnly
|
||||||
|
icon="upload"
|
||||||
|
onPress={() => router.push("/take-picture/1")}
|
||||||
|
>
|
||||||
|
Upload File
|
||||||
|
</ButtonCenteredOnly>
|
||||||
|
<Spacing />
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
placeholder="Judul"
|
||||||
|
label="Judul"
|
||||||
|
value={data.title}
|
||||||
|
onChangeText={(value) => setData({ ...data, title: value })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
iconLeft="Rp."
|
||||||
|
placeholder="0"
|
||||||
|
label="Target Dana"
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, targetDana: Number(value) })
|
||||||
|
}
|
||||||
|
value={data.targetDana === 0 ? "" : data.targetDana.toString()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
iconLeft="Rp."
|
||||||
|
placeholder="0"
|
||||||
|
label="Target Dana"
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, targetDana: Number(value) })
|
||||||
|
}
|
||||||
|
value={data.targetDana === 0 ? "" : data.targetDana.toString()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
iconLeft="Rp."
|
||||||
|
placeholder="0"
|
||||||
|
label="Harga Per Lembar"
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, targetDana: Number(value) })
|
||||||
|
}
|
||||||
|
value={data.targetDana === 0 ? "" : data.targetDana.toString()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
placeholder="0"
|
||||||
|
label="Total Lembar"
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, totalLembar: Number(value) })
|
||||||
|
}
|
||||||
|
value={data.totalLembar === 0 ? "" : data.totalLembar.toString()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInputCustom
|
||||||
|
required
|
||||||
|
iconRight="%"
|
||||||
|
label="Rasio Keuntungan / ROI %"
|
||||||
|
placeholder="0"
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={(value) =>
|
||||||
|
setData({ ...data, rasioKeuntungan: Number(value) })
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
data.rasioKeuntungan === 0 ? "" : data.rasioKeuntungan.toString()
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectCustom
|
||||||
|
required
|
||||||
|
placeholder="Pilih batas waktu"
|
||||||
|
label="Pencarian Investor"
|
||||||
|
data={dummyListPencarianInvestor.map((item) => ({
|
||||||
|
label: item.name + `${" "}hari`,
|
||||||
|
value: item.id,
|
||||||
|
}))}
|
||||||
|
onChange={(value) =>
|
||||||
|
setData({ ...data, pencarianInvestor: value as any })
|
||||||
|
}
|
||||||
|
value={data.pencarianInvestor}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectCustom
|
||||||
|
required
|
||||||
|
placeholder="Pilih batas waktu"
|
||||||
|
label="Pilih Periode Deviden"
|
||||||
|
data={dummyPeriodeDeviden.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}))}
|
||||||
|
onChange={(value) =>
|
||||||
|
setData({ ...data, periodeDeviden: value as any })
|
||||||
|
}
|
||||||
|
value={data.periodeDeviden}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectCustom
|
||||||
|
required
|
||||||
|
placeholder="Pilih batas waktu"
|
||||||
|
label="Pilih Pembagian Deviden"
|
||||||
|
data={dummyPembagianDeviden.map((item) => ({
|
||||||
|
label: item.name + `${" "}bulan`,
|
||||||
|
value: item.id,
|
||||||
|
}))}
|
||||||
|
onChange={(value) =>
|
||||||
|
setData({ ...data, pembagianDeviden: value as any })
|
||||||
|
}
|
||||||
|
value={data.pembagianDeviden}
|
||||||
|
/>
|
||||||
|
<Spacing />
|
||||||
|
<ButtonCustom onPress={() => router.replace("/investment/portofolio")}>
|
||||||
|
Simpan
|
||||||
|
</ButtonCustom>
|
||||||
|
</StackCustom>
|
||||||
|
<Spacing height={50} />
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
193
components/Progress/ProgressCustom.tsx
Normal file
193
components/Progress/ProgressCustom.tsx
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
import { useTheme } from "@react-navigation/native";
|
||||||
|
import React from "react";
|
||||||
|
import { Animated, StyleSheet, Text, View, ViewStyle } from "react-native";
|
||||||
|
|
||||||
|
type ProgressColor =
|
||||||
|
| "primary"
|
||||||
|
| "success"
|
||||||
|
| "warning"
|
||||||
|
| "error"
|
||||||
|
| "info"
|
||||||
|
| "dark";
|
||||||
|
|
||||||
|
type ProgressSize = "xs" | "sm" | "md" | "lg" | "xl";
|
||||||
|
|
||||||
|
interface ProgressProps {
|
||||||
|
value?: number | null;
|
||||||
|
color?: ProgressColor;
|
||||||
|
size?: ProgressSize;
|
||||||
|
radius?: number;
|
||||||
|
style?: ViewStyle;
|
||||||
|
animated?: boolean;
|
||||||
|
label?: React.ReactNode; // Konten label (bisa string, number, atau elemen)
|
||||||
|
showLabel?: boolean; // Jika ingin mengontrol visibilitas
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColor = (color: ProgressColor, isDark: boolean) => {
|
||||||
|
const palette: Record<ProgressColor, string> = {
|
||||||
|
primary: "#FFC107",
|
||||||
|
success: "#228B22",
|
||||||
|
warning: "#FFA500",
|
||||||
|
error: "#DC3545",
|
||||||
|
info: "#177DDC",
|
||||||
|
dark: isDark ? "#DADADA" : "#212121",
|
||||||
|
};
|
||||||
|
return palette[color];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSize = (size: ProgressSize): number => {
|
||||||
|
const sizes: Record<ProgressSize, number> = {
|
||||||
|
xs: 6,
|
||||||
|
sm: 8,
|
||||||
|
md: 12,
|
||||||
|
lg: 16,
|
||||||
|
xl: 20,
|
||||||
|
};
|
||||||
|
return sizes[size];
|
||||||
|
};
|
||||||
|
|
||||||
|
const ProgressCustom: React.FC<ProgressProps> = ({
|
||||||
|
value = 0,
|
||||||
|
color = "primary",
|
||||||
|
size = "md",
|
||||||
|
radius = 999,
|
||||||
|
style,
|
||||||
|
animated = true,
|
||||||
|
label,
|
||||||
|
showLabel = true,
|
||||||
|
}) => {
|
||||||
|
const { dark } = useTheme();
|
||||||
|
const isDark = dark ?? false;
|
||||||
|
|
||||||
|
const barHeight = getSize(size);
|
||||||
|
const progressColor = getColor(color, isDark);
|
||||||
|
const displayValue =
|
||||||
|
typeof value === "number" ? Math.max(0, Math.min(100, value)) : 0;
|
||||||
|
|
||||||
|
// Animasi indeterminate
|
||||||
|
const translateX = React.useRef(new Animated.Value(-1)).current;
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (value === null && animated) {
|
||||||
|
const animation = Animated.loop(
|
||||||
|
Animated.timing(translateX, {
|
||||||
|
toValue: 1,
|
||||||
|
duration: 1200,
|
||||||
|
useNativeDriver: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
animation.start();
|
||||||
|
return () => animation.stop();
|
||||||
|
}
|
||||||
|
}, [value, animated, translateX]);
|
||||||
|
|
||||||
|
const isIndeterminate = value === null;
|
||||||
|
|
||||||
|
// Tentukan teks label
|
||||||
|
const labelText =
|
||||||
|
label !== undefined
|
||||||
|
? label
|
||||||
|
: typeof value === "number"
|
||||||
|
? `${Math.round(value)}%`
|
||||||
|
: "";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.container,
|
||||||
|
{
|
||||||
|
height: barHeight,
|
||||||
|
borderRadius: radius,
|
||||||
|
backgroundColor: isDark
|
||||||
|
? "rgb(255, 255, 255)"
|
||||||
|
: "rgba(255, 255, 255, 0.84)",
|
||||||
|
},
|
||||||
|
style,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{/* Progress Fill */}
|
||||||
|
{isIndeterminate ? (
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
styles.indeterminateBar,
|
||||||
|
{
|
||||||
|
width: "50%",
|
||||||
|
height: barHeight,
|
||||||
|
borderRadius: radius,
|
||||||
|
backgroundColor: progressColor,
|
||||||
|
transform: [
|
||||||
|
{
|
||||||
|
translateX: translateX.interpolate({
|
||||||
|
inputRange: [-1, 1],
|
||||||
|
outputRange: [-100, 100],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.progressBar,
|
||||||
|
{
|
||||||
|
width: `${displayValue}%`,
|
||||||
|
height: barHeight,
|
||||||
|
borderRadius: radius,
|
||||||
|
backgroundColor: progressColor,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Label di tengah */}
|
||||||
|
{showLabel && labelText ? (
|
||||||
|
<View style={StyleSheet.absoluteFill}>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.label,
|
||||||
|
{
|
||||||
|
fontSize: barHeight * 0.7,
|
||||||
|
lineHeight: barHeight,
|
||||||
|
color: isDark ? "black" : "black", // Warna teks, bisa disesuaikan
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
numberOfLines={1}
|
||||||
|
adjustsFontSizeToFit
|
||||||
|
>
|
||||||
|
{labelText}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProgressCustom;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
overflow: "hidden",
|
||||||
|
backgroundColor: "rgba(0,0,0,0.1)",
|
||||||
|
width: "100%",
|
||||||
|
justifyContent: "center", // Pusatkan label secara vertikal
|
||||||
|
},
|
||||||
|
progressBar: {
|
||||||
|
backgroundColor: "#007BFF",
|
||||||
|
},
|
||||||
|
indeterminateBar: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
backgroundColor: "#007BFF",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
textAlign: "center",
|
||||||
|
width: "100%",
|
||||||
|
// Hindari overlap dengan background — bisa tambahkan shadow atau background jika perlu
|
||||||
|
textShadowColor: "rgba(255,255,255,0.6)",
|
||||||
|
textShadowOffset: { width: 1, height: 1 },
|
||||||
|
textShadowRadius: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -55,6 +55,8 @@ import TabBarBackground from "./_ShareComponent/TabBarBackground";
|
|||||||
import ViewWrapper from "./_ShareComponent/ViewWrapper";
|
import ViewWrapper from "./_ShareComponent/ViewWrapper";
|
||||||
import SearchInput from "./_ShareComponent/SearchInput";
|
import SearchInput from "./_ShareComponent/SearchInput";
|
||||||
import DummyLandscapeImage from "./_ShareComponent/DummyLandscapeImage";
|
import DummyLandscapeImage from "./_ShareComponent/DummyLandscapeImage";
|
||||||
|
// Progress
|
||||||
|
import ProgressCustom from "./Progress/ProgressCustom";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AlertCustom,
|
AlertCustom,
|
||||||
@@ -96,6 +98,8 @@ export {
|
|||||||
// Map
|
// Map
|
||||||
MapCustom,
|
MapCustom,
|
||||||
MenuDrawerDynamicGrid,
|
MenuDrawerDynamicGrid,
|
||||||
|
// Progress
|
||||||
|
ProgressCustom,
|
||||||
// Scroll
|
// Scroll
|
||||||
ScrollableCustom,
|
ScrollableCustom,
|
||||||
// Select
|
// Select
|
||||||
|
|||||||
20
lib/dummy-data/investment/pembagian-deviden.ts
Normal file
20
lib/dummy-data/investment/pembagian-deviden.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const dummyPembagianDeviden = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
name: "3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
name: "6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3",
|
||||||
|
name: "9",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4",
|
||||||
|
name: "12",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default dummyPembagianDeviden;
|
||||||
20
lib/dummy-data/investment/pencarian-investor.ts
Normal file
20
lib/dummy-data/investment/pencarian-investor.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const dummyListPencarianInvestor = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
name: "30",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
name: "60",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3",
|
||||||
|
name: "90",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4",
|
||||||
|
name: "120",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default dummyListPencarianInvestor;
|
||||||
12
lib/dummy-data/investment/periode-deviden.ts
Normal file
12
lib/dummy-data/investment/periode-deviden.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const dummyPeriodeDeviden = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
name: "Selamanya",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
name: "Satu tahun",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default dummyPeriodeDeviden;
|
||||||
Reference in New Issue
Block a user