Files
parsshop/components/context/Addresscontext.tsx
2026-04-29 12:44:33 +03:30

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>;
};