'use client' import LoadingComponent from '@/components/LoadingComponent'; import axiosInstance from '@/lib/axios'; import { Button, Col, message, Radio, Row } from 'antd'; import TextArea from 'antd/es/input/TextArea'; import { useSession } from 'next-auth/react'; import dynamic from 'next/dynamic'; import { useEffect, useState } from 'react'; const LiveLocationMap = dynamic(() => import('@/components/LiveLocationMap'), { ssr: false }); const calculateDistance = (lat1, lon1, lat2, lon2) => { const R = 6371; // Radius bumi dalam km const dLat = (lat2 - lat1) * (Math.PI / 180); const dLon = (lon2 - lon1) * (Math.PI / 180); const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); const distance = R * c * 1000; // hasil dalam meter return distance; }; export default function CheckIn() { const [messageApi, contextHolder] = message.useMessage(); const {data : session} = useSession(); const [dataMasterLocation, setDataMasterLocation] = useState([]); const [loadingMasterLocation, setLoadingMasterLocation] = useState(true); const [userLat, setUserLat] = useState(null); const [userLng, setUserLng] = useState(null); const [radius, setRadius] = useState(null); const [centerLat, setCenterLat] = useState(null); const [centerLng, setCenterLng] = useState(null); const [geoError, setGeoError] = useState(false); const [dataAbsen,setDataAbsen] = useState({ id_user : '', latitude_longitude : '', presence_type : 'masuk', presence_condition : '', add_information_type : '', add_information_condition : '', location_validation_status : '', }) useEffect(() => { if (session?.accessToken) { getMasterLocation(session.accessToken); } }, [session]); // useEffect(() => { // let watchId; // if (typeof window !== "undefined" && navigator.geolocation) { // watchId = navigator.geolocation.watchPosition( // (position) => { // const lat = position.coords.latitude; // const lng = position.coords.longitude; // setUserLat(lat); // setUserLng(lng); // setDataAbsen((prev) => ({ // ...prev, // latitude_longitude: `${lat}, ${lng}`, // })); // }, // (error) => { // messageApi.error('Gagal ambil lokasi', error); // console.error('Gagal ambil lokasi:', error); // }, // { enableHighAccuracy: true, maximumAge: 0, timeout: 15000 } // ); // } // return () => { // if (watchId) navigator.geolocation.clearWatch(watchId); // }; // }, []); const getUserLocation = () => { if (typeof window === 'undefined' || !navigator.geolocation) { messageApi.error("Browser tidak mendukung Geolocation."); return; } const watchId = navigator.geolocation.watchPosition( (position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; setUserLat(lat); setUserLng(lng); setGeoError(false); setDataAbsen((prev) => ({ ...prev, latitude_longitude: `${lat}, ${lng}`, })); }, (error) => { setGeoError(true); switch (error.code) { case 1: messageApi.error("Akses lokasi ditolak oleh pengguna."); break; case 2: messageApi.error("Lokasi tidak tersedia."); break; case 3: messageApi.error("Gagal ambil lokasi: Waktu habis (timeout)."); break; default: messageApi.error("Terjadi kesalahan saat mengambil lokasi."); } console.error("Geolocation Error:", error); }, { enableHighAccuracy: true, timeout: 15000, maximumAge: 0, } ); return () => navigator.geolocation.clearWatch(watchId); }; useEffect(() => { const stopWatching = getUserLocation(); return () => { if (typeof stopWatching === 'function') stopWatching(); }; }, []); const getMasterLocation = async (token) => { setLoadingMasterLocation(true); try { const response = await axiosInstance.get('/user/mlp', { headers: { Authorization: `Bearer ${token}`, }, }); const fetchedData = response?.data?.data ?? []; setDataMasterLocation(fetchedData.data); } catch (error) { messageApi.error('Gagal mengambil data Location', error); console.error('Gagal mengambil data Master Location:', error); } setLoadingMasterLocation(false); }; const onChangeRadio = (e) => { if (e.target.value === 'Dinas Luar'){ setDataAbsen({ ...dataAbsen, presence_condition : e.target.value, office_name : e.target.value, office_id : '-', location_validation_status : 0, }) } else { let officeId; dataMasterLocation.map((location) => { if(location.name_location === e.target.value){ officeId = location.id; const [lat, lng] = location.latitude_longitude.split(', ').map(Number); setRadius(location.radius); setCenterLat(lat); setCenterLng(lng); setDataAbsen({ ...dataAbsen, presence_condition : 'WFO', office_name : e.target.value, office_id : officeId, location_validation_status : 1, }) } }) } } const onChangeCatatan = (e) => { setDataAbsen({ ...dataAbsen, add_information_condition: e.target.value }) } const handleSendData = () => { if (dataAbsen.presence_condition === "WFO") { if (!centerLat || !centerLng || !userLat || !userLng || !radius) { messageApi.error("Data lokasi belum lengkap."); return; } const distance = calculateDistance(centerLat, centerLng, userLat, userLng); console.log("Distance from center:", distance, "radius:", radius); const isInside = distance <= radius; setDataAbsen((prev) => ({ ...prev, location_validation_status: isInside ? 1 : 0, })); if (!isInside) { messageApi.warning("📍 Anda berada di luar radius lokasi kantor."); return; } } // Kirim data presensi console.log("Data dikirim:", dataAbsen); } return (
{contextHolder}
PRESENSI DATANG
{loadingMasterLocation ? : <>
LOKASI
onChangeRadio(e)} > {dataMasterLocation && dataMasterLocation.map((location) => { return ( {location.name_location} ) })} Dinas Luar {/* Jika Dinas Luar */} {dataAbsen.presence_condition === "Dinas Luar" &&
CATATAN