teqo/src/components/campaign/advisor/AdvisorPasswordResetButton.tsx
Francisco Ignácio Fontoura Solla 4806c417c8 Engineering Pass 3: consolidate patterns and lock them with guards.
Fold duplicated campanha access, loaders, list/filter/form shells, and scripts into shared modules; reorganize utilities by domain; stabilize e2e; and document prevention-first audit workflow so the same smells cannot creep back in.
2026-07-29 06:11:29 -03:00

83 lines
2.6 KiB
TypeScript

'use client'
import { KeyRoundIcon } from 'lucide-react'
import { useActionState, useEffect } from 'react'
import { toast } from 'sonner'
import { useCampaignFormSuccessToast } from '@/components/campaign/shared/useCampaignFormSuccessToast'
import { Button } from '@/components/ui/button'
import { Spinner } from '@/components/ui/Spinner'
import { PLACEHOLDER_RESET_MESSAGE } from '@/lib/schemas/advisor'
import type { CampaignFormActionState } from '@/utilities/campaignFormActionError'
type AdvisorPasswordResetButtonProps = {
advisorId: number
disabled: boolean
/** `icon` is the compact row action; `block` is the labelled button plus hint. */
layout?: 'block' | 'icon'
/** Names the advisor for screen readers in the `icon` layout. */
accessibleName?: string
formAction: (
state: CampaignFormActionState,
formData: FormData,
) => Promise<CampaignFormActionState>
}
export const AdvisorPasswordResetButton = ({
advisorId,
disabled,
layout = 'block',
accessibleName = 'Enviar link de senha',
formAction,
}: AdvisorPasswordResetButtonProps) => {
const [state, submitAction, isPending] = useActionState(formAction, {})
useCampaignFormSuccessToast({ status: state.status, message: state.message ?? 'Link enviado.' })
useEffect(() => {
if (state.message && state.status !== 'success') {
toast.error(state.message)
}
}, [state.message, state.status])
if (layout === 'icon') {
return (
<form action={submitAction}>
<input type="hidden" name="advisorId" value={advisorId} />
<Button
type="submit"
variant="ghost"
size="icon"
className="size-10"
disabled={disabled || isPending}
aria-label={
disabled ? `${accessibleName} — ${PLACEHOLDER_RESET_MESSAGE}` : accessibleName
}
>
{isPending ? (
<Spinner className="size-4" aria-hidden="true" />
) : (
<KeyRoundIcon className="size-4" aria-hidden="true" />
)}
</Button>
</form>
)
}
return (
<form action={submitAction} className="flex flex-col gap-2">
<input type="hidden" name="advisorId" value={advisorId} />
<Button type="submit" className="min-h-11 w-fit" disabled={disabled || isPending}>
{isPending ? <Spinner data-icon="inline-start" /> : null}
Enviar link de senha
</Button>
{disabled ? (
<p className="text-sm text-muted-foreground">{PLACEHOLDER_RESET_MESSAGE}</p>
) : (
<p className="text-sm text-muted-foreground">
Envia um e-mail com link para o assessor definir a senha de acesso.
</p>
)}
</form>
)
}