Make AddressComponent like choose address... it should fetches from localStorage not redux... however it shouldn't redirect anywhere if there is no addresses! also add remove option!
'use client'
import React, { useState, useEffect } from 'react';
import Image from 'next/image';
import { useRouter } from "next/navigation";
import {useAppDispatch, useAppSelector} from "@/lib/hook";
import {removeAddress, setAddresses} from "@/lib/features/addressesSlice";
import {CircleArrowLeft} from "lucide-react";
import {fetchWithAuth} from "@/lib/api";

const AddressItem = ({ address, onEdit, onDelete }) => {
    return (
        <div className="flex justify-between text-base font-medium items-center text-black p-3.5 mb-4 w-full bg-[rgba(246,243,241,0.5)] rounded-lg">
            <div className="space-y-1">
                <h2 className="font-bold text-xl">{address.full_name}</h2>
                <p className="">{`${address.governorate}, ${address.city}, ${address.address}`}</p>
                <p className="">{address.phone_number}</p>
            </div>
            <div className="flex flex-col items-baseline space-x-2">
                <button onClick={() => onEdit(address)}>
                    <Image src="/address/edit.svg" alt="Edit" width={28} height={28} />
                </button>
                <button onClick={() => onDelete(address.id)}>
                    <Image src="/address/delete.svg" alt="Delete" width={28} height={28} />
                </button>
            </div>
        </div>
    );
};

