From c863c04fb4f13cec23d59e0c2d1c6a45d11a6a05 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Wed, 30 Jul 2025 14:31:39 +0800 Subject: [PATCH] Invesment Add : - screens/Invesment/ - app/(application)/(user)/investment/[id]/ Fix: - index & portofolio: basic UI ## No Issue --- app/(application)/(user)/_layout.tsx | 21 +++ .../(user)/investment/(tabs)/index.tsx | 2 +- .../(user)/investment/(tabs)/portofolio.tsx | 47 +---- .../investment/[id]/[status]/detail.tsx | 171 ++++++++++++++++++ .../(user)/investment/[id]/edit.tsx | 9 + .../(user)/investment/[id]/index.tsx | 9 + .../investment/[id]/list-of-document.tsx | 9 + bun.lock | 6 + package-lock.json | 65 +++++++ package.json | 2 + screens/Invesment/ButtonStatusSection.tsx | 121 +++++++++++++ screens/Invesment/StatusBox.tsx | 48 +++++ 12 files changed, 470 insertions(+), 40 deletions(-) create mode 100644 app/(application)/(user)/investment/[id]/[status]/detail.tsx create mode 100644 app/(application)/(user)/investment/[id]/edit.tsx create mode 100644 app/(application)/(user)/investment/[id]/index.tsx create mode 100644 app/(application)/(user)/investment/[id]/list-of-document.tsx create mode 100644 screens/Invesment/ButtonStatusSection.tsx create mode 100644 screens/Invesment/StatusBox.tsx diff --git a/app/(application)/(user)/_layout.tsx b/app/(application)/(user)/_layout.tsx index 431adff..5c10d0d 100644 --- a/app/(application)/(user)/_layout.tsx +++ b/app/(application)/(user)/_layout.tsx @@ -207,6 +207,27 @@ export default function UserLayout() { headerLeft: () => , }} /> + , + }} + /> + , + }} + /> + , + }} + /> {/* ========== End Investment Section ========= */} diff --git a/app/(application)/(user)/investment/(tabs)/index.tsx b/app/(application)/(user)/investment/(tabs)/index.tsx index 060e8fe..8c36335 100644 --- a/app/(application)/(user)/investment/(tabs)/index.tsx +++ b/app/(application)/(user)/investment/(tabs)/index.tsx @@ -22,7 +22,7 @@ export default function InvestmentBursa() { } > {Array.from({ length: 10 }).map((_, index) => ( - + ( @@ -36,34 +27,12 @@ export default function InvestmentPortofolio() { return ( {Array.from({ length: 10 }).map((_, index) => ( - - - - - Title here : {activeCategory} 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! - - - - - - Target Dana: - - Rp. {index + 1 % 3/4 * 1004000} - - - - - - - - - + ))} ); diff --git a/app/(application)/(user)/investment/[id]/[status]/detail.tsx b/app/(application)/(user)/investment/[id]/[status]/detail.tsx new file mode 100644 index 0000000..1fb25fa --- /dev/null +++ b/app/(application)/(user)/investment/[id]/[status]/detail.tsx @@ -0,0 +1,171 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { + BackButton, + BaseBox, + ButtonCustom, + CenterCustom, + DotButton, + DrawerCustom, + DummyLandscapeImage, + Grid, + MenuDrawerDynamicGrid, + Spacing, + StackCustom, + TextCustom, + ViewWrapper, +} from "@/components"; +import { IconEdit } from "@/components/_Icon"; +import { IMenuDrawerItem } from "@/components/_Interface/types"; +import { AccentColor, MainColor } from "@/constants/color-palet"; +import Investment_ButtonStatusSection from "@/screens/Invesment/ButtonStatusSection"; +import { FontAwesome6 } from "@expo/vector-icons"; +import { router, Stack, useLocalSearchParams } from "expo-router"; +import _ from "lodash"; +import { useState } from "react"; +import { View } from "react-native"; + +export default function InvestmentDetailStatus() { + const { id, status } = useLocalSearchParams(); + const [openDrawerDraft, setOpenDrawerDraft] = useState(false); + + const handlePressDraft = (item: IMenuDrawerItem) => { + console.log("PATH >> ", item.path); + router.navigate(item.path as any); + setOpenDrawerDraft(false); + }; + + return ( + <> + , + headerRight: () => + status === "draft" ? ( + setOpenDrawerDraft(true)} /> + ) : null, + // : status === "publish" ? ( + // setOpenDrawerPublish(true)} /> + // ) : null, + }} + /> + + + + + + + Title of Investment + + + + {listData.map((item, index) => ( + + + {item.label} + + + + + + {item.value} + + + ))} + + + + + + Prospektus + + + + + + + + + + + Dokumen + + + + + + + + + + + + + + + setOpenDrawerDraft(false)} + height={"auto"} + > + , + label: "Edit", + path: `/investment/${id}/edit`, + }, + ]} + columns={4} + onPressItem={handlePressDraft as any} + /> + + + ); +} + +const listData = [ + { + label: "Target Dana", + value: "Rp. 7.500.000", + }, + { + label: "Harga Per Lembar", + value: "Rp. 2.400.", + }, + { + label: "Return Of Investment (ROI)", + value: "3 %", + }, + { + label: "Total Lembar", + value: "1.200", + }, + { + label: "Jadwal Pembagian", + value: "Rp. 2.880.000", + }, + { + label: "Pembagian Deviden", + value: "Selamanya", + }, + { + label: "Pencarian Investor", + value: "30 Hari", + }, +]; diff --git a/app/(application)/(user)/investment/[id]/edit.tsx b/app/(application)/(user)/investment/[id]/edit.tsx new file mode 100644 index 0000000..8811af8 --- /dev/null +++ b/app/(application)/(user)/investment/[id]/edit.tsx @@ -0,0 +1,9 @@ +import { TextCustom, ViewWrapper } from "@/components"; + +export default function InvestmentEdit() { + return ( + + Edit + + ); +} diff --git a/app/(application)/(user)/investment/[id]/index.tsx b/app/(application)/(user)/investment/[id]/index.tsx new file mode 100644 index 0000000..5825d0c --- /dev/null +++ b/app/(application)/(user)/investment/[id]/index.tsx @@ -0,0 +1,9 @@ +import { TextCustom, ViewWrapper } from "@/components"; + +export default function InvestmentDetail() { + return ( + + Investment Detail + + ) +} \ No newline at end of file diff --git a/app/(application)/(user)/investment/[id]/list-of-document.tsx b/app/(application)/(user)/investment/[id]/list-of-document.tsx new file mode 100644 index 0000000..abda925 --- /dev/null +++ b/app/(application)/(user)/investment/[id]/list-of-document.tsx @@ -0,0 +1,9 @@ +import { TextCustom, ViewWrapper } from "@/components"; + +export default function InvestmentListOfDocument() { + return ( + + Document List + + ); +} diff --git a/bun.lock b/bun.lock index 1bce108..ab9bd15 100644 --- a/bun.lock +++ b/bun.lock @@ -11,6 +11,7 @@ "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.21", + "@types/lodash": "^4.17.20", "@types/react-native-vector-icons": "^6.4.18", "dayjs": "^1.11.13", "expo": "53.0.17", @@ -31,6 +32,7 @@ "expo-symbols": "~0.4.5", "expo-system-ui": "~5.0.10", "expo-web-browser": "~14.2.0", + "lodash": "^4.17.21", "react": "19.0.0", "react-dom": "19.0.0", "react-native": "0.79.5", @@ -451,6 +453,8 @@ "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="], + "@types/lodash": ["@types/lodash@4.17.20", "", {}, "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="], + "@types/node": ["@types/node@24.0.3", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg=="], "@types/react": ["@types/react@19.0.14", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-ixLZ7zG7j1fM0DijL9hDArwhwcCb4vqmePgwtV0GfnkHRSCUEv4LvzarcTdhoqgyMznUx/EhoTUv31CKZzkQlw=="], @@ -1159,6 +1163,8 @@ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], diff --git a/package-lock.json b/package-lock.json index 4856d08..9c323e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,16 +9,21 @@ "version": "1.0.0", "dependencies": { "@expo/vector-icons": "^14.1.0", + "@react-native-community/datetimepicker": "8.4.1", "@react-navigation/bottom-tabs": "^7.4.2", "@react-navigation/drawer": "^7.5.2", "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.21", "@types/react-native-vector-icons": "^6.4.18", + "dayjs": "^1.11.13", "expo": "53.0.17", "expo-blur": "~14.1.5", "expo-camera": "~16.1.10", + "expo-clipboard": "~7.1.5", "expo-constants": "~17.1.7", + "expo-document-picker": "~13.1.6", + "expo-file-system": "~18.1.11", "expo-font": "~13.3.2", "expo-haptics": "~14.1.4", "expo-image": "~2.3.2", @@ -37,6 +42,7 @@ "react-native-international-phone-number": "^0.9.3", "react-native-maps": "1.20.1", "react-native-otp-entry": "^1.8.5", + "react-native-pager-view": "6.7.1", "react-native-paper": "^5.14.5", "react-native-reanimated": "~3.17.4", "react-native-safe-area-context": "5.4.0", @@ -2801,6 +2807,29 @@ } } }, + "node_modules/@react-native-community/datetimepicker": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.4.1.tgz", + "integrity": "sha512-DrK+CUS5fZnz8dhzBezirkzQTcNDdaXer3oDLh0z4nc2tbdIdnzwvXCvi8IEOIvleoc9L95xS5tKUl0/Xv71Mg==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "expo": ">=52.0.0", + "react": "*", + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + } + }, "node_modules/@react-native/assets-registry": { "version": "0.79.5", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.79.5.tgz", @@ -5343,6 +5372,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -6331,6 +6366,17 @@ } } }, + "node_modules/expo-clipboard": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/expo-clipboard/-/expo-clipboard-7.1.5.tgz", + "integrity": "sha512-TCANUGOxouoJXxKBW5ASJl2WlmQLGpuZGemDCL2fO5ZMl57DGTypUmagb0CVUFxDl0yAtFIcESd78UsF9o64aw==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, "node_modules/expo-constants": { "version": "17.1.7", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.1.7.tgz", @@ -6345,6 +6391,15 @@ "react-native": "*" } }, + "node_modules/expo-document-picker": { + "version": "13.1.6", + "resolved": "https://registry.npmjs.org/expo-document-picker/-/expo-document-picker-13.1.6.tgz", + "integrity": "sha512-8FTQPDOkyCvFN/i4xyqzH7ELW4AsB6B3XBZQjn1FEdqpozo6rpNJRr7sWFU/93WrLgA9FJEKpKbyr6XxczK6BA==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-file-system": { "version": "18.1.11", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.1.11.tgz", @@ -10442,6 +10497,16 @@ "react-native": "*" } }, + "node_modules/react-native-pager-view": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-6.7.1.tgz", + "integrity": "sha512-cBSr6xw4g5N7Kd3VGWcf+kmaH7iBWb0DXAf2bVo3bXkzBcBbTOmYSvc0LVLHhUPW8nEq5WjT9LCIYAzgF++EXw==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-paper": { "version": "5.14.5", "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.14.5.tgz", diff --git a/package.json b/package.json index 2e57b6f..a56e141 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.21", + "@types/lodash": "^4.17.20", "@types/react-native-vector-icons": "^6.4.18", "dayjs": "^1.11.13", "expo": "53.0.17", @@ -38,6 +39,7 @@ "expo-symbols": "~0.4.5", "expo-system-ui": "~5.0.10", "expo-web-browser": "~14.2.0", + "lodash": "^4.17.21", "react": "19.0.0", "react-dom": "19.0.0", "react-native": "0.79.5", diff --git a/screens/Invesment/ButtonStatusSection.tsx b/screens/Invesment/ButtonStatusSection.tsx new file mode 100644 index 0000000..96af41e --- /dev/null +++ b/screens/Invesment/ButtonStatusSection.tsx @@ -0,0 +1,121 @@ +import { AlertDefaultSystem, ButtonCustom, Grid } from "@/components"; +import { router } from "expo-router"; + +export default function Investment_ButtonStatusSection({ + status, +}: { + status: string; +}) { + const handleBatalkanReview = () => { + AlertDefaultSystem({ + title: "Batalkan Review", + message: "Apakah Anda yakin ingin batalkan review ini?", + textLeft: "Batal", + textRight: "Ya", + onPressRight: () => { + console.log("Hapus"); + router.back(); + }, + }); + }; + + const handleAjukanReview = () => { + AlertDefaultSystem({ + title: "Ajukan Review", + message: "Apakah Anda yakin ingin ajukan review ini?", + textLeft: "Batal", + textRight: "Ya", + onPressRight: () => { + console.log("Hapus"); + router.back(); + }, + }); + }; + + const handleEditKembali = () => { + AlertDefaultSystem({ + title: "Edit Kembali", + message: "Apakah Anda yakin ingin edit kembali ini?", + textLeft: "Batal", + textRight: "Ya", + onPressRight: () => { + console.log("Hapus"); + router.back(); + }, + }); + }; + + const handleOpenDeleteAlert = () => { + AlertDefaultSystem({ + title: "Hapus", + message: "Apakah Anda yakin ingin menghapus data ini?", + textLeft: "Batal", + textRight: "Hapus", + onPressRight: () => { + console.log("Hapus"); + router.back(); + }, + }); + }; + + const DeleteButton = () => { + return ( + <> + + Hapus + + + ); + }; + + switch (status) { + case "publish": + return <>; + + case "review": + return ( + + Batalkan Review + + ); + + case "draft": + return ( + <> + + + + Ajukan Review + + + + {DeleteButton()} + + + + ); + + case "reject": + return ( + <> + + + + Edit Kembali + + + + {DeleteButton()} + + + + ); + + default: + return Status Undifined; + } +} diff --git a/screens/Invesment/StatusBox.tsx b/screens/Invesment/StatusBox.tsx new file mode 100644 index 0000000..7bb81a1 --- /dev/null +++ b/screens/Invesment/StatusBox.tsx @@ -0,0 +1,48 @@ +import { BaseBox, Grid, Spacing, TextCustom } from "@/components"; +import DUMMY_IMAGE from "@/constants/dummy-image-value"; +import { Image } from "expo-image"; +import { Href } from "expo-router"; +import { View } from "react-native"; + +interface Investment_StatusBoxProps { + id: string; + status: string; + href?: Href +} + +export default function Investment_StatusBox({ + id, + status, + href +}: Investment_StatusBoxProps) { + return ( + + + + + Title here : {status} 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! + + + + + + Target Dana: + + Rp. 7.500.000 + + + + + + + + + + ); +}