import { useState } from 'react'; import Modal from 'antd/es/modal'; import Form from 'antd/es/form'; import Input from 'antd/es/input'; import Alert from 'antd/es/alert'; import Button from 'antd/es/button'; import Typography from 'antd/es/typography'; import message from 'antd/es/message'; import { changeCustomerEmail } from './adminCustomersApi'; const { Paragraph, Text } = Typography; type Props = Readonly<{ customerId: number; currentEmail: string; open: boolean; onClose: () => void; /** Called after a successful change, so the drawer and the table can refresh. */ onChanged: () => void; }>; /** * Moving a customer's account to an address they can reach (#337). * * The last step of the only recovery route available to someone who has lost * their mailbox. There is deliberately no self-service equivalent, because the * email address is the root of trust for every other route and this shop holds * no second proof of identity. * * The form leads with what this costs rather than burying it, because the * operator is about to make a decision on someone else's behalf and the * consequences land on that person, not on them. */ export default function ChangeCustomerEmail({ customerId, currentEmail, open, onClose, onChanged }: Props) { const [form] = Form.useForm(); const [saving, setSaving] = useState(false); async function submit(values: { email: string; reason: string }) { setSaving(true); try { const result = await changeCustomerEmail(customerId, values.email, values.reason); // Named rather than counted, because "moved to that address" is the fact // the operator has to repeat back to the customer on the phone. message.success(`Account moved to ${result.customer.email}`); if (result.passkeysRemoved > 0) { // Its own message and a long one. The customer will find their passkeys // gone and needs to be told why while they are still on the line — // finding out later looks like a second thing going wrong. message.warning( result.passkeysRemoved === 1 ? 'Their saved passkey was removed. They will need to set it up again.' : `Their ${result.passkeysRemoved} saved passkeys were removed. They will need to set them up again.`, 10 ); } form.resetFields(); onChanged(); onClose(); } catch (err) { message.error((err as Error).message); } finally { setSaving(false); } } return ( Moving the account signs the customer out everywhere, removes any saved passkeys, and cancels reset links already sent to {currentEmail}. A notice goes to that address, and a confirmation link goes to the new one.
); }