│ │ │ 1. Device Token Registration Error (HTTP 500) │ │ - File: service/api-device-token.ts │ │ - Fix: Hapus nested data wrapper pada payload │ │ - Improvement: Tambahkan error logging detail │ │ │ │ 2. Uncaught Promise Errors │ │ - File: components/Notification/NotificationInitializer.tsx │ │ - Fix: Better error handling untuk device token registration │ │ - File: app/(application)/(user)/home.tsx │ │ - Fix: Add .catch() untuk userData() dan error handling apiUser() │ │ - File: app/(application)/(user)/profile/[id]/index.tsx │ │ - Fix: Add error handling untuk apiProfile(), apiUser(), userData() │ │ │ │ 3. UI Improvements │ │ - File: app/(application)/(user)/home.tsx │ │ - Feature: 4 skeleton lingkaran untuk loading state grid features │ │ │ │ 4. Maps Migration │ │ - File: app/(application)/admin/maps.tsx │ │ - Change: Replace react-native-maps dengan MapsV2Custom (Maplibre) │ │ - Cleanup: Hapus unused imports dan interfaces │ │ │ │ Files Modified (7) │ │ - app/(application)/(user)/home.tsx │ │ - app/(application)/(user)/profile/[id]/index.tsx │ │ - app/(application)/admin/maps.tsx │ │ - components/Notification/NotificationInitializer.tsx │ │ - service/api-device-token.ts │ │ - constants/constans-value.ts │ │ - screens/Home/bottomFeatureSection.tsx │ │ - screens/UserSeach/MainView_V2.tsx ### No Issue
174 lines
4.7 KiB
TypeScript
174 lines
4.7 KiB
TypeScript
import {
|
|
ButtonCustom,
|
|
DrawerCustom,
|
|
DummyLandscapeImage,
|
|
Grid,
|
|
Spacing,
|
|
StackCustom,
|
|
TextCustom,
|
|
ViewWrapper,
|
|
} from "@/components";
|
|
import GridTwoView from "@/components/_ShareComponent/GridTwoView";
|
|
import { MapMarker, MapsV2Custom } from "@/components/Map/MapsV2Custom";
|
|
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
|
|
import { apiMapsGetAll } from "@/service/api-client/api-maps";
|
|
import { openInDeviceMaps } from "@/utils/openInDeviceMaps";
|
|
import { FontAwesome, Ionicons } from "@expo/vector-icons";
|
|
import { router, useFocusEffect } from "expo-router";
|
|
import { useCallback, useState } from "react";
|
|
|
|
export default function AdminMaps() {
|
|
const [list, setList] = useState<any[] | null>(null);
|
|
const [loadList, setLoadList] = useState(false);
|
|
const [openDrawer, setOpenDrawer] = useState(false);
|
|
const [selected, setSelected] = useState({
|
|
id: "",
|
|
bidangBisnis: "",
|
|
nomorTelepon: "",
|
|
alamatBisnis: "",
|
|
namePin: "",
|
|
imageId: "",
|
|
portofolioId: "",
|
|
latitude: 0,
|
|
longitude: 0,
|
|
});
|
|
|
|
useFocusEffect(
|
|
useCallback(() => {
|
|
handlerLoadList();
|
|
}, []),
|
|
);
|
|
|
|
const handlerLoadList = async () => {
|
|
try {
|
|
setLoadList(true);
|
|
const response = await apiMapsGetAll();
|
|
|
|
if (response.success) {
|
|
setList(response.data);
|
|
}
|
|
} catch (error) {
|
|
console.log("[ERROR]", error);
|
|
} finally {
|
|
setLoadList(false);
|
|
}
|
|
};
|
|
|
|
const markers: MapMarker[] = list?.map((item) => ({
|
|
id: item.id,
|
|
coordinate: [item.longitude, item.latitude] as [number, number],
|
|
imageId: item.Portofolio?.logoId,
|
|
onSelected: () => {
|
|
setOpenDrawer(true);
|
|
setSelected({
|
|
id: item?.id,
|
|
bidangBisnis: item?.Portofolio?.MasterBidangBisnis?.name,
|
|
nomorTelepon: item?.Portofolio?.tlpn,
|
|
alamatBisnis: item?.Portofolio?.alamatKantor,
|
|
namePin: item?.namePin,
|
|
imageId: item?.imageId,
|
|
portofolioId: item?.Portofolio?.id,
|
|
latitude: item?.latitude,
|
|
longitude: item?.longitude,
|
|
});
|
|
},
|
|
})) || [];
|
|
|
|
return (
|
|
<>
|
|
<ViewWrapper style={{ paddingInline: 0, paddingBlock: 0 }}>
|
|
<MapsV2Custom markers={markers} />
|
|
</ViewWrapper>
|
|
|
|
<DrawerCustom
|
|
isVisible={openDrawer}
|
|
closeDrawer={() => setOpenDrawer(false)}
|
|
height={"auto"}
|
|
>
|
|
{selected.imageId && (
|
|
<DummyLandscapeImage height={200} imageId={selected.imageId} />
|
|
)}
|
|
<Spacing />
|
|
<StackCustom gap={"xs"}>
|
|
<GridTwoView
|
|
spanLeft={2}
|
|
spanRight={10}
|
|
leftItem={
|
|
<FontAwesome
|
|
name="building-o"
|
|
size={ICON_SIZE_SMALL}
|
|
color="white"
|
|
/>
|
|
}
|
|
rightItem={<TextCustom>{selected.namePin}</TextCustom>}
|
|
/>
|
|
|
|
<GridTwoView
|
|
spanLeft={2}
|
|
spanRight={10}
|
|
leftItem={
|
|
<Ionicons
|
|
name="list-outline"
|
|
size={ICON_SIZE_SMALL}
|
|
color="white"
|
|
/>
|
|
}
|
|
rightItem={<TextCustom>{selected.bidangBisnis}</TextCustom>}
|
|
/>
|
|
|
|
<GridTwoView
|
|
spanLeft={2}
|
|
spanRight={10}
|
|
leftItem={
|
|
<Ionicons
|
|
name="call-outline"
|
|
size={ICON_SIZE_SMALL}
|
|
color="white"
|
|
/>
|
|
}
|
|
rightItem={<TextCustom>+{selected.nomorTelepon}</TextCustom>}
|
|
/>
|
|
<GridTwoView
|
|
spanLeft={2}
|
|
spanRight={10}
|
|
leftItem={
|
|
<Ionicons
|
|
name="location-outline"
|
|
size={ICON_SIZE_SMALL}
|
|
color="white"
|
|
/>
|
|
}
|
|
rightItem={<TextCustom>{selected.alamatBisnis}</TextCustom>}
|
|
/>
|
|
|
|
<Grid>
|
|
<Grid.Col span={6} style={{ paddingRight: 10 }}>
|
|
<ButtonCustom
|
|
onPress={() => {
|
|
setOpenDrawer(false);
|
|
router.push(`/portofolio/${selected.portofolioId}`);
|
|
}}
|
|
>
|
|
Detail
|
|
</ButtonCustom>
|
|
</Grid.Col>
|
|
<Grid.Col span={6} style={{ paddingLeft: 10 }}>
|
|
<ButtonCustom
|
|
onPress={() => {
|
|
openInDeviceMaps({
|
|
latitude: selected.latitude,
|
|
longitude: selected.longitude,
|
|
title: selected.namePin,
|
|
});
|
|
}}
|
|
>
|
|
Buka Maps
|
|
</ButtonCustom>
|
|
</Grid.Col>
|
|
</Grid>
|
|
</StackCustom>
|
|
</DrawerCustom>
|
|
</>
|
|
);
|
|
}
|