2025-09-17 18:43:43 +09:00
|
|
|
"use client";
|
|
|
|
|
|
2025-09-25 15:14:36 +09:00
|
|
|
import { SubCard } from "@/components/molecules/SubCard/SubCard";
|
2025-09-17 18:43:43 +09:00
|
|
|
import { UserIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
2025-12-15 17:29:48 +09:00
|
|
|
import type { UserProfile } from "@customer-portal/domain/customer";
|
2025-12-16 13:54:31 +09:00
|
|
|
import { Button } from "@/components/atoms/button";
|
|
|
|
|
import { Input } from "@/components/atoms/input";
|
2025-09-17 18:43:43 +09:00
|
|
|
|
|
|
|
|
interface PersonalInfoCardProps {
|
2025-12-15 17:29:48 +09:00
|
|
|
data: UserProfile;
|
2025-09-17 18:43:43 +09:00
|
|
|
isEditing: boolean;
|
|
|
|
|
isSaving: boolean;
|
|
|
|
|
onEdit: () => void;
|
|
|
|
|
onCancel: () => void;
|
2025-12-15 17:29:48 +09:00
|
|
|
onChange: (field: "email" | "phonenumber", value: string) => void;
|
2025-09-17 18:43:43 +09:00
|
|
|
onSave: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function PersonalInfoCard({
|
|
|
|
|
data,
|
|
|
|
|
isEditing,
|
|
|
|
|
isSaving,
|
|
|
|
|
onEdit,
|
|
|
|
|
onCancel,
|
|
|
|
|
onChange,
|
|
|
|
|
onSave,
|
|
|
|
|
}: PersonalInfoCardProps) {
|
|
|
|
|
return (
|
|
|
|
|
<SubCard>
|
2025-12-16 13:54:31 +09:00
|
|
|
<div className="pb-5 border-b border-border">
|
2025-09-17 18:43:43 +09:00
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<div className="flex items-center space-x-3">
|
2025-12-16 13:54:31 +09:00
|
|
|
<UserIcon className="h-6 w-6 text-primary" />
|
|
|
|
|
<h2 className="text-xl font-semibold text-foreground">Personal Information</h2>
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
|
|
|
|
{!isEditing && (
|
2025-12-16 13:54:31 +09:00
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
2025-09-17 18:43:43 +09:00
|
|
|
onClick={onEdit}
|
2025-12-16 13:54:31 +09:00
|
|
|
leftIcon={<PencilIcon className="h-4 w-4" />}
|
2025-09-17 18:43:43 +09:00
|
|
|
>
|
|
|
|
|
Edit
|
2025-12-16 13:54:31 +09:00
|
|
|
</Button>
|
2025-09-17 18:43:43 +09:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="pt-5">
|
|
|
|
|
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2">
|
|
|
|
|
<div>
|
2025-12-16 13:54:31 +09:00
|
|
|
<label className="block text-sm font-medium text-muted-foreground mb-2">
|
|
|
|
|
First Name
|
|
|
|
|
</label>
|
|
|
|
|
<div className="bg-muted rounded-lg p-4 border border-border">
|
|
|
|
|
<p className="text-sm text-foreground font-medium">
|
|
|
|
|
{data.firstname || (
|
|
|
|
|
<span className="text-muted-foreground italic">Not provided</span>
|
|
|
|
|
)}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-xs text-muted-foreground mt-2">
|
|
|
|
|
Name cannot be changed from the portal.
|
2025-09-17 18:43:43 +09:00
|
|
|
</p>
|
2025-12-15 17:29:48 +09:00
|
|
|
</div>
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
2025-12-16 13:54:31 +09:00
|
|
|
<label className="block text-sm font-medium text-muted-foreground mb-2">
|
|
|
|
|
Last Name
|
|
|
|
|
</label>
|
|
|
|
|
<div className="bg-muted rounded-lg p-4 border border-border">
|
|
|
|
|
<p className="text-sm text-foreground font-medium">
|
|
|
|
|
{data.lastname || (
|
|
|
|
|
<span className="text-muted-foreground italic">Not provided</span>
|
|
|
|
|
)}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-xs text-muted-foreground mt-2">
|
|
|
|
|
Name cannot be changed from the portal.
|
2025-09-17 18:43:43 +09:00
|
|
|
</p>
|
2025-12-15 17:29:48 +09:00
|
|
|
</div>
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="sm:col-span-2">
|
2025-12-16 13:54:31 +09:00
|
|
|
<label className="block text-sm font-medium text-muted-foreground mb-3">
|
|
|
|
|
Email Address
|
|
|
|
|
</label>
|
2025-12-15 17:29:48 +09:00
|
|
|
{isEditing ? (
|
2025-12-16 13:54:31 +09:00
|
|
|
<Input
|
2025-12-15 17:29:48 +09:00
|
|
|
type="email"
|
|
|
|
|
value={data.email}
|
|
|
|
|
onChange={e => onChange("email", e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
2025-12-16 13:54:31 +09:00
|
|
|
<div className="bg-muted rounded-lg p-4 border border-border">
|
2025-12-15 17:29:48 +09:00
|
|
|
<div className="flex items-center justify-between">
|
2025-12-16 13:54:31 +09:00
|
|
|
<p className="text-base text-foreground font-medium">{data.email}</p>
|
2025-12-15 17:29:48 +09:00
|
|
|
</div>
|
2025-12-16 13:54:31 +09:00
|
|
|
<p className="text-xs text-muted-foreground mt-2">
|
|
|
|
|
Email can be updated from the portal.
|
|
|
|
|
</p>
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
2025-12-15 17:29:48 +09:00
|
|
|
)}
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{isEditing && (
|
2025-12-16 13:54:31 +09:00
|
|
|
<div className="flex items-center justify-end space-x-3 pt-6 border-t border-border mt-6">
|
|
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
2025-09-17 18:43:43 +09:00
|
|
|
onClick={onCancel}
|
|
|
|
|
disabled={isSaving}
|
2025-12-16 13:54:31 +09:00
|
|
|
leftIcon={<XMarkIcon className="h-4 w-4" />}
|
2025-09-17 18:43:43 +09:00
|
|
|
>
|
|
|
|
|
Cancel
|
2025-12-16 13:54:31 +09:00
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
2025-09-17 18:43:43 +09:00
|
|
|
onClick={onSave}
|
|
|
|
|
disabled={isSaving}
|
2025-12-16 13:54:31 +09:00
|
|
|
isLoading={isSaving}
|
|
|
|
|
loadingText="Saving…"
|
|
|
|
|
leftIcon={!isSaving ? <CheckIcon className="h-4 w-4" /> : undefined}
|
2025-09-17 18:43:43 +09:00
|
|
|
>
|
2025-12-16 13:54:31 +09:00
|
|
|
Save Changes
|
|
|
|
|
</Button>
|
2025-09-17 18:43:43 +09:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</SubCard>
|
|
|
|
|
);
|
|
|
|
|
}
|