barsa 1a3032bbd3 Refactor Address Handling in Signup and Profile Components
- Updated address handling in Salesforce account and contact services to remove unnecessary address fields during signup, improving data management.
- Refactored address input fields in the SignupForm and AddressForm components to ensure proper labeling and validation for Japanese address formats.
- Enhanced address display logic in ProfileContainer and AddressConfirmation components for better user experience.
- Standardized address field names and improved placeholder texts for clarity and consistency across the application.
2026-01-06 16:13:59 +09:00

109 lines
4.0 KiB
TypeScript

"use client";
import { SubCard } from "@/components/molecules/SubCard/SubCard";
import { MapPinIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { AddressForm, type AddressFormProps } from "@/features/services/components";
import type { Address } from "@customer-portal/domain/customer";
import { getCountryName } from "@/shared/constants";
interface AddressCardProps {
address: Address;
isEditing: boolean;
isSaving: boolean;
error?: string | null;
onEdit: () => void;
onCancel: () => void;
onSave: () => void;
onAddressChange: NonNullable<AddressFormProps["onChange"]>;
}
export function AddressCard({
address,
isEditing,
isSaving,
error,
onEdit,
onCancel,
onSave,
onAddressChange,
}: AddressCardProps) {
const countryLabel = address.country
? (getCountryName(address.country) ?? address.country)
: null;
return (
<SubCard>
<div className="pb-5 border-b border-border/60">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="h-10 w-10 rounded-xl bg-primary/10 flex items-center justify-center">
<MapPinIcon className="h-5 w-5 text-primary" />
</div>
<h2 className="text-lg font-semibold text-foreground">Address Information</h2>
</div>
{!isEditing && (
<button
onClick={onEdit}
className="inline-flex items-center px-4 py-2 border border-border text-sm font-medium rounded-lg text-foreground bg-background hover:bg-muted transition-colors"
>
<PencilIcon className="h-4 w-4 mr-2" />
Edit
</button>
)}
</div>
</div>
<div className="pt-5">
{isEditing ? (
<div className="space-y-6">
<AddressForm initialAddress={address} onChange={addr => onAddressChange(addr, true)} />
{error && <div className="text-sm text-danger">{error}</div>}
<div className="flex items-center justify-end space-x-3 pt-4 border-t border-border/60">
<button
onClick={onCancel}
disabled={isSaving}
className="inline-flex items-center px-4 py-2 border border-border text-sm font-medium rounded-lg text-foreground bg-background hover:bg-muted disabled:opacity-50 transition-colors"
>
<XMarkIcon className="h-4 w-4 mr-2" />
Cancel
</button>
<button
onClick={onSave}
disabled={isSaving}
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-lg text-primary-foreground bg-primary hover:bg-primary-hover disabled:opacity-50 transition-colors shadow-sm"
>
{isSaving ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-primary-foreground mr-2"></div>
Saving...
</>
) : (
<>
<CheckIcon className="h-4 w-4 mr-2" />
Save Address
</>
)}
</button>
</div>
</div>
) : (
<div className="space-y-1.5 text-foreground">
{(address.address2 || address.address1) && (
<p className="font-semibold text-base">{address.address2 || address.address1}</p>
)}
{address.address2 && address.address1 && (
<p className="text-muted-foreground">{address.address1}</p>
)}
{(address.city || address.state || address.postcode) && (
<p className="text-muted-foreground">
{[address.city, address.state, address.postcode].filter(Boolean).join(", ")}
</p>
)}
{countryLabel && <p className="text-muted-foreground font-medium">{countryLabel}</p>}
</div>
)}
</div>
</SubCard>
);
}