Apply SQL migration
Apply the SQL migration to the database.
This commit is contained in:
parent
0dc7667f05
commit
8c3b01e6b6
@ -3,8 +3,8 @@ import { useState } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
|
||||||
import { supabase } from "@/integrations/supabase/client";
|
import { supabase } from "@/integrations/supabase/client";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface LoginFormProps {
|
interface LoginFormProps {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
@ -13,74 +13,30 @@ interface LoginFormProps {
|
|||||||
|
|
||||||
const LoginForm = ({ isLoading, setIsLoading }: LoginFormProps) => {
|
const LoginForm = ({ isLoading, setIsLoading }: LoginFormProps) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { toast } = useToast();
|
|
||||||
|
|
||||||
// State for login form
|
|
||||||
const [loginEmail, setLoginEmail] = useState('');
|
const [loginEmail, setLoginEmail] = useState('');
|
||||||
const [loginSenha, setLoginSenha] = useState('');
|
const [loginSenha, setLoginSenha] = useState('');
|
||||||
|
|
||||||
// Function for handling login
|
|
||||||
const handleLogin = async (e: React.FormEvent) => {
|
const handleLogin = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
const { error } = await supabase.auth.signInWithPassword({
|
||||||
// Tenta autenticar o usuário através da função RPC do Supabase
|
email: loginEmail,
|
||||||
const { data, error } = await supabase.rpc('autenticar_usuario', {
|
password: loginSenha,
|
||||||
email_login: loginEmail,
|
});
|
||||||
senha_login: loginSenha
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error || !data) {
|
|
||||||
throw new Error(error?.message || "Falha ao autenticar. Verifique seu email e senha.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Se encontrou um usuário válido
|
setIsLoading(false);
|
||||||
if (data) {
|
|
||||||
// Fetch user details to get the WhatsApp number
|
if (error) {
|
||||||
const { data: userData, error: userError } = await supabase
|
toast.error("Erro no login", {
|
||||||
.from('usuarios')
|
description: "Email ou senha incorretos. Verifique seus dados."
|
||||||
.select('nome, email, whatsapp')
|
|
||||||
.eq('id', data)
|
|
||||||
.single();
|
|
||||||
|
|
||||||
if (userError) {
|
|
||||||
console.error("Erro ao buscar dados do usuário:", userError);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Armazenar informações de sessão
|
|
||||||
localStorage.setItem('autenticado', 'true');
|
|
||||||
localStorage.setItem('userId', data);
|
|
||||||
localStorage.setItem('userEmail', loginEmail);
|
|
||||||
|
|
||||||
if (userData) {
|
|
||||||
localStorage.setItem('userName', userData.nome);
|
|
||||||
localStorage.setItem('userWhatsapp', userData.whatsapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
toast({
|
|
||||||
title: "Login realizado com sucesso",
|
|
||||||
description: "Bem-vindo de volta!"
|
|
||||||
});
|
|
||||||
|
|
||||||
// Corrigir o redirecionamento para a rota principal "/"
|
|
||||||
navigate('/');
|
|
||||||
} else {
|
|
||||||
toast({
|
|
||||||
title: "Falha no login",
|
|
||||||
description: "Email ou senha incorretos",
|
|
||||||
variant: "destructive"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Erro ao fazer login:", error);
|
|
||||||
toast({
|
|
||||||
title: "Erro ao fazer login",
|
|
||||||
description: "Verifique suas credenciais e tente novamente",
|
|
||||||
variant: "destructive"
|
|
||||||
});
|
});
|
||||||
} finally {
|
} else {
|
||||||
setIsLoading(false);
|
toast.success("Login realizado com sucesso", {
|
||||||
|
description: "Bem-vindo de volta!"
|
||||||
|
});
|
||||||
|
navigate('/');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
|
||||||
import { formatarWhatsapp } from '@/utils/whatsappFormatter';
|
import { formatarWhatsapp } from '@/utils/whatsappFormatter';
|
||||||
import { validateRegisterForm } from '@/utils/registerValidation';
|
import { validateRegisterForm } from '@/utils/registerValidation';
|
||||||
import { registerUser, loginAfterRegister } from '@/services/registerService';
|
|
||||||
import RegisterFormFields from './RegisterFormFields';
|
import RegisterFormFields from './RegisterFormFields';
|
||||||
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface RegisterFormProps {
|
interface RegisterFormProps {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
@ -14,22 +13,16 @@ interface RegisterFormProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
||||||
const navigate = useNavigate();
|
|
||||||
const { toast } = useToast();
|
|
||||||
|
|
||||||
// Estado do formulário de cadastro
|
|
||||||
const [nome, setNome] = useState('');
|
const [nome, setNome] = useState('');
|
||||||
const [empresa, setEmpresa] = useState('');
|
const [empresa, setEmpresa] = useState('');
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [whatsapp, setWhatsapp] = useState('55()');
|
const [whatsapp, setWhatsapp] = useState('55');
|
||||||
const [senha, setSenha] = useState('');
|
const [senha, setSenha] = useState('');
|
||||||
const [confirmaSenha, setConfirmaSenha] = useState('');
|
const [confirmaSenha, setConfirmaSenha] = useState('');
|
||||||
|
|
||||||
// Função para cadastrar usuário
|
|
||||||
const handleCadastro = async (e: React.FormEvent) => {
|
const handleCadastro = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Validações básicas
|
|
||||||
const validationError = validateRegisterForm({
|
const validationError = validateRegisterForm({
|
||||||
nome,
|
nome,
|
||||||
empresa,
|
empresa,
|
||||||
@ -40,52 +33,42 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (validationError) {
|
if (validationError) {
|
||||||
toast({
|
toast.error("Campos obrigatórios", { description: validationError });
|
||||||
title: "Campos obrigatórios",
|
|
||||||
description: validationError,
|
|
||||||
variant: "destructive"
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
const { data, error } = await supabase.auth.signUp({
|
||||||
const { userId, whatsappLimpo } = await registerUser({
|
email,
|
||||||
nome,
|
password: senha,
|
||||||
empresa,
|
options: {
|
||||||
email,
|
emailRedirectTo: `${window.location.origin}/`,
|
||||||
whatsapp,
|
data: {
|
||||||
senha
|
nome,
|
||||||
});
|
empresa: empresa || null,
|
||||||
|
whatsapp: whatsapp.replace(/\D/g, ''),
|
||||||
toast({
|
}
|
||||||
title: "Cadastro realizado",
|
|
||||||
description: "Sua conta foi criada com sucesso!"
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fazer login automaticamente após o cadastro
|
|
||||||
const loginData = await loginAfterRegister(email, senha);
|
|
||||||
|
|
||||||
if (loginData) {
|
|
||||||
localStorage.setItem('autenticado', 'true');
|
|
||||||
localStorage.setItem('userId', loginData);
|
|
||||||
localStorage.setItem('userEmail', email);
|
|
||||||
localStorage.setItem('userName', nome);
|
|
||||||
localStorage.setItem('userWhatsapp', whatsappLimpo);
|
|
||||||
|
|
||||||
// Redirecionamento para a página principal após cadastro bem-sucedido
|
|
||||||
navigate('/');
|
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
});
|
||||||
console.error("Erro ao cadastrar:", error);
|
|
||||||
toast({
|
setIsLoading(false);
|
||||||
title: "Erro no cadastro",
|
|
||||||
description: error.message || "Não foi possível completar o cadastro",
|
if (error) {
|
||||||
variant: "destructive"
|
toast.error("Erro no cadastro", {
|
||||||
|
description: error.message || "Não foi possível completar o cadastro. O e-mail já pode estar em uso.",
|
||||||
});
|
});
|
||||||
} finally {
|
} else if (data.user) {
|
||||||
setIsLoading(false);
|
if (data.user.identities && data.user.identities.length === 0) {
|
||||||
|
toast.error("Erro no cadastro", {
|
||||||
|
description: "Este e-mail já está em uso. Tente fazer login.",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toast.success("Cadastro realizado com sucesso!", {
|
||||||
|
description: "Enviamos um link de confirmação para o seu e-mail. Por favor, verifique sua caixa de entrada e spam.",
|
||||||
|
duration: 10000,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -475,7 +475,6 @@ export type Database = {
|
|||||||
instancia_zap: string | null
|
instancia_zap: string | null
|
||||||
nome: string | null
|
nome: string | null
|
||||||
remote_jid: string | null
|
remote_jid: string | null
|
||||||
senha: string | null
|
|
||||||
status_instancia: string | null
|
status_instancia: string | null
|
||||||
webhook: string | null
|
webhook: string | null
|
||||||
whatsapp: string
|
whatsapp: string
|
||||||
@ -488,7 +487,6 @@ export type Database = {
|
|||||||
instancia_zap?: string | null
|
instancia_zap?: string | null
|
||||||
nome?: string | null
|
nome?: string | null
|
||||||
remote_jid?: string | null
|
remote_jid?: string | null
|
||||||
senha?: string | null
|
|
||||||
status_instancia?: string | null
|
status_instancia?: string | null
|
||||||
webhook?: string | null
|
webhook?: string | null
|
||||||
whatsapp: string
|
whatsapp: string
|
||||||
@ -501,7 +499,6 @@ export type Database = {
|
|||||||
instancia_zap?: string | null
|
instancia_zap?: string | null
|
||||||
nome?: string | null
|
nome?: string | null
|
||||||
remote_jid?: string | null
|
remote_jid?: string | null
|
||||||
senha?: string | null
|
|
||||||
status_instancia?: string | null
|
status_instancia?: string | null
|
||||||
webhook?: string | null
|
webhook?: string | null
|
||||||
whatsapp?: string
|
whatsapp?: string
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
import { supabase } from "@/integrations/supabase/client";
|
|
||||||
import { enviarDadosParaWebhook } from '@/utils/webhookService';
|
|
||||||
|
|
||||||
export interface UserRegistrationData {
|
|
||||||
nome: string;
|
|
||||||
empresa: string;
|
|
||||||
email: string;
|
|
||||||
whatsapp: string;
|
|
||||||
senha: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const registerUser = async (userData: UserRegistrationData) => {
|
|
||||||
const { nome, empresa, email, senha, whatsapp } = userData;
|
|
||||||
|
|
||||||
// Removemos formatação antes de enviar para o banco
|
|
||||||
const whatsappLimpo = whatsapp.replace(/\D/g, '');
|
|
||||||
|
|
||||||
// Registrar o usuário usando a função RPC do Supabase
|
|
||||||
const { data, error } = await supabase.rpc('registrar_usuario', {
|
|
||||||
nome,
|
|
||||||
empresa: empresa || null,
|
|
||||||
email,
|
|
||||||
senha,
|
|
||||||
whatsapp: whatsappLimpo
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) throw error;
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
// Preparar os dados do usuário para enviar ao webhook
|
|
||||||
const dadosUsuario = {
|
|
||||||
nome,
|
|
||||||
empresa,
|
|
||||||
email,
|
|
||||||
whatsapp: whatsappLimpo,
|
|
||||||
data_cadastro: new Date().toISOString(),
|
|
||||||
origem: window.location.origin,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enviar dados do usuário para o webhook
|
|
||||||
await enviarDadosParaWebhook(dadosUsuario);
|
|
||||||
|
|
||||||
return { userId: data, whatsappLimpo };
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("Falha no registro do usuário");
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loginAfterRegister = async (email: string, senha: string) => {
|
|
||||||
const { data, error } = await supabase.rpc('autenticar_usuario', {
|
|
||||||
email_login: email,
|
|
||||||
senha_login: senha
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) throw error;
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
-- This function creates a new row in the public.usuarios table
|
||||||
|
-- whenever a new user signs up in auth.users.
|
||||||
|
CREATE OR REPLACE FUNCTION public.handle_new_user()
|
||||||
|
RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path = public
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO public.usuarios (id, email)
|
||||||
|
VALUES (new.id, new.email);
|
||||||
|
RETURN new;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- This trigger calls the function after a new user is inserted into auth.users.
|
||||||
|
DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
|
||||||
|
CREATE TRIGGER on_auth_user_created
|
||||||
|
AFTER INSERT ON auth.users
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
|
||||||
|
|
||||||
|
-- Remove the redundant password column from the public.usuarios table
|
||||||
|
-- as it is now securely managed by Supabase Auth.
|
||||||
|
ALTER TABLE public.usuarios
|
||||||
|
DROP COLUMN IF EXISTS senha;
|
||||||
Loading…
Reference in New Issue
Block a user