283 lines
8.4 KiB
JavaScript
283 lines
8.4 KiB
JavaScript
'use client';
|
|
|
|
import { Map, Placemark, YMaps } from '@pbe/react-yandex-maps';
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
import { useEffect, useState } from 'react';
|
|
import axiosInstance from '../../api/axiosInstance';
|
|
|
|
// Reverse geocoding (OSM orqali)
|
|
async function getAddress(lat, lon) {
|
|
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json`);
|
|
const data = await response.json();
|
|
const address = data.address || {};
|
|
|
|
return {
|
|
fullAddress: data.display_name || '',
|
|
country: address.country || '',
|
|
region: address.state || '',
|
|
city: address.city || address.town || address.village || '',
|
|
street: address.road || '',
|
|
house: address.house_number || '',
|
|
postalCode: address.postcode || '',
|
|
};
|
|
}
|
|
|
|
const CreateBranches = ({ branches, setAlert, setBranches }) => {
|
|
const queryClient = useQueryClient();
|
|
const [formData, setFormData] = useState({
|
|
id: '',
|
|
title: '',
|
|
titleRu: '',
|
|
address: '',
|
|
addressRu: '',
|
|
workingHours: '',
|
|
workingHoursRu: '',
|
|
phone: '',
|
|
telegramAdmin: '',
|
|
telegramChannel: '',
|
|
code: '',
|
|
active: true,
|
|
});
|
|
|
|
const [coords, setCoords] = useState({
|
|
latitude: 41.311081, // Toshkent
|
|
longitude: 69.240562,
|
|
});
|
|
|
|
const [locationDetails, setLocationDetails] = useState({
|
|
fullAddress: '',
|
|
country: '',
|
|
region: '',
|
|
city: '',
|
|
street: '',
|
|
house: '',
|
|
postalCode: '',
|
|
});
|
|
|
|
const resetForm = () => {
|
|
setFormData({
|
|
id: '',
|
|
title: '',
|
|
titleRu: '',
|
|
address: '',
|
|
addressRu: '',
|
|
workingHours: '',
|
|
workingHoursRu: '',
|
|
phone: '',
|
|
telegramAdmin: '',
|
|
telegramChannel: '',
|
|
code: '',
|
|
active: true,
|
|
});
|
|
setCoords({
|
|
latitude: 41.311081,
|
|
longitude: 69.240562,
|
|
});
|
|
setLocationDetails({
|
|
fullAddress: '',
|
|
country: '',
|
|
region: '',
|
|
city: '',
|
|
street: '',
|
|
house: '',
|
|
postalCode: '',
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (locationDetails.fullAddress) {
|
|
setFormData((prev) => ({
|
|
...prev,
|
|
address: locationDetails.fullAddress,
|
|
addressRu: locationDetails.fullAddress,
|
|
}));
|
|
}
|
|
}, [locationDetails]);
|
|
|
|
const { data: branchData, refetch } = useQuery({
|
|
queryKey: ['one_branch', branches],
|
|
queryFn: () => axiosInstance.get(`/branches/${branches}`).then((res) => res.data),
|
|
enabled: !!branches,
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (branches) {
|
|
refetch();
|
|
}
|
|
}, [branches, refetch]);
|
|
|
|
useEffect(() => {
|
|
if (branchData) {
|
|
setFormData({
|
|
id: branchData.id || '',
|
|
title: branchData.title || '',
|
|
titleRu: branchData.titleRu || '',
|
|
address: branchData.address || '',
|
|
addressRu: branchData.addressRu || '',
|
|
workingHours: branchData.workingHours || '',
|
|
workingHoursRu: branchData.workingHoursRu || '',
|
|
phone: branchData.phone || '',
|
|
telegramAdmin: branchData.telegramAdmin || '',
|
|
telegramChannel: branchData.telegramChannel || '',
|
|
code: branchData.code || '',
|
|
active: branchData.active ?? true,
|
|
});
|
|
setCoords({
|
|
latitude: branchData.latitude || 41.311081,
|
|
longitude: branchData.longitude || 69.240562,
|
|
});
|
|
}
|
|
}, [branchData]);
|
|
|
|
const { mutate: createBranch } = useMutation({
|
|
mutationFn: (body) => axiosInstance.post('/branches', body),
|
|
onSuccess: () => {
|
|
setAlert({ type: 'success', message: "Filial muvaffaqiyatli qo'shildi." });
|
|
queryClient.invalidateQueries({ queryKey: ['branch_list'] });
|
|
resetForm();
|
|
},
|
|
onError: () => {
|
|
setAlert({
|
|
type: 'warning',
|
|
message: "Filial qo'shilmadi, xatolik yuz berdi.",
|
|
});
|
|
},
|
|
});
|
|
|
|
const { mutate: editBranch } = useMutation({
|
|
mutationFn: (body) => axiosInstance.put(`/branches/${body.id}`, body),
|
|
onSuccess: () => {
|
|
setBranches(null);
|
|
setAlert({
|
|
type: 'success',
|
|
message: 'Filial muvaffaqiyatli yangilandi.',
|
|
});
|
|
queryClient.invalidateQueries({ queryKey: ['branch_list'] });
|
|
resetForm();
|
|
},
|
|
onError: () => {
|
|
setAlert({
|
|
type: 'warning',
|
|
message: 'Filial yangilanmadi, xatolik yuz berdi.',
|
|
});
|
|
},
|
|
});
|
|
|
|
const addBranch = () => {
|
|
const { id, ...dataWithoutId } = formData;
|
|
createBranch({
|
|
...dataWithoutId,
|
|
latitude: Number(coords.latitude) || 0,
|
|
longitude: Number(coords.longitude) || 0,
|
|
});
|
|
};
|
|
|
|
const updateBranch = (id) => {
|
|
editBranch({
|
|
...formData,
|
|
id,
|
|
latitude: Number(coords.latitude) || 0,
|
|
longitude: Number(coords.longitude) || 0,
|
|
});
|
|
};
|
|
|
|
const handleMapClick = async (e) => {
|
|
const lat = e.get('coords')[0];
|
|
const lon = e.get('coords')[1];
|
|
setCoords({ latitude: lat, longitude: lon });
|
|
const details = await getAddress(lat, lon);
|
|
setLocationDetails(details);
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col bg-white shadow rounded-lg p-6 mb-6">
|
|
<div className="h-96 mb-10">
|
|
<YMaps query={{ lang: 'en_RU' }}>
|
|
<Map
|
|
defaultState={{
|
|
center: [coords.latitude, coords.longitude],
|
|
zoom: 13,
|
|
}}
|
|
width="100%"
|
|
height="400px"
|
|
onClick={handleMapClick}
|
|
>
|
|
<Placemark geometry={[coords.latitude, coords.longitude]} />
|
|
</Map>
|
|
</YMaps>
|
|
</div>
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
{Object.keys(formData)
|
|
.filter((key) => key !== 'id')
|
|
.map((key) => (
|
|
<div key={key} className="flex flex-col">
|
|
<label className="mb-1 font-semibold text-slate-700">
|
|
{key === 'title'
|
|
? 'Filial nomi'
|
|
: key === 'titleRu'
|
|
? 'Filial nomi (RU)'
|
|
: key === 'address'
|
|
? 'Manzil'
|
|
: key === 'addressRu'
|
|
? 'Manzil (RU)'
|
|
: key === 'workingHours'
|
|
? 'Ish vaqti'
|
|
: key === 'workingHoursRu'
|
|
? 'Ish vaqti (RU)'
|
|
: key === 'phone'
|
|
? 'Telefon'
|
|
: key === 'telegramAdmin'
|
|
? 'Telegram Admin'
|
|
: key === 'telegramChannel'
|
|
? 'Telegram Kanal'
|
|
: key === 'code'
|
|
? 'Kod'
|
|
: key === 'active'
|
|
? 'Faol'
|
|
: key}
|
|
</label>
|
|
{key === 'active' ? (
|
|
<div className="flex items-center gap-3">
|
|
<button type="button" onClick={() => setFormData({ ...formData, active: !formData.active })} className={`w-14 h-8 flex items-center rounded-full p-1 transition-colors duration-300 ${formData.active ? 'bg-[#3489e3]' : 'bg-gray-300'}`}>
|
|
<div className={`w-6 h-6 bg-white rounded-full shadow-md transform transition-transform duration-300 ${formData.active ? 'translate-x-6' : 'translate-x-0'}`}></div>
|
|
</button>
|
|
<span>{formData.active ? 'Faol' : 'Faol emas'}</span>
|
|
</div>
|
|
) : (
|
|
<input
|
|
type="text"
|
|
className="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#3489e3]"
|
|
value={formData[key]}
|
|
onChange={(e) =>
|
|
setFormData({
|
|
...formData,
|
|
[key]: e.target.value,
|
|
})
|
|
}
|
|
/>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="flex flex-wrap gap-3 mb-8 mt-6">
|
|
{!branches && (
|
|
<button onClick={addBranch} className="bg-[#3489e3] hover:bg-blue-500 text-white px-5 py-2 rounded-lg shadow">
|
|
Yaratish
|
|
</button>
|
|
)}
|
|
{branches && (
|
|
<button onClick={() => updateBranch(formData.id)} disabled={!formData.id} className={`px-5 py-2 rounded-lg shadow text-white ${!formData.id ? 'bg-gray-400 cursor-not-allowed' : 'bg-[#3489e3] hover:bg-blue-500'}`}>
|
|
Yangilash
|
|
</button>
|
|
)}
|
|
<button onClick={resetForm} className="bg-gray-400 hover:bg-gray-500 text-white px-5 py-2 rounded-lg shadow">
|
|
Tozalash
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CreateBranches;
|