Fix Bug
Maps Platform Update - components/Map/MapSelectedPlatform.tsx - components/Map/MapSelectedV2.tsx Maps Screens - screens/Maps/ScreenMapsCreate.tsx - screens/Maps/ScreenMapsEdit.tsx Home - screens/Home/bottomFeatureSection.tsx Config & Native - app.config.js - android/app/build.gradle - ios/HIPMIBadungConnect.xcodeproj/project.pbxproj - ios/HIPMIBadungConnect/Info.plist ### No Issue
This commit is contained in:
@@ -100,8 +100,8 @@ packagingOptions {
|
||||
applicationId 'com.bip.hipmimobileapp'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 4
|
||||
versionName "1.0.1"
|
||||
versionCode 1
|
||||
versionName "1.0.2"
|
||||
|
||||
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ require("dotenv").config();
|
||||
export default {
|
||||
name: "HIPMI Badung Connect",
|
||||
slug: "hipmi-mobile",
|
||||
version: "1.0.1",
|
||||
version: "1.0.2",
|
||||
orientation: "portrait",
|
||||
icon: "./assets/images/icon.png",
|
||||
scheme: "hipmimobile",
|
||||
@@ -21,7 +21,7 @@ export default {
|
||||
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
||||
},
|
||||
associatedDomains: ["applinks:cld-dkr-staging-hipmi.wibudev.com"],
|
||||
buildNumber: "21",
|
||||
buildNumber: "1",
|
||||
},
|
||||
|
||||
android: {
|
||||
@@ -32,7 +32,7 @@ export default {
|
||||
},
|
||||
edgeToEdgeEnabled: true,
|
||||
package: "com.bip.hipmimobileapp",
|
||||
versionCode: 4,
|
||||
versionCode: 1,
|
||||
// softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration
|
||||
intentFilters: [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Platform } from "react-native";
|
||||
import MapSelected from "./MapSelected";
|
||||
import { MapSelectedV2 } from "./MapSelectedV2";
|
||||
import { Region } from "./MapSelectedV2";
|
||||
import MapSelectedV2 from "./MapSelectedV2";
|
||||
import { LatLng } from "react-native-maps";
|
||||
|
||||
/**
|
||||
@@ -58,18 +57,18 @@ export function MapSelectedPlatform({
|
||||
showsMyLocationButton = true,
|
||||
}: MapSelectedPlatformProps) {
|
||||
// iOS: Gunakan react-native-maps
|
||||
if (Platform.OS === "ios") {
|
||||
return (
|
||||
<MapSelected
|
||||
initialRegion={initialRegion}
|
||||
selectedLocation={(selectedLocation as LatLng) || { latitude: 0, longitude: 0 }}
|
||||
setSelectedLocation={(location: LatLng) => {
|
||||
onLocationSelect(location);
|
||||
}}
|
||||
height={height}
|
||||
/>
|
||||
);
|
||||
}
|
||||
// if (Platform.OS === "ios") {
|
||||
// return (
|
||||
// <MapSelected
|
||||
// initialRegion={initialRegion}
|
||||
// selectedLocation={(selectedLocation as LatLng) || { latitude: 0, longitude: 0 }}
|
||||
// setSelectedLocation={(location: LatLng) => {
|
||||
// onLocationSelect(location);
|
||||
// }}
|
||||
// height={height}
|
||||
// />
|
||||
// );
|
||||
// }
|
||||
|
||||
// Android: Gunakan MapLibre
|
||||
// Konversi dari LatLng ke [longitude, latitude] jika perlu
|
||||
@@ -81,7 +80,6 @@ export function MapSelectedPlatform({
|
||||
|
||||
return (
|
||||
<MapSelectedV2
|
||||
initialRegion={initialRegion as Region}
|
||||
selectedLocation={androidLocation}
|
||||
onLocationSelect={(location: [number, number]) => {
|
||||
// Konversi dari [longitude, latitude] ke LatLng untuk konsistensi
|
||||
@@ -92,8 +90,8 @@ export function MapSelectedPlatform({
|
||||
onLocationSelect(latLng);
|
||||
}}
|
||||
height={height}
|
||||
showUserLocation={showUserLocation}
|
||||
showsMyLocationButton={showsMyLocationButton}
|
||||
// showUserLocation={showUserLocation}
|
||||
// showsMyLocationButton={showsMyLocationButton}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,125 +1,119 @@
|
||||
import React, { useCallback, useMemo, useRef } from "react";
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
ViewStyle,
|
||||
StyleProp,
|
||||
} from "react-native";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import React, { useCallback, useRef, useEffect, useState } from "react";
|
||||
import { StyleSheet, View, ActivityIndicator } from "react-native";
|
||||
import {
|
||||
MapView,
|
||||
Camera,
|
||||
PointAnnotation,
|
||||
} from "@maplibre/maplibre-react-native";
|
||||
import * as Location from "expo-location";
|
||||
|
||||
const DEFAULT_MAP_STYLE = "https://tiles.openfreemap.org/styles/liberty";
|
||||
const MAP_STYLE = "https://tiles.openfreemap.org/styles/liberty";
|
||||
const DEBOUNCE_MS = 800;
|
||||
|
||||
export interface Region {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
latitudeDelta: number;
|
||||
longitudeDelta: number;
|
||||
}
|
||||
|
||||
export interface MapSelectedV2Props {
|
||||
initialRegion?: Region;
|
||||
interface Props {
|
||||
selectedLocation?: [number, number];
|
||||
onLocationSelect?: (location: [number, number]) => void;
|
||||
height?: number;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
mapViewStyle?: StyleProp<ViewStyle>;
|
||||
showUserLocation?: boolean;
|
||||
showsMyLocationButton?: boolean;
|
||||
mapStyle?: string;
|
||||
zoomLevel?: number;
|
||||
}
|
||||
|
||||
// ✅ Marker simple tanpa Animated — hapus pulse animation
|
||||
function SelectedLocationMarker({
|
||||
color = MainColor.darkblue,
|
||||
}: {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}) {
|
||||
return (
|
||||
<View style={styles.markerContainer}>
|
||||
<View style={[styles.markerRing, { borderColor: color }]} />
|
||||
<View style={[styles.markerDot, { backgroundColor: color }]} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export function MapSelectedV2({
|
||||
initialRegion,
|
||||
selectedLocation,
|
||||
onLocationSelect,
|
||||
height = 400,
|
||||
style = styles.container,
|
||||
mapViewStyle = styles.map,
|
||||
mapStyle,
|
||||
zoomLevel = 12,
|
||||
}: MapSelectedV2Props) {
|
||||
const defaultRegion = useMemo(
|
||||
() => ({
|
||||
latitude: -8.737109,
|
||||
longitude: 115.1756897,
|
||||
latitudeDelta: 0.1,
|
||||
longitudeDelta: 0.1,
|
||||
}),
|
||||
[],
|
||||
}: Props) {
|
||||
const lastTapRef = useRef<number>(0);
|
||||
const cameraRef = useRef<any>(null);
|
||||
|
||||
const [userLocation, setUserLocation] = useState<[number, number] | null>(
|
||||
null,
|
||||
);
|
||||
const [isLoadingLocation, setIsLoadingLocation] = useState(true);
|
||||
|
||||
const region = initialRegion || defaultRegion;
|
||||
// ✅ Ambil lokasi user saat pertama mount
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
if (status !== "granted") {
|
||||
console.log("Permission lokasi ditolak");
|
||||
setIsLoadingLocation(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// ✅ Simpan initial center — TIDAK berubah saat user tap
|
||||
const initialCenter = useRef<[number, number]>([
|
||||
region.longitude,
|
||||
region.latitude,
|
||||
]);
|
||||
const location = await Location.getCurrentPositionAsync({
|
||||
accuracy: Location.Accuracy.Balanced,
|
||||
});
|
||||
|
||||
const coords: [number, number] = [
|
||||
location.coords.longitude,
|
||||
location.coords.latitude,
|
||||
];
|
||||
|
||||
setUserLocation(coords);
|
||||
|
||||
// ✅ Fly ke posisi user jika belum ada selectedLocation
|
||||
if (!selectedLocation && cameraRef.current) {
|
||||
cameraRef.current.flyTo(coords, 1000);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Gagal ambil lokasi:", error);
|
||||
} finally {
|
||||
setIsLoadingLocation(false);
|
||||
}
|
||||
})();
|
||||
}, [isLoadingLocation]);
|
||||
|
||||
const handleMapPress = useCallback(
|
||||
(event: any) => {
|
||||
const coordinate = event?.geometry?.coordinates || event?.coordinates;
|
||||
if (coordinate && Array.isArray(coordinate) && coordinate.length === 2) {
|
||||
console.log("[MapSelectedV2] coordinate", coordinate);
|
||||
onLocationSelect?.([coordinate[0], coordinate[1]]);
|
||||
}
|
||||
const now = Date.now();
|
||||
if (now - lastTapRef.current < DEBOUNCE_MS) return;
|
||||
lastTapRef.current = now;
|
||||
|
||||
const coords = event?.geometry?.coordinates;
|
||||
if (!coords || coords.length < 2) return;
|
||||
|
||||
onLocationSelect?.([coords[0], coords[1]]);
|
||||
},
|
||||
[onLocationSelect],
|
||||
);
|
||||
|
||||
// Center awal kamera:
|
||||
// 1. Jika ada selectedLocation → pakai itu
|
||||
// 2. Jika ada userLocation → pakai itu
|
||||
// 3. Fallback → Bali
|
||||
const initialCenter: [number, number] = selectedLocation ??
|
||||
userLocation ?? [115.1756897, -8.737109];
|
||||
|
||||
return (
|
||||
<View style={[style, { height }]} collapsable={false}>
|
||||
<View style={{ height, width: "100%" }}>
|
||||
{/* Loading indicator saat fetch lokasi */}
|
||||
{isLoadingLocation && (
|
||||
<View style={styles.loadingOverlay}>
|
||||
<ActivityIndicator size="small" color="#0a1f44" />
|
||||
</View>
|
||||
)}
|
||||
|
||||
<MapView
|
||||
style={mapViewStyle}
|
||||
mapStyle={mapStyle || DEFAULT_MAP_STYLE}
|
||||
style={StyleSheet.absoluteFillObject}
|
||||
mapStyle={MAP_STYLE}
|
||||
onPress={handleMapPress}
|
||||
logoEnabled={false}
|
||||
compassEnabled={true}
|
||||
compassViewPosition={2}
|
||||
compassViewMargins={{ x: 10, y: 10 }}
|
||||
scrollEnabled={true}
|
||||
zoomEnabled={true}
|
||||
rotateEnabled={true}
|
||||
pitchEnabled={false}
|
||||
>
|
||||
{/* ✅ Camera hanya set sekali di awal, tidak reactive ke selectedLocation */}
|
||||
<Camera
|
||||
ref={cameraRef}
|
||||
defaultSettings={{
|
||||
centerCoordinate: initialCenter.current,
|
||||
zoomLevel: zoomLevel,
|
||||
centerCoordinate: initialCenter,
|
||||
zoomLevel: 14,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* ✅ Hanya render PointAnnotation jika ada selectedLocation */}
|
||||
{/* ✅ Key statis — tidak pernah unmount/remount */}
|
||||
{selectedLocation && (
|
||||
<PointAnnotation
|
||||
id="selected-location"
|
||||
key="selected-location"
|
||||
coordinate={selectedLocation}
|
||||
>
|
||||
<SelectedLocationMarker />
|
||||
<View style={styles.dot} />
|
||||
</PointAnnotation>
|
||||
)}
|
||||
</MapView>
|
||||
@@ -128,37 +122,29 @@ export function MapSelectedV2({
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: "100%",
|
||||
backgroundColor: "#f5f5f5",
|
||||
overflow: "hidden",
|
||||
borderRadius: 8,
|
||||
dot: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
backgroundColor: "#0a1f44",
|
||||
borderWidth: 2,
|
||||
borderColor: "#fff",
|
||||
},
|
||||
map: {
|
||||
flex: 1,
|
||||
},
|
||||
markerContainer: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
// ✅ Ring statis pengganti pulse animation
|
||||
markerRing: {
|
||||
loadingOverlay: {
|
||||
position: "absolute",
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
borderWidth: 2,
|
||||
opacity: 0.4,
|
||||
},
|
||||
markerDot: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
borderRadius: 8,
|
||||
borderWidth: 2,
|
||||
borderColor: "#FFFFFF",
|
||||
top: 10,
|
||||
alignSelf: "center",
|
||||
zIndex: 10,
|
||||
backgroundColor: "#fff",
|
||||
borderRadius: 20,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
elevation: 4,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 4,
|
||||
},
|
||||
});
|
||||
|
||||
export default MapSelectedV2;
|
||||
export default MapSelectedV2;
|
||||
|
||||
@@ -165,6 +165,12 @@
|
||||
CCCF75FD0B87410193A6B7DB /* Remove signature files (Xcode workaround) */,
|
||||
51F61F14096F4B7FBD9344A7 /* Remove signature files (Xcode workaround) */,
|
||||
60F3AE3AC4B24C2FA7FC8F10 /* Remove signature files (Xcode workaround) */,
|
||||
E188CB171C1B4A4DA64BC5C4 /* Remove signature files (Xcode workaround) */,
|
||||
90714A8C562E4676B84E6E07 /* Remove signature files (Xcode workaround) */,
|
||||
DB93AB500BC2459E8BAE3F74 /* Remove signature files (Xcode workaround) */,
|
||||
EEC6AC8AF9C04E91AA81C190 /* Remove signature files (Xcode workaround) */,
|
||||
D2BED766D85C4781B154BD69 /* Remove signature files (Xcode workaround) */,
|
||||
E01278D305D540D5B29ED50A /* Remove signature files (Xcode workaround) */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -671,6 +677,108 @@
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
E188CB171C1B4A4DA64BC5C4 /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
90714A8C562E4676B84E6E07 /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
DB93AB500BC2459E8BAE3F74 /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
EEC6AC8AF9C04E91AA81C190 /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
D2BED766D85C4781B154BD69 /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
E01278D305D540D5B29ED50A /* Remove signature files (Xcode workaround) */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
name = "Remove signature files (Xcode workaround)";
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "
|
||||
echo \"Remove signature files (Xcode workaround)\";
|
||||
rm -rf \"$CONFIGURATION_BUILD_DIR/MapLibre.xcframework-ios.signature\";
|
||||
";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.1</string>
|
||||
<string>1.0.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -39,7 +39,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>21</string>
|
||||
<string>1</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { apiJobGetAll } from "@/service/api-client/api-job";
|
||||
import CustomSkeleton from "@/components/_ShareComponent/SkeletonCustom";
|
||||
|
||||
export default function Home_BottomFeatureSection() {
|
||||
const [listData, setListData] = useState<any>([]);
|
||||
const [listData, setListData] = useState<any[] | null>(null);
|
||||
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
@@ -17,7 +17,7 @@ export default function Home_BottomFeatureSection() {
|
||||
category: "beranda",
|
||||
});
|
||||
|
||||
// console.log("[DATA JOB]", JSON.stringify(response.data, null, 2));
|
||||
console.log("[DATA JOB]", JSON.stringify(response.data, null, 2));
|
||||
const result = response.data
|
||||
.sort(
|
||||
(a: any, b: any) =>
|
||||
@@ -36,7 +36,7 @@ export default function Home_BottomFeatureSection() {
|
||||
}, [])
|
||||
);
|
||||
|
||||
if (!listData || listData.length === 0) {
|
||||
if (listData === null) {
|
||||
return <CustomSkeleton height={200}/>
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function Home_BottomFeatureSection() {
|
||||
|
||||
<View style={stylesHome.vacancyList}>
|
||||
{/* Vacancy Item 1 */}
|
||||
{listData.map((item: any, index: number) => (
|
||||
{listData?.map((item: any, index: number) => (
|
||||
<View style={stylesHome.vacancyItem} key={index}>
|
||||
<View style={stylesHome.vacancyDetails}>
|
||||
<TextCustom bold color="yellow" truncate size="large">
|
||||
|
||||
@@ -20,7 +20,6 @@ import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { LatLng } from "react-native-maps";
|
||||
import Toast from "react-native-toast-message";
|
||||
import MapSelected from "@/components/Map/MapSelected";
|
||||
|
||||
/**
|
||||
* Screen untuk create maps
|
||||
@@ -150,14 +149,9 @@ export function Maps_ScreenMapsCreate() {
|
||||
<InformationBox text="Tentukan lokasi pin map dengan menekan pada map." />
|
||||
|
||||
<BaseBox>
|
||||
{/* <MapSelected
|
||||
selectedLocation={selectedLocation as any}
|
||||
setSelectedLocation={setSelectedLocation}
|
||||
/> */}
|
||||
<MapSelectedPlatform
|
||||
selectedLocation={selectedLocation}
|
||||
onLocationSelect={(location) => {
|
||||
// Set location (auto handle LatLng format)
|
||||
setSelectedLocation(location as LatLng);
|
||||
}}
|
||||
height={300}
|
||||
|
||||
@@ -9,6 +9,9 @@ import {
|
||||
TextInputCustom,
|
||||
ViewWrapper,
|
||||
} from "@/components";
|
||||
import CustomSkeleton from "@/components/_ShareComponent/SkeletonCustom";
|
||||
import { MapSelectedPlatform } from "@/components/Map/MapSelectedPlatform";
|
||||
import MapSelectedV2 from "@/components/Map/MapSelectedV2";
|
||||
import API_IMAGE from "@/constants/api-storage";
|
||||
import DIRECTORY_ID from "@/constants/directory-id";
|
||||
import { apiMapsGetOne, apiMapsUpdate } from "@/service/api-client/api-maps";
|
||||
@@ -16,8 +19,7 @@ import { uploadFileService } from "@/service/upload-service";
|
||||
import pickFile, { IFileData } from "@/utils/pickFile";
|
||||
import { router, useFocusEffect, useLocalSearchParams } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import { StyleSheet, View } from "react-native";
|
||||
import MapView, { LatLng, Marker } from "react-native-maps";
|
||||
import { LatLng } from "react-native-maps";
|
||||
import Toast from "react-native-toast-message";
|
||||
|
||||
const defaultRegion = {
|
||||
@@ -43,7 +45,7 @@ export function Maps_ScreenMapsEdit() {
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
onLoadData();
|
||||
}, [id])
|
||||
}, [id]),
|
||||
);
|
||||
|
||||
const onLoadData = async () => {
|
||||
@@ -64,10 +66,14 @@ export function Maps_ScreenMapsEdit() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleMapPress = (event: any) => {
|
||||
const { latitude, longitude } = event.nativeEvent.coordinate;
|
||||
const location = { latitude, longitude };
|
||||
setSelectedLocation(location);
|
||||
const handleLocationSelect = (location: LatLng | [number, number]) => {
|
||||
if (Array.isArray(location)) {
|
||||
// Android format: [longitude, latitude]
|
||||
setSelectedLocation({ latitude: location[1], longitude: location[0] });
|
||||
} else {
|
||||
// iOS format: LatLng
|
||||
setSelectedLocation(location);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
@@ -149,51 +155,41 @@ export function Maps_ScreenMapsEdit() {
|
||||
</BoxButtonOnFooter>
|
||||
);
|
||||
|
||||
const initialRegion =
|
||||
data?.latitude && data?.longitude
|
||||
? {
|
||||
latitude: Number(data?.latitude),
|
||||
longitude: Number(data?.longitude),
|
||||
latitudeDelta: 0.1,
|
||||
longitudeDelta: 0.1,
|
||||
}
|
||||
: defaultRegion;
|
||||
|
||||
return (
|
||||
<ViewWrapper footerComponent={buttonFooter}>
|
||||
<InformationBox text="Tentukan lokasi pin map dengan menekan pada map." />
|
||||
|
||||
<View style={[styles.container, { height: 400 }]}>
|
||||
<MapView
|
||||
style={styles.map}
|
||||
initialRegion={
|
||||
data?.latitude && data?.longitude
|
||||
? {
|
||||
latitude: data?.latitude,
|
||||
longitude: data?.longitude,
|
||||
latitudeDelta: 0.1,
|
||||
longitudeDelta: 0.1,
|
||||
}
|
||||
: defaultRegion
|
||||
}
|
||||
onPress={handleMapPress}
|
||||
showsUserLocation={true}
|
||||
showsMyLocationButton={true}
|
||||
loadingEnabled={true}
|
||||
loadingIndicatorColor="#666"
|
||||
loadingBackgroundColor="#f0f0f0"
|
||||
>
|
||||
{selectedLocation ? (
|
||||
<Marker
|
||||
coordinate={selectedLocation}
|
||||
title="Lokasi Dipilih"
|
||||
description={`Lat: ${selectedLocation.latitude.toFixed(
|
||||
6
|
||||
)}, Lng: ${selectedLocation.longitude.toFixed(6)}`}
|
||||
pinColor="red"
|
||||
/>
|
||||
) : (
|
||||
<Marker
|
||||
coordinate={defaultRegion}
|
||||
title="Lokasi Dipilih"
|
||||
description={`Lat: ${defaultRegion.latitude.toFixed(
|
||||
6
|
||||
)}, Lng: ${defaultRegion.longitude.toFixed(6)}`}
|
||||
pinColor="red"
|
||||
/>
|
||||
)}
|
||||
</MapView>
|
||||
</View>
|
||||
{/* <MapSelectedPlatform
|
||||
initialRegion={initialRegion}
|
||||
selectedLocation={selectedLocation}
|
||||
onLocationSelect={handleLocationSelect}
|
||||
height={400}
|
||||
/> */}
|
||||
|
||||
{!data || !data.latitude || !data.longitude ? (
|
||||
<CustomSkeleton height={200} />
|
||||
) : (
|
||||
<MapSelectedV2
|
||||
selectedLocation={[data.longitude, data.latitude]}
|
||||
onLocationSelect={(location: [number, number]) => {
|
||||
setData({
|
||||
...data,
|
||||
longitude: location[0],
|
||||
latitude: location[1],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<TextInputCustom
|
||||
required
|
||||
@@ -230,16 +226,3 @@ export function Maps_ScreenMapsEdit() {
|
||||
</ViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: "100%",
|
||||
backgroundColor: "#f5f5f5",
|
||||
overflow: "hidden",
|
||||
borderRadius: 8,
|
||||
marginBottom: 20,
|
||||
},
|
||||
map: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user