'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'; import { getLocationAddress } from '@/utils/locationUtils'; import { ReloadOutlined } from '@ant-design/icons'; const DynamicMap = dynamic(() => import('@/components/RealTimeMapComponent'), { ssr: false, }); 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 [selectedLocation, setSelectedLocation] = useState(null); const [radiusTarget, setRadiusTarget] = useState(0); const [userLocationName, setUserLocationName] = useState(''); const [refreshingLocation, setRefreshingLocation] = useState(false); const [loadingLocation, setLoadingLocation] = useState(false); const [loadingSendData, setLoadingSendData] = useState(false); const [dataAbsen, setDataAbsen] = useState({ latitude_longitude: '', presence_type: 'masuk', presence_condition: '-', add_information_type: '-', add_information_condition: '', location_validation_status: '', office_id : '-', office_name : '-', location_name: '-', }); const refreshLocation = async () => { setLoadingLocation(true); if (!navigator.geolocation) { messageApi.error('Geolocation tidak didukung oleh browser Anda.'); return; } setRefreshingLocation(true); try { const position = await new Promise((resolve, reject) => { navigator.geolocation.getCurrentPosition(resolve, reject, { enableHighAccuracy: true, maximumAge: 0, timeout: 10000, }); }); const lat = position.coords.latitude; const lng = position.coords.longitude; setUserLat(lat); setUserLng(lng); const address = await getLocationAddress(lat, lng); setUserLocationName(address); setDataAbsen((prev) => ({ ...prev, latitude_longitude: `${lat}, ${lng}`, location_name: address || '', })); } catch (error) { console.error('Gagal ambil lokasi:', error); messageApi.error('Gagal ambil lokasi: ' + error.message); } finally { setRefreshingLocation(false); setLoadingLocation(false); } }; useEffect(() => { if (session?.accessToken) { getMasterLocation(session.accessToken); } }, [session]); useEffect(() => { let watchId; if (typeof window !== 'undefined' && navigator.geolocation) { watchId = navigator.geolocation.watchPosition( async (position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; setUserLat(lat); setUserLng(lng); const address = await getLocationAddress(lat, lng); setDataAbsen((prev) => ({ ...prev, latitude_longitude: `${lat}, ${lng}`, location_name: address || '', })); setUserLocationName(address); }, (error) => { messageApi.error('Gagal ambil lokasi: ' + error.message); }, { enableHighAccuracy: true, maximumAge: 0, timeout: 5000 } ); } return () => { if (watchId) navigator.geolocation.clearWatch(watchId); }; }, []); 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'); } setLoadingMasterLocation(false); }; const onChangeRadio = (e) => { const selected = dataMasterLocation.find((loc) => loc.name_location === e.target.value); if (e.target.value === 'Dinas Luar') { setDataAbsen({ ...dataAbsen, presence_condition: e.target.value, office_name: e.target.value, office_id: '-', location_validation_status: 0, }); setSelectedLocation(null); setRadiusTarget(0); } else if (selected) { setSelectedLocation(selected); setRadiusTarget(selected.radius); setDataAbsen({ ...dataAbsen, presence_condition: 'WFO', office_name: selected.name_location, office_id: selected.id, location_validation_status: 1, add_information_condition: '' }); } }; const onChangeCatatan = (e) => { setDataAbsen({ ...dataAbsen, add_information_condition: e.target.value, }); }; const handleSendData = () => { setLoadingSendData(true); if (!userLat || !userLng ) { messageApi.warning('Lokasi pengguna tidak tersedia'); return; } if(dataAbsen.office_name !== 'Dinas Luar') { const [targetLat, targetLng] = selectedLocation.latitude_longitude.split(', ').map(Number); const R = 6371; const dLat = (targetLat - userLat) * (Math.PI / 180); const dLon = (targetLng - userLng) * (Math.PI / 180); const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(userLat * (Math.PI / 180)) * Math.cos(targetLat * (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; const inRadius = distance <= radiusTarget; setDataAbsen((prev) => ({ ...prev, location_validation_status: inRadius ? 1 : 0, })); if (inRadius) { messageApi.success('Anda berada di dalam radius. Data siap dikirim.'); localStorage.setItem('pendingAbsensi', JSON.stringify(dataAbsen)); window.location.href = '/foto'; } else { messageApi.warning('Anda berada di luar radius kantor !'); } } else { messageApi.success('Anda berada di Luar Kantor. Data siap dikirim.'); console.log('dataSend', dataAbsen); localStorage.setItem('pendingAbsensi', JSON.stringify(dataAbsen)); window.location.href = '/foto'; } }; const isCanCheckin = (dataAbsen.presence_condition === 'Dinas Luar' && dataAbsen.add_information_condition.length >= 10) || (dataAbsen.presence_condition === 'WFO'); return (