156 lines
6.3 KiB
TypeScript
156 lines
6.3 KiB
TypeScript
'use client';
|
|
|
|
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
|
import { fetchUserAddresses, addAddressApi, updateAddressApi, deleteAddressApi, type Address, type NewAddressData } from "@/public/src/services/address/api";
|
|
|
|
interface AddressContextType {
|
|
addresses: Address[];
|
|
selectedAddressId: string | null;
|
|
setSelectedAddressId: (id: string | null) => void;
|
|
isAddressLoading: boolean;
|
|
showNewAddressForm: boolean;
|
|
setShowNewAddressForm: (show: boolean) => void;
|
|
editingAddressId: string | null;
|
|
newAddress: NewAddressData;
|
|
handleAddressInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => void;
|
|
handleAddNewAddress: (e: React.FormEvent) => Promise<void>;
|
|
handleEditClick: (address: Address, e: any) => void;
|
|
handleUpdateAddress: () => Promise<void>;
|
|
handleCancelForm: () => void;
|
|
handleDeleteAddress: (addressId: string, e: React.MouseEvent) => Promise<void>;
|
|
fetchAddresses: () => Promise<void>;
|
|
}
|
|
|
|
export const AddressContext = createContext<AddressContextType | undefined>(undefined);
|
|
|
|
export const useAddressContext = () => {
|
|
const context = useContext(AddressContext);
|
|
if (!context) {
|
|
throw new Error("useAddressContext must be used within an AddressProvider");
|
|
}
|
|
return context;
|
|
};
|
|
|
|
export const AddressProvider = ({ children }: { children: ReactNode }) => {
|
|
const [addresses, setAddresses] = useState<Address[]>([]);
|
|
const [selectedAddressId, setSelectedAddressId] = useState<string | null>(null);
|
|
const [isAddressLoading, setIsAddressLoading] = useState(true);
|
|
const [showNewAddressForm, setShowNewAddressForm] = useState(false);
|
|
const [editingAddressId, setEditingAddressId] = useState<string | null>(null);
|
|
|
|
const initialAddressState: NewAddressData = {
|
|
title: 'خانه', recipientName: '', phone: '', province: '', city: '',
|
|
postalCode: '', addressLine: '', plaque: '', unit: '', isDefault: false
|
|
};
|
|
const [newAddress, setNewAddress] = useState<NewAddressData>(initialAddressState);
|
|
|
|
const fetchAddresses = async () => {
|
|
setIsAddressLoading(true);
|
|
try {
|
|
const token = localStorage.getItem('accessToken') || localStorage.getItem('refreshToken');
|
|
if (!token) {
|
|
setIsAddressLoading(false);
|
|
return;
|
|
}
|
|
const addressData = await fetchUserAddresses();
|
|
if (addressData && addressData.length > 0) {
|
|
setAddresses(addressData);
|
|
const defaultAddress = addressData.find(addr => addr.isDefault) || addressData[0];
|
|
setSelectedAddressId(defaultAddress.id);
|
|
} else {
|
|
setShowNewAddressForm(true);
|
|
}
|
|
} catch (error) {
|
|
console.error("خطا در دریافت آدرسها:", error);
|
|
} finally {
|
|
setIsAddressLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchAddresses();
|
|
}, []);
|
|
|
|
const handleAddressInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
|
|
const { name, value } = e.target;
|
|
setNewAddress(prev => ({ ...prev, [name]: value }));
|
|
};
|
|
|
|
const handleAddNewAddress = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
try {
|
|
const addedAddress = await addAddressApi(newAddress);
|
|
setAddresses(prev => [...prev, addedAddress]);
|
|
setSelectedAddressId(addedAddress.id);
|
|
setShowNewAddressForm(false);
|
|
setNewAddress(initialAddressState);
|
|
} catch (error) {
|
|
console.error("خطا در ذخیره آدرس:", error);
|
|
}
|
|
};
|
|
|
|
const handleEditClick = (address: any, e: any) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setEditingAddressId(address.id);
|
|
setNewAddress({
|
|
title: address.title || "", recipientName: address.recipientName || "", phone: address.phone || "",
|
|
province: address.province || "", city: address.city || "", postalCode: address.postalCode || "",
|
|
addressLine: address.addressLine || "", plaque: address.plaque || "", unit: address.unit || "",
|
|
isDefault: address.isDefault || false
|
|
});
|
|
setShowNewAddressForm(true);
|
|
};
|
|
|
|
const handleUpdateAddress = async () => {
|
|
if (!editingAddressId) return;
|
|
try {
|
|
const response = await updateAddressApi(editingAddressId, newAddress);
|
|
if (response.success) {
|
|
setAddresses(prev => prev.map(addr => addr.id === editingAddressId ? response.data : addr));
|
|
setShowNewAddressForm(false);
|
|
setEditingAddressId(null);
|
|
setNewAddress(initialAddressState);
|
|
}
|
|
} catch (error) {
|
|
console.error("خطا در بهروزرسانی آدرس:", error);
|
|
}
|
|
};
|
|
|
|
const handleCancelForm = () => {
|
|
setShowNewAddressForm(false);
|
|
setEditingAddressId(null);
|
|
setNewAddress(initialAddressState);
|
|
};
|
|
|
|
const handleDeleteAddress = async (addressId: string, e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
const confirmDelete = window.confirm("آیا از حذف این آدرس اطمینان دارید؟");
|
|
if (!confirmDelete) return;
|
|
|
|
try {
|
|
const response = await deleteAddressApi(addressId);
|
|
if (response.success) {
|
|
setAddresses(prev => prev.filter(addr => addr.id !== addressId));
|
|
if (selectedAddressId === addressId) setSelectedAddressId(null);
|
|
if (editingAddressId === addressId) {
|
|
setShowNewAddressForm(false);
|
|
setEditingAddressId(null);
|
|
setNewAddress(initialAddressState);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error("خطا در حذف آدرس:", error);
|
|
}
|
|
};
|
|
|
|
const value = {
|
|
addresses, selectedAddressId, setSelectedAddressId, isAddressLoading,
|
|
showNewAddressForm, setShowNewAddressForm, editingAddressId, newAddress,
|
|
handleAddressInputChange, handleAddNewAddress, handleEditClick,
|
|
handleUpdateAddress, handleCancelForm, handleDeleteAddress, fetchAddresses
|
|
};
|
|
|
|
return <AddressContext.Provider value={value}>{children}</AddressContext.Provider>;
|
|
};
|