const ManageAddress = () => {
    const dispatch = useAppDispatch();
    const isAuthenticated = useAppSelector(state => state.auth.isAuthenticated);
    const addresses = useAppSelector(state => state.addresses);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);
    const router = useRouter();

    useEffect(() => {
        const fetchAddresses = async () => {
            try {
                if (isAuthenticated) {
                    const response = await fetch(`${process.env.NEXT_PUBLIC_API}/addresses`, {credentials: 'include'});
                    if (response.status === 401 || response.status === 403) {
                        router.push("/login");
                    }
                    if (!response.ok) {
                        throw new Error('Failed to fetch addresses');
                    }
                    const data = await response.json();
                    dispatch(setAddresses(data));
                }
            } catch (err) {
                console.error('Error fetching addresses:', err);
            }
        };
        fetchAddresses();
        setIsLoading(false)
    }, [dispatch, router, isAuthenticated]);

    const handleEdit = (address) => {
        router.push(`/profile/address/edit/${address.id}`);
    };

    const handleDelete = async (id) => {
        if (window.confirm('Are you sure you want to delete this address?')) {
            try {
                const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_API}/addresses/${id}`);
            } catch (err) {
                console.error('Error deleting address:', err);
            }
        }
    };

    return (
        <div>
            <header className="flex items-center mb-24">
                <CircleArrowLeft size={52} strokeWidth={0.7} onClick={router.back} className="p-2 relative z-20" />
                <h1 className="text-2xl ssm:text-3xl absolute right-0 left-0 z-10 text-center font-medium font-sans">Manage Address</h1>
            </header>

            {error && <p className="text-red-500 text-center mb-4">{error}</p>}

            <div className="w-full my-20 text-center">
                <button
                    className="py-4 px-14 flex items-center align-center rounded-lg m-auto font-serif text-center text-white bg-[#3B5345] text-xl"
                    onClick={() => router.push("/profile/address/add")}
                    disabled={addresses.length >= 5}
                >
                    <svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <g clipPath="url(#clip0_578_4240)">
                            <path d="M3.5 14C3.5 15.3789 3.77159 16.7443 4.29926 18.0182C4.82694 19.2921 5.60036 20.4496 6.57538 21.4246C7.55039 22.3996 8.70791 23.1731 9.98182 23.7007C11.2557 24.2284 12.6211 24.5 14 24.5C15.3789 24.5 16.7443 24.2284 18.0182 23.7007C19.2921 23.1731 20.4496 22.3996 21.4246 21.4246C22.3996 20.4496 23.1731 19.2921 23.7007 18.0182C24.2284 16.7443 24.5 15.3789 24.5 14C24.5 11.2152 23.3938 8.54451 21.4246 6.57538C19.4555 4.60625 16.7848 3.5 14 3.5C11.2152 3.5 8.54451 4.60625 6.57538 6.57538C4.60625 8.54451 3.5 11.2152 3.5 14Z" stroke="white" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
                            <path d="M10.5 14H17.5" stroke="white" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
                            <path d="M14 10.5V17.5" stroke="white" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
                        </g>
                        <defs>
                            <clipPath id="clip0_578_4240">
                                <rect width="28" height="28" fill="white"/>
                            </clipPath>
                        </defs>
                    </svg>
                    Add a new address
                </button>
                {addresses.length >= 5 && <p className="text-red-500 mt-2">Maximum limit of 5 addresses reached</p>}
            </div>

            {isLoading ? (
                <p className="text-center">Loading addresses...</p>
            ) : (
                <div className="space-y-4 font-serif">
                    {addresses.map((address) => (
                        <AddressItem
                            key={address.id}
                            address={address}
                            onEdit={handleEdit}
                            onDelete={handleDelete}
                        />
                    ))}
                </div>
            )}
        </div>
    );
};

export default ManageAddress;
AddAddress:
'use client';

import React, { useState, useCallback, useRef } from 'react';
import { HomeIcon, PlusCircleIcon, BriefcaseBusiness, CircleArrowLeft } from 'lucide-react';
import { useRouter, useSearchParams } from "next/navigation";
import { useNotification } from '@/components/NotificationContext'; // Assuming you have a notification system

export default function AddAddress() {
    const [addressType, setAddressType] = useState(''); // Optional: Can be empty string
    const [formData, setFormData] = useState({
        full_name: '',
        governorate: '',
        city: '',
        address: '',
        closest_point: '',
        phone_number: ''
    });
    const [errors, setErrors] = useState({});
    const [isLoading, setIsLoading] = useState(false);
    const router = useRouter();
    const searchParams = useSearchParams();
    const { addNotification } = useNotification(); // Using notification context
    const formRef = useRef(null);

    // Validate phone number with optional starting '0'
    const validatePhoneNumber = useCallback((number) => {
        const regex = /^0?7\d{9}$/; // Starts with '07' or '7' followed by 9 digits
        return regex.test(number);
    }, []);

    // Handle input change
    const handleInputChange = useCallback((e) => {
        const { name, value } = e.target;
        setFormData(prev => ({ ...prev, [name]: value }));
    }, []);

    // Define handleRedirect with useCallback
    const handleRedirect = useCallback(() => {
        const redirectPath = searchParams.get('redirect') ? "/cart/order" : '/profile/address';
        router.push(redirectPath);
    }, [router, searchParams]);

    // Handle form submission
    const handleSubmit = useCallback(async (e) => {
        e.preventDefault();
        setIsLoading(true);
        setErrors({});

        // Validate phone number
        if (!validatePhoneNumber(formData.phone_number)) {
            setErrors(prev => ({
                ...prev,
                phone_number: 'Please enter a correct phone number starting with 07xxxxxxxxx or 7xxxxxxxxx.'
            }));
            setIsLoading(false);
            return;
        }

        const newAddress = { ...formData };
        if (addressType) {
            newAddress.type = addressType;
        }

        try {
            // Retrieve existing addresses safely
            const storedAddresses = JSON.parse(localStorage.getItem('addresses') || '[]');
            const updatedAddresses = [...storedAddresses, newAddress];
            localStorage.setItem('addresses', JSON.stringify(updatedAddresses));
            localStorage.setItem('lastUsedAddress', JSON.stringify(newAddress));
            handleRedirect();
        } catch (error) {
            console.error('Failed to save the address:', error);
            setErrors(prev => ({
                ...prev,
                general: 'Failed to save the address. Please try again.'
            }));
            addNotification('error', 'Failed to save the address.');
        } finally {
            setIsLoading(false);
        }
    }, [formData, addressType, validatePhoneNumber, addNotification, handleRedirect]);

    return (
        <div className="bg-white max-w-2xl mx-auto px-4 py-8">
            {/* Header */}
            <header className="flex font-sans items-center justify-between mb-8">
                <CircleArrowLeft
                    size={52}
                    strokeWidth={1}
                    onClick={() => router.back()}
                    className="p-2 cursor-pointer text-gray-700 hover:text-gray-900"
                    aria-label="Go back"
                />
                <h1 className="text-3xl font-medium">Add Address</h1>
                {/* Placeholder for alignment */}
                <div className="w-8"></div>
            </header>

            {/* Notification Placeholder */}
            {/* Ensure your NotificationContext displays notifications appropriately */}

            {/* Address Type Selection */}
            <div className="mb-6 font-serif">
                <div className="font-medium font-sans flex space-x-2 mb-4">
                    {['home', 'work', 'other'].map((type) => (
                        <button
                            key={type}
                            className={`flex flex-1 items-center justify-center py-3 border rounded-md transition-colors duration-200 ${
                                addressType === type
                                    ? 'bg-[#3B5345] text-white'
                                    : 'bg-white text-gray-800 hover:bg-gray-100'
                            }`}
                            onClick={() => setAddressType(type)}
                            type="button"
                            aria-pressed={addressType === type}
                        >
                            {type === 'home' && <HomeIcon className="mr-2 h-4 w-4" />}
                            {type === 'work' && <BriefcaseBusiness className="mr-2 h-4 w-4" />}
                            {type === 'other' && <PlusCircleIcon className="mr-2 h-4 w-4" />}
                            {type.charAt(0).toUpperCase() + type.slice(1)}
                        </button>
                    ))}
                </div>
                {errors.addressType && <p className="text-red-500 text-sm">{errors.addressType}</p>}
            </div>

            {/* Address Form */}
            <form onSubmit={handleSubmit} className="space-y-4 font-medium font-serif" ref={formRef}>
                {/* Full Name */}
                <div>
                    <label htmlFor="full_name" className="block text-sm font-medium text-gray-700">
                        Full Name
                    </label>
                    <input
                        id="full_name"
                        className={`mt-1 w-full p-3 border rounded-md focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.full_name ? 'border-red-500' : 'border-gray-300'
                        }`}
                        placeholder="Full Name"
                        name="full_name"
                        value={formData.full_name}
                        onChange={handleInputChange}
                        required
                        aria-invalid={errors.full_name ? 'true' : 'false'}
                        aria-describedby={errors.full_name ? 'full_name-error' : undefined}
                    />
                    {errors.full_name && (
                        <p className="text-red-500 text-sm mt-1" id="full_name-error">
                            {errors.full_name}
                        </p>
                    )}
                </div>

                {/* Governorate */}
                <div>
                    <label htmlFor="governorate" className="block text-sm font-medium text-gray-700">
                        Governorate
                    </label>
                    <select
                        id="governorate"
                        className={`mt-1 w-full p-3 border rounded-md bg-white focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.governorate ? 'border-red-500' : 'border-gray-300'
                        }`}
                        name="governorate"
                        value={formData.governorate}
                        onChange={handleInputChange}
                        required
                        aria-invalid={errors.governorate ? 'true' : 'false'}
                        aria-describedby={errors.governorate ? 'governorate-error' : undefined}
                    >
                        <option value="" disabled hidden>Governorate</option>
                        {/* Add all governorate options here */}
                        <option value="al-anbar">Al-Anbar</option>
                        <option value="babil">Babil</option>
                        <option value="baghdad">Baghdad</option>
                        <option value="basra">Basra</option>
                        <option value="dhi_qar">Dhi Qar</option>
                        <option value="diyala">Diyala</option>
                        <option value="dohuk">Dohuk</option>
                        <option value="erbil">Erbil</option>
                        <option value="karbala">Karbala</option>
                        <option value="kirkuk">Kirkuk</option>
                        <option value="maysan">Maysan</option>
                        <option value="muthanna">Muthanna</option>
                        <option value="najaf">Najaf</option>
                        <option value="nineveh">Nineveh</option>
                        <option value="al-qadisiyyah">Al-Qadisiyyah</option>
                        <option value="saladin">Saladin</option>
                        <option value="sulaymaniyah">Sulaymaniyah</option>
                        <option value="wasit">Wasit</option>
                    </select>
                    {errors.governorate && (
                        <p className="text-red-500 text-sm mt-1" id="governorate-error">
                            {errors.governorate}
                        </p>
                    )}
                </div>

                {/* City */}
                <div>
                    <label htmlFor="city" className="block text-sm font-medium text-gray-700">
                        City
                    </label>
                    <input
                        id="city"
                        className={`mt-1 w-full p-3 border rounded-md focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.city ? 'border-red-500' : 'border-gray-300'
                        }`}
                        placeholder="City"
                        name="city"
                        value={formData.city}
                        onChange={handleInputChange}
                        required
                        aria-invalid={errors.city ? 'true' : 'false'}
                        aria-describedby={errors.city ? 'city-error' : undefined}
                    />
                    {errors.city && (
                        <p className="text-red-500 text-sm mt-1" id="city-error">
                            {errors.city}
                        </p>
                    )}
                </div>

                {/* Address */}
                <div>
                    <label htmlFor="address" className="block text-sm font-medium text-gray-700">
                        Address
                    </label>
                    <input
                        id="address"
                        className={`mt-1 w-full p-3 border rounded-md focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.address ? 'border-red-500' : 'border-gray-300'
                        }`}
                        placeholder="Address"
                        name="address"
                        value={formData.address}
                        onChange={handleInputChange}
                        required
                        aria-invalid={errors.address ? 'true' : 'false'}
                        aria-describedby={errors.address ? 'address-error' : undefined}
                    />
                    {errors.address && (
                        <p className="text-red-500 text-sm mt-1" id="address-error">
                            {errors.address}
                        </p>
                    )}
                </div>

                {/* Closest Point */}
                <div>
                    <label htmlFor="closest_point" className="block text-sm font-medium text-gray-700">
                        The Closest Point of Function
                    </label>
                    <input
                        id="closest_point"
                        className={`mt-1 w-full p-3 border rounded-md focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.closest_point ? 'border-red-500' : 'border-gray-300'
                        }`}
                        placeholder="The closest point of a function"
                        name="closest_point"
                        value={formData.closest_point}
                        onChange={handleInputChange}
                        aria-invalid={errors.closest_point ? 'true' : 'false'}
                        aria-describedby={errors.closest_point ? 'closest_point-error' : undefined}
                    />
                    {errors.closest_point && (
                        <p className="text-red-500 text-sm mt-1" id="closest_point-error">
                            {errors.closest_point}
                        </p>
                    )}
                </div>

                {/* Phone Number */}
                <div>
                    <label htmlFor="phone_number" className="block text-sm font-medium text-gray-700">
                        Phone Number
                    </label>
                    <input
                        id="phone_number"
                        className={`mt-1 w-full p-3 border rounded-md focus:outline-none focus:ring-2 focus:ring-[#3B5345] ${
                            errors.phone_number ? 'border-red-500' : 'border-gray-300'
                        }`}
                        placeholder="Phone Number"
                        name="phone_number"
                        value={formData.phone_number}
                        onChange={handleInputChange}
                        required
                        type={"tel"}
                        maxLength={11}
                        pattern="^0?7\d{9}$"
                        title="07xxxxxxxxx or 7xxxxxxxxx."
                        aria-invalid={errors.phone_number ? 'true' : 'false'}
                        aria-describedby={errors.phone_number ? 'phone_number-error' : undefined}
                    />
                    {errors.phone_number && (
                        <p className="text-red-500 text-sm mt-1" id="phone_number-error">
                            {errors.phone_number}
                        </p>
                    )}
                </div>

                {/* General Errors */}
                {errors.general && (
                    <div className="text-red-500 text-sm">
                        {errors.general}
                    </div>
                )}

                {/* Submit Button */}
                <button
                    type="submit"
                    className={`w-full p-3 bg-[#3B5345] text-white rounded-md hover:bg-[#2a4031] transition-colors duration-200 disabled:bg-gray-400`}
                    disabled={isLoading}
                    aria-label="Save Address"
                >
                    {isLoading ? 'Saving...' : 'Save'}
                </button>
            </form>
        </div>
    );
}
chooseAddress:
'use client'
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useRouter } from 'next/navigation';
import Link from "next/link";
import { CircleArrowLeft, Home, Building2, PlusCircle, MapPin, Phone, Trash2 } from "lucide-react";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
import {Button} from "@/components/ui/button";

