fix(05-04): replace locked client display with editable email input
- Remove isLocked variable and read-only div for assigned client - Add primaryEmail state pre-filled with assigned client's email, user-editable - Show client name as helper text below the input for reference - Update buildEmailAddresses() to use primaryEmail when assignedClientId is set - Update button disabled logic to gate on primaryEmail when assigned client exists
This commit is contained in:
@@ -40,15 +40,15 @@ export function PreparePanel({
|
|||||||
}: PreparePanelProps) {
|
}: PreparePanelProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
// If the document already has an explicit assigned client, lock to that client.
|
|
||||||
// Otherwise default to the document owner (defaultClientId) but allow changing.
|
|
||||||
const isLocked = assignedClientId !== null;
|
|
||||||
|
|
||||||
// selectedClientId: id from the dropdown (empty string = "pick manually by email")
|
// selectedClientId: id from the dropdown (empty string = "pick manually by email")
|
||||||
const [selectedClientId, setSelectedClientId] = useState<string>(
|
const [selectedClientId, setSelectedClientId] = useState<string>(
|
||||||
assignedClientId ?? defaultClientId,
|
assignedClientId ?? defaultClientId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// primaryEmail: editable email for the assigned client (pre-filled, can be overridden)
|
||||||
|
const assignedClient = clients.find(c => c.id === assignedClientId);
|
||||||
|
const [primaryEmail, setPrimaryEmail] = useState(assignedClient?.email ?? '');
|
||||||
|
|
||||||
// emailInput: raw text for manual email entry (used when selectedClientId is '' or
|
// emailInput: raw text for manual email entry (used when selectedClientId is '' or
|
||||||
// as additional CC addresses)
|
// as additional CC addresses)
|
||||||
const [emailInput, setEmailInput] = useState('');
|
const [emailInput, setEmailInput] = useState('');
|
||||||
@@ -61,12 +61,15 @@ export function PreparePanel({
|
|||||||
const canPrepare = currentStatus === 'Draft';
|
const canPrepare = currentStatus === 'Draft';
|
||||||
|
|
||||||
// The email addresses that will be sent with the prepare request.
|
// The email addresses that will be sent with the prepare request.
|
||||||
// If a known client is selected, start with that client's email.
|
// When an assigned client exists, use the (editable) primaryEmail.
|
||||||
|
// Otherwise use the dropdown-selected client's email.
|
||||||
// Any manually-entered addresses are appended.
|
// Any manually-entered addresses are appended.
|
||||||
function buildEmailAddresses(): string[] {
|
function buildEmailAddresses(): string[] {
|
||||||
const addresses: string[] = [];
|
const addresses: string[] = [];
|
||||||
|
|
||||||
if (selectedClientId) {
|
if (assignedClientId && primaryEmail.trim()) {
|
||||||
|
addresses.push(primaryEmail.trim());
|
||||||
|
} else if (selectedClientId) {
|
||||||
const client = clients.find((c) => c.id === selectedClientId);
|
const client = clients.find((c) => c.id === selectedClientId);
|
||||||
if (client?.email) addresses.push(client.email);
|
if (client?.email) addresses.push(client.email);
|
||||||
}
|
}
|
||||||
@@ -136,22 +139,25 @@ export function PreparePanel({
|
|||||||
<div className="rounded-lg border border-gray-200 p-4 space-y-4">
|
<div className="rounded-lg border border-gray-200 p-4 space-y-4">
|
||||||
<h2 className="font-semibold text-gray-900">Prepare Document</h2>
|
<h2 className="font-semibold text-gray-900">Prepare Document</h2>
|
||||||
|
|
||||||
{/* Client / recipient selection */}
|
{/* Primary recipient */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
{isLocked ? 'Assigned client (locked)' : 'Assign to client'}
|
Recipient email
|
||||||
</label>
|
</label>
|
||||||
|
{assignedClientId ? (
|
||||||
{isLocked ? (
|
<>
|
||||||
// Document already has an assigned client — show read-only info
|
<input
|
||||||
<div className="w-full border rounded px-2 py-1.5 text-sm bg-gray-50 text-gray-600">
|
type="email"
|
||||||
{(() => {
|
value={primaryEmail}
|
||||||
const c = clients.find((c) => c.id === assignedClientId);
|
onChange={(e) => setPrimaryEmail(e.target.value)}
|
||||||
return c ? `${c.name} (${c.email})` : assignedClientId;
|
className="w-full border rounded px-2 py-1.5 text-sm"
|
||||||
})()}
|
placeholder="recipient@example.com"
|
||||||
</div>
|
/>
|
||||||
|
<p className="text-xs text-gray-400 mt-0.5">
|
||||||
|
Assigned client: {clients.find(c => c.id === assignedClientId)?.name ?? assignedClientId}
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
// No explicit assignment yet — allow choosing from list or entering email manually
|
|
||||||
<select
|
<select
|
||||||
value={selectedClientId}
|
value={selectedClientId}
|
||||||
onChange={(e) => setSelectedClientId(e.target.value)}
|
onChange={(e) => setSelectedClientId(e.target.value)}
|
||||||
@@ -168,17 +174,15 @@ export function PreparePanel({
|
|||||||
{/* Additional / manual email addresses */}
|
{/* Additional / manual email addresses */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
{isLocked
|
{assignedClientId || selectedClientId
|
||||||
? 'Additional email addresses (optional, comma-separated)'
|
? 'Additional email addresses (optional, comma-separated)'
|
||||||
: selectedClientId
|
: 'Email address(es) — required if no client selected above'}
|
||||||
? 'Additional email addresses (optional, comma-separated)'
|
|
||||||
: 'Email address(es) — required if no client selected above'}
|
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={emailInput}
|
value={emailInput}
|
||||||
onChange={(e) => setEmailInput(e.target.value)}
|
onChange={(e) => setEmailInput(e.target.value)}
|
||||||
placeholder={
|
placeholder={
|
||||||
isLocked || selectedClientId
|
assignedClientId || selectedClientId
|
||||||
? 'e.g. cc@example.com, another@example.com'
|
? 'e.g. cc@example.com, another@example.com'
|
||||||
: 'Enter recipient email, e.g. client@example.com'
|
: 'Enter recipient email, e.g. client@example.com'
|
||||||
}
|
}
|
||||||
@@ -197,7 +201,7 @@ export function PreparePanel({
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={handlePrepare}
|
onClick={handlePrepare}
|
||||||
disabled={loading || (!selectedClientId && parseEmails(emailInput).length === 0)}
|
disabled={loading || (assignedClientId ? !primaryEmail.trim() : (!selectedClientId && parseEmails(emailInput).length === 0))}
|
||||||
className="w-full py-2 px-4 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed text-sm font-medium"
|
className="w-full py-2 px-4 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed text-sm font-medium"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user