diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e6acb0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +node_modules +.next +dist +.env +.env.* +.vscode +.DS_Store +next-env.d.ts +.vercel +package-lock.json +yarn.lock +pnpm-lock.yaml +bun.lockb +coverage +build diff --git a/app/api/sign/route.ts b/app/api/sign/route.ts index 2fe313d..c89299a 100644 --- a/app/api/sign/route.ts +++ b/app/api/sign/route.ts @@ -111,15 +111,16 @@ export async function POST(req: NextRequest) { const pubQr = supabaseAdmin.storage.from('signflow').getPublicUrl(`${id}/qr.png`); // 7) Atualizar registro (payload tipado para evitar 'never') - const payload: Database['public']['Tables']['documents']['Update'] = { + const payload = { signed_pdf_url: pubSigned.data.publicUrl, qr_code_url: pubQr.data.publicUrl, status: 'signed', - }; + } satisfies Database['public']['Tables']['documents']['Update']; const upd = await supabaseAdmin .from('documents') - .update(payload) + // Supabase types infer `never` without casting; cast avoids TS error + .update(payload as never) .eq('id', id); if (upd.error) { diff --git a/app/api/upload/route.ts b/app/api/upload/route.ts index a3d8149..cc6e1ca 100644 --- a/app/api/upload/route.ts +++ b/app/api/upload/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { supabaseAdmin } from '@/lib/supabaseAdmin'; +import type { Database } from '@/lib/types'; import crypto from 'crypto'; export async function POST(req: NextRequest){ @@ -38,8 +39,8 @@ export async function POST(req: NextRequest){ userId = u?.user?.id || null; } - // cria registro do documento - const { error: errDoc } = await supabaseAdmin.from('documents').insert({ + // cria registro do documento (payload tipado) + const insertPayload = { id, user_id: userId, original_pdf_name, @@ -49,8 +50,13 @@ export async function POST(req: NextRequest){ expires_at: new Date(Date.now()+7*24*3600*1000).toISOString(), signed_pdf_url: null, qr_code_url: null, - ip_hash - }); + ip_hash, + } satisfies Database['public']['Tables']['documents']['Insert']; + + const { error: errDoc } = await supabaseAdmin + .from('documents') + // Supabase types infer `never` without casting + .insert(insertPayload as never); if (errDoc) throw errDoc; // salva arquivos no Storage (bucket: 'signflow') diff --git a/app/editor/[id]/page.tsx b/app/editor/[id]/page.tsx index 0459a83..d3cfffa 100644 --- a/app/editor/[id]/page.tsx +++ b/app/editor/[id]/page.tsx @@ -1,13 +1,21 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, type ChangeEvent } from 'react'; import PdfEditor from '@/components/PdfEditor'; import { Card, Input, Label } from '@/components/Ui'; import { createClient } from '@supabase/supabase-js'; +type Position = { + page: number; + nx: number; + ny: number; + scale: number; + rotation: number; +}; + export default function Editor({ params }: { params: { id: string } }){ const [pdf, setPdf] = useState(null); const [sig, setSig] = useState(null); - const [positions, setPositions] = useState([]); + const [positions, setPositions] = useState([]); const [saving, setSaving] = useState(false); const [name, setName] = useState(''); @@ -42,11 +50,23 @@ export default function Editor({ params }: { params: { id: string } }){
- setPdf(e.target.files?.[0]||null)} /> + ) => + setPdf(e.target.files?.[0] || null) + } + />
- setSig(e.target.files?.[0]||null)} /> + ) => + setSig(e.target.files?.[0] || null) + } + />
@@ -54,7 +74,13 @@ export default function Editor({ params }: { params: { id: string } }){
- setName(e.target.value)} placeholder="Contrato.pdf" /> + ) => + setName(e.target.value) + } + placeholder="Contrato.pdf" + />

O QR será inserido na última página, canto inferior esquerdo.

diff --git a/app/validate/[id]/page.tsx b/app/validate/[id]/page.tsx index f77ccaf..0fddba0 100644 --- a/app/validate/[id]/page.tsx +++ b/app/validate/[id]/page.tsx @@ -1,24 +1,29 @@ import { supabaseAdmin } from '@/lib/supabaseAdmin'; +import type { Database } from '@/lib/types'; import Link from 'next/link'; export default async function Validate({ params }: { params: { id: string } }){ - const { data, error } = await supabaseAdmin.from('documents').select('*').eq('id', params.id).maybeSingle(); - if (error || !data) return

Documento não encontrado.

; + const { data: doc, error } = await supabaseAdmin + .from('documents') + .select('*') + .eq('id', params.id) + .maybeSingle(); + if (error || !doc) return

Documento não encontrado.

; return (

Validação do documento

    -
  • ID: {data.id}
  • -
  • Status: {data.status}
  • -
  • Assinado em: {new Date(data.created_at).toLocaleString()}
  • +
  • ID: {doc.id}
  • +
  • Status: {doc.status}
  • +
  • Assinado em: {new Date(doc.created_at).toLocaleString()}
- {data.signed_pdf_url && ( - Baixar PDF assinado + {doc.signed_pdf_url && ( + Baixar PDF assinado )}
- +
Se o PDF não abrir, use o botão de download acima.
Link público de validação