barsa f1c88b6017 Refactor PersonalInfoCard and useProfileData for improved user profile management
- Updated type definitions in PersonalInfoCard to use UserProfile instead of ProfileDisplayData, enhancing clarity.
- Simplified onChange function to restrict fields to "email" and "phonenumber".
- Modified UI to indicate that first and last names cannot be changed from the portal.
- Adjusted useProfileData hook to focus on email management, removing firstname and lastname from state and update logic, streamlining profile updates.
2025-12-15 17:29:48 +09:00

143 lines
4.2 KiB
TypeScript

"use client";
import { useEffect, useState, useCallback } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { queryKeys } from "@/lib/api";
import { useAuthStore } from "@/features/auth/services/auth.store";
import { accountService } from "@/features/account/services/account.service";
import { logger } from "@/lib/logger";
// Use centralized profile types
import type { ProfileEditFormData, Address } from "@customer-portal/domain/customer";
export function useProfileData() {
const { user } = useAuthStore();
const queryClient = useQueryClient();
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [isSavingProfile, setIsSavingProfile] = useState(false);
const [isSavingAddress, setIsSavingAddress] = useState(false);
const [billingInfo, setBillingInfo] = useState<{ address: Address } | null>(null);
const [formData, setFormData] = useState<ProfileEditFormData>({
email: user?.email || "",
phonenumber: user?.phonenumber || "",
});
const [addressData, setAddress] = useState<Address>({
address1: "",
address2: "",
city: "",
state: "",
postcode: "",
country: "",
countryCode: "",
phoneNumber: "",
phoneCountryCode: "",
});
const fetchBillingInfo = useCallback(async () => {
try {
setLoading(true);
const address = await accountService.getAddress().catch(() => null);
if (address) {
const normalizedAddress: Address = {
address1: address.address1 || "",
address2: address.address2 || "",
city: address.city || "",
state: address.state || "",
postcode: address.postcode || "",
country: address.country || "",
countryCode: address.countryCode || "",
phoneNumber: address.phoneNumber || "",
phoneCountryCode: address.phoneCountryCode || "",
};
setBillingInfo({ address: normalizedAddress });
setAddress(normalizedAddress);
}
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to load address information");
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
void fetchBillingInfo();
}, [fetchBillingInfo]);
useEffect(() => {
if (user) {
setFormData({
email: user.email || "",
phonenumber: user.phonenumber || "",
});
}
}, [user]);
const saveProfile = async (next: ProfileEditFormData) => {
setIsSavingProfile(true);
try {
const updatedUser = await accountService.updateProfile({
email: next.email,
phonenumber: next.phonenumber,
});
useAuthStore.setState(state => ({
...state,
user: state.user ? { ...state.user, ...updatedUser } : state.user,
}));
setFormData(next);
return true;
} catch (err) {
logger.error("Error updating profile", err);
setError(err instanceof Error ? err.message : "Failed to update profile");
return false;
} finally {
setIsSavingProfile(false);
}
};
const saveAddress = async (next: Address) => {
setIsSavingAddress(true);
setError(null);
try {
await accountService.updateAddress({
address1: next.address1,
address2: next.address2,
city: next.city,
state: next.state,
postcode: next.postcode,
country: next.country,
countryCode: next.countryCode,
phoneNumber: next.phoneNumber,
phoneCountryCode: next.phoneCountryCode,
});
// Address changes can affect server-personalized catalog results (eligibility).
await queryClient.invalidateQueries({ queryKey: queryKeys.catalog.all() });
setBillingInfo({ address: next });
setAddress(next);
return true;
} catch (err) {
logger.error("Error updating address", err);
setError(err instanceof Error ? err.message : "Failed to update address");
return false;
} finally {
setIsSavingAddress(false);
}
};
return {
loading,
error,
billingInfo,
formData,
setFormData,
addressData,
setAddressData: setAddress,
saveProfile,
saveAddress,
isSavingProfile,
isSavingAddress,
} as const;
}