diff --git a/.env b/.env new file mode 100644 index 0000000..14fb927 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNtc2FybWdvaXJsY2VkbXF2ZGdjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzY0MzczNjAsImV4cCI6MjA5MjAxMzM2MH0.AjMSQOn3BtzV-fJ2x9SWoM2ozjLyPD6g3dmTSeCT9II" +SUPABASE_URL="https://smsarmgoirlcedmqvdgc.supabase.co" +VITE_SUPABASE_PROJECT_ID="smsarmgoirlcedmqvdgc" +VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNtc2FybWdvaXJsY2VkbXF2ZGdjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzY0MzczNjAsImV4cCI6MjA5MjAxMzM2MH0.AjMSQOn3BtzV-fJ2x9SWoM2ozjLyPD6g3dmTSeCT9II" +VITE_SUPABASE_URL="https://smsarmgoirlcedmqvdgc.supabase.co" diff --git a/bun.lockb b/bun.lockb index fd9327d..4d5c249 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index edd0f95..c5445e7 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,9 @@ "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.11", "@radix-ui/react-tooltip": "^1.2.8", + "@supabase/supabase-js": "^2.103.3", "@tailwindcss/vite": "^4.2.1", - "@tanstack/react-query": "^5.83.0", + "@tanstack/react-query": "^5.99.0", "@tanstack/react-router": "^1.168.0", "@tanstack/react-start": "^1.167.14", "@tanstack/router-plugin": "^1.167.10", @@ -50,12 +51,14 @@ "cmdk": "^1.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", + "framer-motion": "^12.38.0", "input-otp": "^1.4.2", "lucide-react": "^0.575.0", "react": "^19.2.0", "react-day-picker": "^9.14.0", "react-dom": "^19.2.0", - "react-hook-form": "^7.71.2", + "react-hook-form": "^7.72.1", + "react-imask": "^7.6.1", "react-resizable-panels": "^4.6.5", "recharts": "^2.15.4", "sonner": "^2.0.7", @@ -64,7 +67,7 @@ "tw-animate-css": "^1.3.4", "vaul": "^1.1.2", "vite-tsconfig-paths": "^6.0.2", - "zod": "^3.24.2" + "zod": "^4.3.6" }, "devDependencies": { "@eslint/js": "^9.32.0", diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..27dbdc5 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,5 @@ + + + M. + diff --git a/public/og.svg b/public/og.svg new file mode 100644 index 0000000..6d155cf --- /dev/null +++ b/public/og.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + Mika. + + + Seu assistente de IA no Telegram + + + mika.domco.ai + + + diff --git a/src/components/mika/EnterpriseLeadForm.tsx b/src/components/mika/EnterpriseLeadForm.tsx new file mode 100644 index 0000000..dd86d4f --- /dev/null +++ b/src/components/mika/EnterpriseLeadForm.tsx @@ -0,0 +1,119 @@ +"use client"; + +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; +import { IMaskInput } from "react-imask"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { Label } from "@/components/ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Loader2 } from "lucide-react"; + +const schema = z.object({ + company_name: z.string().min(2, "Informe o nome da empresa").max(120), + contact_name: z.string().min(2, "Informe seu nome").max(120), + email: z.string().email("Formato de e-mail inválido."), + phone: z.string().min(14, "Telefone inválido").max(20), + team_size: z.enum(["1-10", "11-50", "51-200", "200+"], { message: "Selecione o tamanho da equipe" }), + message: z.string().max(1000).optional(), +}); + +type FormValues = z.infer; + +export function EnterpriseLeadForm() { + const [submitting, setSubmitting] = useState(false); + const { + register, + handleSubmit, + setValue, + watch, + reset, + formState: { errors }, + } = useForm({ resolver: zodResolver(schema) }); + + const onSubmit = async (data: FormValues) => { + setSubmitting(true); + try { + // Etapa 2: gravar em enterprise_leads via supabase.from(...).insert(...) + // Por ora: feedback otimista para o usuário. + await new Promise((r) => setTimeout(r, 700)); + toast.success("Recebemos seu contato! Falamos com você em até 1 dia útil."); + reset(); + } catch { + toast.error("Algo deu errado do nosso lado. Já estamos investigando."); + } finally { + setSubmitting(false); + } + }; + + const phone = watch("phone") || ""; + + return ( +
+
+
+ + + {errors.company_name &&

{errors.company_name.message}

} +
+
+ + + {errors.contact_name &&

{errors.contact_name.message}

} +
+
+ +
+
+ + + {errors.email &&

{errors.email.message}

} +
+
+ + setValue("phone", value as string, { shouldValidate: true })} + placeholder="(11) 99999-9999" + className="flex h-10 w-full rounded-lg border border-input bg-transparent px-3 py-2 text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" + /> + {errors.phone &&

{errors.phone.message}

} +
+
+ +
+ + + {errors.team_size &&

{errors.team_size.message}

} +
+ +
+ +