const ChooseAddress = () => {
    const router = useRouter();
    const [addresses, setAddresses] = useState([]);
    const [order, setOrder] = useState({});
    const [error, setError] = useState('');
    const [isSelecting, setIsSelecting] = useState(false);

    useEffect(() => {
        try {
            const storedAddresses = JSON.parse(localStorage.getItem('addresses') || '[]');
            const storedOrder = JSON.parse(localStorage.getItem('orderData') || '{}');
            setAddresses(storedAddresses);
            setOrder(storedOrder);
            if (storedAddresses.length === 0) {
                router.push("/profile/address/add?redirect=cart/order")
            }
        } catch (err) {
            console.error('Failed to load from localStorage:', err);
            setError('Failed to load addresses. Please try again.');
        }
    }, [router]);

    const handleAddressSelect = useCallback((address) => {
        setIsSelecting(true);
        try {
            const updatedOrder = { ...order, shippingAddress: address };
            setOrder(updatedOrder);
            localStorage.setItem('orderData', JSON.stringify(updatedOrder));
            localStorage.setItem('lastUsedAddress', JSON.stringify(address));
            router.push('/cart/order');
        } catch (err) {
            console.error('Failed to save order data:', err);
            setError('Failed to select address. Please try again.');
        } finally {
            setIsSelecting(false);
        }
    }, [order, router]);

    const handleDeleteAddress = useCallback((index) => {
        const updatedAddresses = addresses.filter((_, i) => i !== index);
        setAddresses(updatedAddresses);
        localStorage.setItem('addresses', JSON.stringify(updatedAddresses));
        if (updatedAddresses.length === 0) {
            router.push("/profile/address/add?redirect=cart/order");
        }
    }, [addresses, router]);

    const getAddressIcon = (type) => {
        switch (type) {
            case 'home':
                return <Home size={24} />;
            case 'work':
                return <Building2 size={24} />;
            default:
                return <PlusCircle size={24} />;
        }
    };

    const renderedAddresses = useMemo(() => {
        if (addresses.length === 0) {
            return;
        }

        return addresses.map((address, index) => (
            <div
                key={index}
                className="mb-4 p-4 bg-[#F6F3F1]/30 shadow-[0px_2px_4px_3px_rgba(0,0,0,0.1)] rounded-xl cursor-pointer hover:bg-gray-50"
                role="button"
                tabIndex={0}
                aria-label={`Select ${address.type ? address.type.charAt(0).toUpperCase() + address.type.slice(1) : 'Other'} address`}
            >
                <div className="flex items-center mb-2 justify-between">
                    <div className="flex items-center" onClick={() => handleAddressSelect(address)}>
                        {getAddressIcon(address.type)}
                        <h2 className="text-xl font-medium ml-2 capitalize">
                            {address.type
                                ? (address.type === 'home' ? 'Home' :
                                    address.type === 'work' ? 'Work' : 'Other')
                                : 'Other'}
                        </h2>
                    </div>
                    <AlertDialog>
                        <AlertDialogTrigger asChild>
                            <button className="text-red-500 hover:text-red-700" aria-label="Delete address">
                                <Trash2 size={20} />
                            </button>
                        </AlertDialogTrigger>
                        <AlertDialogContent className="w-[90%] max-w-[364px] p-6 rounded-md shadow-lg">
                            <div className="flex flex-col items-center">
                                <div className="w-full  mb-6">
                                    <video autoPlay loop muted playsInline className="w-full max-h-[20vh]">
                                        <source src="/waiting.mp4" type="video/mp4" />
                                        Your browser does not support the video tag.
                                    </video>
                                </div>
                                <AlertDialogHeader className="font-serif text-center">
                                    <AlertDialogTitle className="text-2xl font-serif font-medium mb-2">Delete Address</AlertDialogTitle>
                                    <p className="text-gray-500 font-serif mb-6">
                                        Are you sure you want to delete this address?
                                    </p>
                                </AlertDialogHeader>
                                <AlertDialogFooter className="w-full max-w-52 pt-4 font-serif flex flex-col">
                                    <AlertDialogAction
                                        className="w-full bg-[#44594A] py-6 text-white hover:bg-[#3a4d40] transition-colors duration-200"
                                        onClick={() => handleDeleteAddress(index)}
                                    >
                                        Delete
                                    </AlertDialogAction>
                                    <AlertDialogCancel
                                        className="w-full bg-gray-200 py-6 text-gray-700 hover:bg-gray-300 transition-colors duration-200"
                                        variant="secondary"
                                    >
                                        Cancel
                                    </AlertDialogCancel>
                                </AlertDialogFooter>
                            </div>
                        </AlertDialogContent>
                    </AlertDialog>
                </div>
                <div className="w-full mb-4 mt-4 h-[1px] bg-[#695C5C]/30"></div>
                <div className="flex items-center text-gray-800 mb-1" onClick={() => handleAddressSelect(address)}>
                    <MapPin size={18} className="mr-2"/>
                    <p className="capitalize">{address.governorate},&nbsp;</p>
                    <p>{`${address.city}, ${address.address}`}</p>
                </div>
                <div className="flex items-center text-gray-800" onClick={() => handleAddressSelect(address)}>
                    <Phone size={18} className="mr-2"/>
                    <p>{address.phone_number}</p>
                </div>
            </div>
        ));
    }, [addresses, handleAddressSelect, handleDeleteAddress]);

    return (
        <div className="container mx-auto max-w-md font-sans">
            <header className="flex items-center mb-12">
                <CircleArrowLeft
                    size={52}
                    strokeWidth={0.7}
                    onClick={() => router.push("/cart/order")}
                    className="p-2 relative z-20 cursor-pointer"
                    aria-label="Go back"
                />
                <h1 className="text-2xl ssm:text-3xl absolute right-0 left-0 z-10 text-center font-medium">
                    Choose Address
                </h1>
            </header>

            {error && <p className="text-red-500 text-center mb-4">{error}</p>}
            {isSelecting && <p className="text-center text-gray-500">Selecting address...</p>}
            {!isSelecting && renderedAddresses}

            <Link
                className="w-full flex items-center justify-center bg-[#3B5345] text-white py-3 px-4 rounded-lg gap-1.5 font-medium text-lg mt-4 text-center"
                href={{
                    pathname: "/profile/address/add",
                    query: { redirect: "/cart/order" }
                }}
                aria-label="Add a new address"
            >
                <PlusCircle size={24} />
                Add a new address
            </Link>
        </div>
    );
};

export default React.memo(ChooseAddress);