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.
This commit is contained in:
barsa 2025-12-15 17:29:48 +09:00
parent 545e62b8a1
commit f1c88b6017
2 changed files with 28 additions and 46 deletions

View File

@ -2,15 +2,15 @@
import { SubCard } from "@/components/molecules/SubCard/SubCard";
import { UserIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
import type { ProfileDisplayData } from "@customer-portal/domain/customer";
import type { UserProfile } from "@customer-portal/domain/customer";
interface PersonalInfoCardProps {
data: ProfileDisplayData;
data: UserProfile;
isEditing: boolean;
isSaving: boolean;
onEdit: () => void;
onCancel: () => void;
onChange: (field: keyof ProfileDisplayData, value: string) => void;
onChange: (field: "email" | "phonenumber", value: string) => void;
onSave: () => void;
}
@ -47,56 +47,41 @@ export function PersonalInfoCard({
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">First Name</label>
{isEditing ? (
<input
type="text"
value={data.firstname}
onChange={e => onChange("firstname", e.target.value)}
className="block w-full px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
) : (
<p className="text-sm text-gray-900 py-2">
<div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
<p className="text-sm text-gray-900 font-medium">
{data.firstname || <span className="text-gray-500 italic">Not provided</span>}
</p>
)}
<p className="text-xs text-gray-500 mt-2">Name cannot be changed from the portal.</p>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Last Name</label>
{isEditing ? (
<input
type="text"
value={data.lastname}
onChange={e => onChange("lastname", e.target.value)}
className="block w-full px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
) : (
<p className="text-sm text-gray-900 py-2">
<div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
<p className="text-sm text-gray-900 font-medium">
{data.lastname || <span className="text-gray-500 italic">Not provided</span>}
</p>
)}
<p className="text-xs text-gray-500 mt-2">Name cannot be changed from the portal.</p>
</div>
</div>
<div className="sm:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-3">Email Address</label>
<div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
<div className="flex items-center justify-between">
<p className="text-base text-gray-900 font-medium">{data.email}</p>
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-green-100 text-green-800 border border-green-200">
<svg className="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
Verified
</span>
{isEditing ? (
<input
type="email"
value={data.email}
onChange={e => onChange("email", e.target.value)}
className="block w-full px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
) : (
<div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
<div className="flex items-center justify-between">
<p className="text-base text-gray-900 font-medium">{data.email}</p>
</div>
<p className="text-xs text-gray-500 mt-2">Email can be updated from the portal.</p>
</div>
<p className="text-xs text-gray-500 mt-2">
Email cannot be changed. Contact support to update your email.
</p>
</div>
)}
</div>
</div>

View File

@ -20,8 +20,7 @@ export function useProfileData() {
const [billingInfo, setBillingInfo] = useState<{ address: Address } | null>(null);
const [formData, setFormData] = useState<ProfileEditFormData>({
firstname: user?.firstname || "",
lastname: user?.lastname || "",
email: user?.email || "",
phonenumber: user?.phonenumber || "",
});
@ -70,8 +69,7 @@ export function useProfileData() {
useEffect(() => {
if (user) {
setFormData({
firstname: user.firstname || "",
lastname: user.lastname || "",
email: user.email || "",
phonenumber: user.phonenumber || "",
});
}
@ -81,8 +79,7 @@ export function useProfileData() {
setIsSavingProfile(true);
try {
const updatedUser = await accountService.updateProfile({
firstname: next.firstname,
lastname: next.lastname,
email: next.email,
phonenumber: next.phonenumber,
});
useAuthStore.setState(state => ({