teqo/src/components/WhatsappForm.tsx
Francisco Ignácio Fontoura Solla 0e4e6855dc Add the tooling gate: knip, CI, zero-warning lint, as-never ban
- knip (files/deps at error level; unused exports ledgered as warn) with
  config for Payload/Next entries; deleted the dead modules it confirmed:
  RecentlyVisited + UpcomingActionPlansCard + actionPlanUpcomingPreview,
  lazy-dialog helpers, tseZone, federalCandidateTotalsAggregate (test-only),
  unused ui kit files, one-shot rename script; pruned unused radix deps and
  typescript-eslint; added pg/@types/pg (pinned to drizzle's 8.10.2)
- GitHub Actions CI on the mirror: lint, typecheck, knip, unit, migrate, int
  against a Postgres 17 service
- eslint: unused-vars with ^_ ignore patterns (migrations args exempt),
  repo-wide ban on `as never` (no-restricted-syntax), lint gate at
  --max-warnings=0; fixed all 54 pre-existing warnings (dead imports,
  hooks deps, tracking-pixel img disable with impeccable config exception)
- tsconfig: include consolidated from 219 lines to 5 (wildcard covers all
  .next dist variants), noUnusedLocals on
- typed replacements for every as-never: hookFilledCreateData (actions
  create data completed by collection hooks), drizzle scopeColumn narrowing,
  tests' stub<T> helper (property-level checking kept, completeness waived)
- test infra: leased-consent generalization used by onda0 spec (shared
  leases over the stable consent keys; window race ledgered), purge fix
- docs: IMPROVE-CODE-QUALITY-PLAN.md tracker, TECH-DEBT.md ledger,
  TESTING.md safety-net map (package.json also gains the Phase 2
  build:election-aggregates script entry; the script lands next commit)
2026-07-23 23:06:12 -03:00

103 lines
3.2 KiB
TypeScript

'use client'
import { CitySelect } from '@/components/CitySelect'
import { EmailInput } from '@/components/EmailInput'
import { NameInput } from '@/components/NameInput'
import { PhoneInput } from '@/components/PhoneInput'
import { StateSelect } from '@/components/StateSelect'
import { Button } from '@/components/ui/button'
import { Field, FieldDescription, FieldGroup } from '@/components/ui/field'
import { Textarea } from '@/components/ui/textarea'
import { WhatsAppFormInput, whatsAppFormSchema } from '@/lib/schemas/whatsapp-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form'
import { useTransition } from 'react'
import { submitWhatsapp } from '@/app/(frontend)/actions/submitWhatsapp'
interface WhatsappFormProps {
classname?: string
onSubmit: () => void
}
export const WhatsappForm = ({ classname, onSubmit }: WhatsappFormProps) => {
const methods = useForm<WhatsAppFormInput>({
resolver: zodResolver(whatsAppFormSchema),
defaultValues: {
name: '',
email: '',
phone: '',
state: undefined,
city: '',
comment: '',
},
})
const [isSubmitting, startTransition] = useTransition()
const handleSubmit: SubmitHandler<WhatsAppFormInput> = (input) => {
startTransition(async () => {
try {
await submitWhatsapp(input)
methods.reset()
onSubmit()
} catch (e) {
console.log(e)
methods.setError('root', {
message: 'Falha ao enviar assinatura. Tente novamente.',
})
}
})
}
return (
<FormProvider {...methods}>
<form
id="mandato-no-whatsapp"
onSubmit={methods.handleSubmit(handleSubmit)}
className={classname}
>
<FieldGroup>
<Field>
<NameInput placeholder="Nome completo*" />
</Field>
<Field>
<PhoneInput placeholder="WhatsApp (com DDD)*" />
</Field>
<Field>
<EmailInput placeholder="Digite seu melhor email*" />
</Field>
<div className="flex gap-2">
<Field>
<StateSelect placeholder="Estado" />
</Field>
<Field>
<CitySelect placeholder="Cidade" />
</Field>
</div>
<Field>
<Textarea
id="comment"
{...methods.register('comment')}
placeholder='Campo de Interesse: "O que você mais quer ver no canal?" (Votações, Bastidores, Ações Sociais, Agenda).'
className="min-h-22"
/>
</Field>
<Field>
{methods.formState.errors.root?.message ? (
<FieldDescription className="text-destructive">
{methods.formState.errors.root.message}
</FieldDescription>
) : null}
<Button
type="submit"
disabled={isSubmitting}
className="bg-[#99c343] font-bold text-xl py-6 rounded-full"
>
{isSubmitting ? 'Enviando...' : 'FAZER MEU CADASTRO'}
</Button>
</Field>
</FieldGroup>
</form>
</FormProvider>
)
}