From 6887f85e6a885b0351f3bd321b638f097c16665b Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Mon, 1 Sep 2025 17:10:25 +0800 Subject: [PATCH] Poortofoloio Fix: - service/api-client/api-portofolio.ts : api edit detail. logo, medsos ### No Issue --- app/(application)/(user)/maps/index.tsx | 12 +- .../(user)/portofolio/[id]/edit-logo.tsx | 120 +++++++++++- .../portofolio/[id]/edit-social-media.tsx | 112 +++++++++++- .../(user)/portofolio/[id]/edit.tsx | 172 +++++++++++++----- .../(user)/portofolio/[id]/index.tsx | 2 +- screens/Portofolio/MenuDrawer.tsx | 2 +- service/api-client/api-portofolio.ts | 28 ++- 7 files changed, 381 insertions(+), 67 deletions(-) diff --git a/app/(application)/(user)/maps/index.tsx b/app/(application)/(user)/maps/index.tsx index b4a9f78..87e5c5d 100644 --- a/app/(application)/(user)/maps/index.tsx +++ b/app/(application)/(user)/maps/index.tsx @@ -1,9 +1,19 @@ import { MapCustom, ViewWrapper } from "@/components"; +import { View } from "react-native"; +import MapView from "react-native-maps"; export default function Maps() { return ( - + {/* */} + + + ); } diff --git a/app/(application)/(user)/portofolio/[id]/edit-logo.tsx b/app/(application)/(user)/portofolio/[id]/edit-logo.tsx index 26f6e76..189c9c9 100644 --- a/app/(application)/(user)/portofolio/[id]/edit-logo.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit-logo.tsx @@ -1,25 +1,125 @@ import { - AvatarCustom, BaseBox, BoxButtonOnFooter, ButtonCenteredOnly, ButtonCustom, - ViewWrapper, + ViewWrapper } from "@/components"; +import API_STRORAGE from "@/constants/base-url-api-strorage"; +import DIRECTORY_ID from "@/constants/directory-id"; +import DUMMY_IMAGE from "@/constants/dummy-image-value"; +import { useAuth } from "@/hooks/use-auth"; +import { apiFileDelete } from "@/service/api-client/api-file"; +import { + apiGetOnePortofolio, + apiUpdatePortofolio, +} from "@/service/api-client/api-portofolio"; +import { uploadImageService } from "@/service/upload-service"; +import pickImage from "@/utils/pickImage"; +import { Image } from "expo-image"; import { router, useLocalSearchParams } from "expo-router"; +import { useEffect, useState } from "react"; +import Toast from "react-native-toast-message"; export default function PortofolioEditLogo() { const { id } = useLocalSearchParams(); + const [logoId, setLogoId] = useState(); + const [imageUri, setImageUri] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const { token } = useAuth(); + + useEffect(() => { + onLoadData(id as string); + }, [id]); + + const onLoadData = async (id: string) => { + const response = await apiGetOnePortofolio({ id: id }); + console.log( + "Response portofolio >>", + JSON.stringify(response.data.logoId, null, 2) + ); + setLogoId(response.data.logoId); + }; + + async function onUpload() { + try { + setIsLoading(true); + + const response = await uploadImageService({ + imageUri, + dirId: DIRECTORY_ID.portofolio_logo, + }); + + if (response.success) { + const fileId = response.data.id; + const responseUpdate = await apiUpdatePortofolio({ + id: id as string, + data: { fileId }, + category: "logo", + }); + + if (!responseUpdate.success) { + Toast.show({ + type: "error", + text1: "Info", + text2: responseUpdate.message, + }); + return; + } + + if (logoId) { + const deletePrevFile = await apiFileDelete({ + token: token as string, + id: logoId as string, + }); + + if (!deletePrevFile.success) { + console.log("error delete prev file >>", deletePrevFile.message); + } + } + + Toast.show({ + type: "success", + text1: "Sukses", + text2: "Logo berhasil diupdate", + }); + + router.back(); + } + } catch (error) { + Toast.show({ + type: "error", + text1: "Gagal", + text2: error as string, + }); + } finally { + setIsLoading(false); + } + } + + const image = imageUri ? ( + + ) : ( + + ); const buttonFooter = ( { - console.log("Simpan logo "); - router.back(); + onUpload(); }} > - Simpan + Update ); @@ -34,13 +134,17 @@ export default function PortofolioEditLogo() { height: 250, }} > - + {image} router.navigate(`/take-picture/${id}`)} + onPress={() => { + pickImage({ + setImageUri, + }); + }} > - Update + Upload diff --git a/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx b/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx index a6ec430..1770c3f 100644 --- a/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx @@ -4,20 +4,87 @@ import { TextInputCustom, ViewWrapper, } from "@/components"; +import { + apiGetOnePortofolio, + apiUpdatePortofolio, +} from "@/service/api-client/api-portofolio"; import { useLocalSearchParams, router } from "expo-router"; +import { useEffect, useState } from "react"; +import Toast from "react-native-toast-message"; export default function PortofolioEditSocialMedia() { const { id } = useLocalSearchParams(); + console.log("ID >>", id); + const [isLoading, setIsLoading] = useState(false); + const [data, setData] = useState({ + facebook: "", + twitter: "", + instagram: "", + tiktok: "", + youtube: "", + }); + + useEffect(() => { + onLoadData(id as string); + }, [id]); + + const onLoadData = async (id: string) => { + const response = await apiGetOnePortofolio({ id: id }); + console.log( + "Response portofolio >>", + JSON.stringify(response.data.Portofolio_MediaSosial, null, 2) + ); + const data = response.data.Portofolio_MediaSosial; + setData({ + facebook: data.facebook, + twitter: data.twitter, + instagram: data.instagram, + tiktok: data.tiktok, + youtube: data.youtube, + }); + }; + + const onSubmitUpdate = async () => { + try { + setIsLoading(true); + const response = await apiUpdatePortofolio({ + id: id as string, + data: data, + category: "medsos", + }); + + if (!response.success) { + Toast.show({ + type: "info", + text1: "Info", + text2: response.message, + }); + + return; + } + + Toast.show({ + type: "success", + text1: "Sukses", + text2: "Data media terupdate", + }); + + router.back(); + } catch (error) { + console.log("Error onSubmitUpdate", error); + } finally { + setIsLoading(false); + } + }; const buttonFooter = ( { - console.log(`Simpan sosmed ${id}`); - router.back(); - }} + isLoading={isLoading} + disabled={isLoading} + onPress={onSubmitUpdate} > - Simpan + Update ); @@ -25,11 +92,36 @@ export default function PortofolioEditSocialMedia() { return ( <> - - - - - + setData({ ...data, tiktok: value })} + label="Tiktok" + placeholder="Masukkan tiktok" + /> + setData({ ...data, instagram: value })} + label="Instagram" + placeholder="Masukkan instagram" + /> + setData({ ...data, facebook: value })} + label="Facebook" + placeholder="Masukkan facebook" + /> + setData({ ...data, twitter: value })} + label="Twitter" + placeholder="Masukkan twitter" + /> + setData({ ...data, youtube: value })} + label="Youtube" + placeholder="Masukkan youtube" + /> ); diff --git a/app/(application)/(user)/portofolio/[id]/edit.tsx b/app/(application)/(user)/portofolio/[id]/edit.tsx index e3f7ec8..ea92267 100644 --- a/app/(application)/(user)/portofolio/[id]/edit.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit.tsx @@ -1,57 +1,134 @@ import { - BoxButtonOnFooter, - ButtonCenteredOnly, - ButtonCustom, - Grid, - SelectCustom, - Spacing, - StackCustom, - TextAreaCustom, - TextCustom, - TextInputCustom, - ViewWrapper, + BoxButtonOnFooter, + ButtonCustom, + SelectCustom, + Spacing, + StackCustom, + TextAreaCustom, + TextCustom, + TextInputCustom, + ViewWrapper, } from "@/components"; import { MainColor } from "@/constants/color-palet"; -import dummyMasterBidangBisnis from "@/lib/dummy-data/master-bidang-bisnis"; -import dummyMasterSubBidangBisnis from "@/lib/dummy-data/master-sub-bidang-bisnis"; -import { Ionicons } from "@expo/vector-icons"; +import { apiMasterBidangBisnis } from "@/service/api-client/api-master"; +import { + apiGetOnePortofolio, + apiUpdatePortofolio, +} from "@/service/api-client/api-portofolio"; +import { IMasterBidangBisnis } from "@/types/Type-Master"; import { router, useLocalSearchParams } from "expo-router"; -import { useState } from "react"; -import { Text, TouchableOpacity, View } from "react-native"; +import { useEffect, useState } from "react"; +import { Text, View } from "react-native"; import PhoneInput, { ICountry } from "react-native-international-phone-number"; +import Toast from "react-native-toast-message"; + +interface IFormData { + id_Portofolio: string; + namaBisnis: string; + alamatKantor: string; + tlpn: string; + deskripsi: string; + masterBidangBisnisId: string; +} export default function PortofolioEdit() { const { id } = useLocalSearchParams(); + const [isLoading, setIsLoading] = useState(false); const [selectedCountry, setSelectedCountry] = useState(null); - const [inputValue, setInputValue] = useState(""); - - const [data, setData] = useState({ - namaBisnis: "", - bidang_usaha: "", - sub_bidang_usaha: "", - alamat: "", - nomor_telepon: "", - deskripsi: "", - }); + const [bidangBisnis, setBidangBisnis] = useState([]); + const [data, setData] = useState({}); function handleInputValue(phoneNumber: string) { - setInputValue(phoneNumber); + setData({ ...data, tlpn: phoneNumber }); } function handleSelectedCountry(country: ICountry) { setSelectedCountry(country); } - function handleSave() { - console.log(`Update portofolio berhasil ${id}`); - router.back(); - } + useEffect(() => { + onLoadData(id as string); + onLoadMaster(); + }, [id]); + + const onLoadData = async (id: string) => { + const response = await apiGetOnePortofolio({ id: id }); + + if (response.data.tlpn && response.data.tlpn.includes("62")) { + const fixNumber = response.data.tlpn.replace("62", ""); + console.log("Fix Number >>", fixNumber); + setData({ ...response.data, tlpn: fixNumber }); + } + }; + + const onLoadMaster = async () => { + try { + const response = await apiMasterBidangBisnis(); + setBidangBisnis(response.data); + } catch (error) { + setBidangBisnis([]); + console.log("Error onLoadMasterBidangBisnis", error); + } + }; + + const handleSubmitUpdate = async () => { + try { + setIsLoading(true); + const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; + const fixNumber = data.tlpn.replace(/\s+/g, ""); + const realNumber = callingCode + fixNumber; + + const newData: IFormData = { + id_Portofolio: data.id_Portofolio, + namaBisnis: data.namaBisnis, + alamatKantor: data.alamatKantor, + tlpn: realNumber, + deskripsi: data.deskripsi, + masterBidangBisnisId: data.masterBidangBisnisId, + }; + + const response = await apiUpdatePortofolio({ + id: id as string, + data: newData, + category: "detail", + }); + + if (!response.success) { + Toast.show({ + type: "info", + text1: "Info", + text2: response.message, + }); + + return + } + + Toast.show({ + type: "success", + text1: "Sukses", + text2: "Data terupdate", + }); + + router.back(); + } catch (error) { + console.log("Error handleSubmitUpdate", error); + } finally { + setIsLoading(false); + } + }; const buttonUpdate = ( - Simpan + + Update + ); + return ( <> @@ -60,22 +137,26 @@ export default function PortofolioEdit() { required label="Nama Bisnis" placeholder="Masukkan nama bisnis" + value={data.namaBisnis} + onChangeText={(value: any) => + setData({ ...data, namaBisnis: value }) + } /> ({ + data={bidangBisnis?.map((item) => ({ label: item.name, value: item.id, }))} - value={data.bidang_usaha} + value={data.masterBidangBisnisId} onChange={(value) => { - setData({ ...(data as any), bidang_usaha: value }); + setData({ ...(data as any), masterBidangBisnisId: value }); }} /> - + {/* { - setData({ ...(data as any), sub_bidang_usaha: value }); + setData({ ...(data as any), masterSubBidangBisnisId: value }); }} /> @@ -99,11 +180,12 @@ export default function PortofolioEdit() { - - console.log("add")}> + */} + {/* console.log("add")}> Tambah Pilihan - + */} + @@ -113,7 +195,7 @@ export default function PortofolioEdit() { + setData({ ...data, alamatKantor: value }) + } /> diff --git a/app/(application)/(user)/portofolio/[id]/index.tsx b/app/(application)/(user)/portofolio/[id]/index.tsx index 2d2cf39..3cbc8e6 100644 --- a/app/(application)/(user)/portofolio/[id]/index.tsx +++ b/app/(application)/(user)/portofolio/[id]/index.tsx @@ -91,7 +91,7 @@ export default function Portofolio() { ); diff --git a/service/api-client/api-portofolio.ts b/service/api-client/api-portofolio.ts index 26bbad2..5424ea6 100644 --- a/service/api-client/api-portofolio.ts +++ b/service/api-client/api-portofolio.ts @@ -25,7 +25,7 @@ export async function apiGetPortofolio({ id }: { id: string }) { export async function apiGetOnePortofolio({ id }: { id: string }) { try { const response = await apiConfig.get(`/mobile/portofolio/${id}`); - + return response.data; } catch (error) { throw error; @@ -35,10 +35,32 @@ export async function apiGetOnePortofolio({ id }: { id: string }) { export async function apiDeletePortofolio({ id }: { id: string }) { try { const response = await apiConfig.delete(`/mobile/portofolio/${id}`); - + + return response.data; + } catch (error) { + throw error; + } +} + +export async function apiUpdatePortofolio({ + id, + data, + category, +}: { + id: string; + data: any; + category: "detail" | "medsos" | "logo"; +}) { + try { + const response = await apiConfig.put( + `/mobile/portofolio/${id}?category=${category}`, + { + data: data, + } + ); + return response.data; } catch (error) { throw error; } } - \ No newline at end of file