forked from RiseUP/riseup-squad20
Remove Magic Link client UI and helpers; keep email+password login
This commit is contained in:
parent
7b4353ef7b
commit
fbc7c46f4d
@ -3,7 +3,6 @@ import { useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Link from 'next/link'
|
||||
import { useAuth } from '@/hooks/useAuth'
|
||||
import { sendMagicLink } from '@/lib/api'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
@ -13,9 +12,7 @@ import { AuthenticationError } from '@/lib/auth'
|
||||
export default function LoginAdminPage() {
|
||||
const [credentials, setCredentials] = useState({ email: '', password: '' })
|
||||
const [error, setError] = useState('')
|
||||
const [magicMessage, setMagicMessage] = useState('')
|
||||
const [magicError, setMagicError] = useState('')
|
||||
const [magicLoading, setMagicLoading] = useState(false)
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const { login } = useAuth()
|
||||
@ -48,26 +45,7 @@ export default function LoginAdminPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleSendMagicLink = async () => {
|
||||
if (!credentials.email) {
|
||||
setMagicError('Por favor, preencha o email antes de solicitar o magic link.')
|
||||
return
|
||||
}
|
||||
|
||||
setMagicLoading(true)
|
||||
setMagicError('')
|
||||
setMagicMessage('')
|
||||
|
||||
try {
|
||||
const res = await sendMagicLink(credentials.email, { target: 'admin' })
|
||||
setMagicMessage(res?.message ?? 'Magic link enviado. Verifique seu email.')
|
||||
} catch (err: any) {
|
||||
console.error('[MAGIC-LINK ADMIN] erro ao enviar:', err)
|
||||
setMagicError(err?.message ?? String(err))
|
||||
} finally {
|
||||
setMagicLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-background py-12 px-4 sm:px-6 lg:px-8">
|
||||
@ -133,25 +111,7 @@ export default function LoginAdminPage() {
|
||||
{loading ? 'Entrando...' : 'Entrar no Sistema Administrativo'}
|
||||
</Button>
|
||||
</form>
|
||||
<div className="mt-4 space-y-2">
|
||||
<div className="text-sm text-muted-foreground mb-2">Ou entre usando um magic link (sem senha)</div>
|
||||
|
||||
{magicError && (
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>{magicError}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{magicMessage && (
|
||||
<Alert>
|
||||
<AlertDescription>{magicMessage}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Button className="w-full" onClick={handleSendMagicLink} disabled={magicLoading}>
|
||||
{magicLoading ? 'Enviando magic link...' : 'Enviar magic link'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="mt-4 text-center">
|
||||
<Button variant="outline" asChild className="w-full hover:bg-primary! hover:text-white! hover:border-primary! transition-all duration-200">
|
||||
|
||||
@ -3,7 +3,6 @@ import { useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Link from 'next/link'
|
||||
import { useAuth } from '@/hooks/useAuth'
|
||||
import { sendMagicLink } from '@/lib/api'
|
||||
import { ENV_CONFIG } from '@/lib/env-config'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
@ -14,9 +13,7 @@ import { AuthenticationError } from '@/lib/auth'
|
||||
export default function LoginPacientePage() {
|
||||
const [credentials, setCredentials] = useState({ email: '', password: '' })
|
||||
const [error, setError] = useState('')
|
||||
const [magicMessage, setMagicMessage] = useState('')
|
||||
const [magicError, setMagicError] = useState('')
|
||||
const [magicLoading, setMagicLoading] = useState(false)
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const { login } = useAuth()
|
||||
@ -56,26 +53,7 @@ export default function LoginPacientePage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleSendMagicLink = async () => {
|
||||
if (!credentials.email) {
|
||||
setMagicError('Por favor, preencha o email antes de solicitar o magic link.')
|
||||
return
|
||||
}
|
||||
|
||||
setMagicLoading(true)
|
||||
setMagicError('')
|
||||
setMagicMessage('')
|
||||
|
||||
try {
|
||||
const res = await sendMagicLink(credentials.email, { target: 'paciente' })
|
||||
setMagicMessage(res?.message ?? 'Magic link enviado. Verifique seu email.')
|
||||
} catch (err: any) {
|
||||
console.error('[MAGIC-LINK PACIENTE] erro ao enviar:', err)
|
||||
setMagicError(err?.message ?? String(err))
|
||||
} finally {
|
||||
setMagicLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Auto-cadastro (client-side) ---
|
||||
const [showRegister, setShowRegister] = useState(false)
|
||||
@ -219,25 +197,7 @@ export default function LoginPacientePage() {
|
||||
{loading ? 'Entrando...' : 'Entrar na Minha Área'}
|
||||
</Button>
|
||||
</form>
|
||||
<div className="mt-4 space-y-2">
|
||||
<div className="text-sm text-muted-foreground mb-2">Ou entre usando um magic link (sem senha)</div>
|
||||
|
||||
{magicError && (
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>{magicError}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{magicMessage && (
|
||||
<Alert>
|
||||
<AlertDescription>{magicMessage}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Button className="w-full" onClick={handleSendMagicLink} disabled={magicLoading}>
|
||||
{magicLoading ? 'Enviando magic link...' : 'Enviar magic link'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="mt-4 text-center">
|
||||
<Button variant="outline" asChild className="w-full hover:bg-primary! hover:text-white! hover:border-primary! transition-all duration-200">
|
||||
|
||||
@ -3,7 +3,6 @@ import { useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import Link from 'next/link'
|
||||
import { useAuth } from '@/hooks/useAuth'
|
||||
import { sendMagicLink } from '@/lib/api'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
@ -13,9 +12,7 @@ import { AuthenticationError } from '@/lib/auth'
|
||||
export default function LoginPage() {
|
||||
const [credentials, setCredentials] = useState({ email: '', password: '' })
|
||||
const [error, setError] = useState('')
|
||||
const [magicMessage, setMagicMessage] = useState('')
|
||||
const [magicError, setMagicError] = useState('')
|
||||
const [magicLoading, setMagicLoading] = useState(false)
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const { login } = useAuth()
|
||||
@ -57,27 +54,7 @@ export default function LoginPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleSendMagicLink = async () => {
|
||||
// basic client-side validation
|
||||
if (!credentials.email) {
|
||||
setMagicError('Por favor, preencha o email antes de solicitar o magic link.')
|
||||
return
|
||||
}
|
||||
|
||||
setMagicLoading(true)
|
||||
setMagicError('')
|
||||
setMagicMessage('')
|
||||
|
||||
try {
|
||||
const res = await sendMagicLink(credentials.email, { target: 'medico' })
|
||||
setMagicMessage(res?.message ?? 'Magic link enviado. Verifique seu email.')
|
||||
} catch (err: any) {
|
||||
console.error('[MAGIC-LINK] erro ao enviar:', err)
|
||||
setMagicError(err?.message ?? String(err))
|
||||
} finally {
|
||||
setMagicLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-background py-12 px-4 sm:px-6 lg:px-8">
|
||||
@ -143,25 +120,7 @@ export default function LoginPage() {
|
||||
{loading ? 'Entrando...' : 'Entrar'}
|
||||
</Button>
|
||||
</form>
|
||||
<div className="mt-4 space-y-2">
|
||||
<div className="text-sm text-muted-foreground mb-2">Ou entre usando um magic link (sem senha)</div>
|
||||
|
||||
{magicError && (
|
||||
<Alert variant="destructive">
|
||||
<AlertDescription>{magicError}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{magicMessage && (
|
||||
<Alert>
|
||||
<AlertDescription>{magicMessage}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Button className="w-full" onClick={handleSendMagicLink} disabled={magicLoading}>
|
||||
{magicLoading ? 'Enviando magic link...' : 'Enviar magic link'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="mt-4 text-center">
|
||||
<Button variant="outline" asChild className="w-full hover:bg-primary! hover:text-white! hover:border-primary! transition-all duration-200">
|
||||
|
||||
@ -182,7 +182,7 @@ const ProfissionalPage = () => {
|
||||
const q = `doctor_id=eq.${encodeURIComponent(String(resolvedDoctorId))}&select=patient_id&limit=200`;
|
||||
const appts = await listarAgendamentos(q).catch(() => []);
|
||||
for (const a of (appts || [])) {
|
||||
const pid = a.patient_id ?? a.patient ?? a.patient_id_raw ?? null;
|
||||
const pid = a.patient_id ?? (a as any).patient ?? (a as any).patient_id_raw ?? null;
|
||||
if (pid) patientIdSet.add(String(pid));
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@ -2474,7 +2474,7 @@ export type CreateUserInput = {
|
||||
full_name: string;
|
||||
phone?: string | null;
|
||||
role: UserRoleEnum;
|
||||
// Optional: when provided, backend can use this to send magic links that redirect
|
||||
// Optional: when provided, backend can use this to perform a redirect
|
||||
// to the given URL or interpret `target` to build a role-specific redirect.
|
||||
emailRedirectTo?: string;
|
||||
// Compatibility: some integrations expect `redirect_url` as the parameter name
|
||||
@ -2616,11 +2616,11 @@ export async function criarUsuarioDirectAuth(input: {
|
||||
// Try several common locations for the returned user id depending on Supabase configuration
|
||||
const userId = responseData?.user?.id || responseData?.id || responseData?.data?.user?.id || responseData?.data?.id;
|
||||
|
||||
// If no user id was returned, treat this as a failure. Some Supabase setups (e.g. magic link / invite)
|
||||
// may not return the user id immediately. In that case we cannot safely link the profile to a user.
|
||||
// If no user id was returned, treat this as a failure. Some Supabase setups (for example invite-only flows)
|
||||
// may not return the user id immediately. In that case we cannot safely link the profile to a user.
|
||||
if (!userId) {
|
||||
console.warn('[DIRECT AUTH] signup response did not include a user id; response:', responseData);
|
||||
throw new Error('Signup did not return a user id (provider may be configured for magic links or pending confirmation). Fallback cannot determine created user id.');
|
||||
throw new Error('Signup did not return a user id (provider may be configured for invite or pending-confirmation flows). Fallback cannot determine created user id.');
|
||||
}
|
||||
|
||||
console.log('[DIRECT AUTH] Usuário criado:', userId);
|
||||
@ -2657,8 +2657,8 @@ export async function criarUsuarioDirectAuth(input: {
|
||||
export async function criarUsuarioMedico(medico: { email: string; full_name: string; phone_mobile: string; }): Promise<any> {
|
||||
const redirectBase = DEFAULT_LANDING;
|
||||
const emailRedirectTo = `${redirectBase.replace(/\/$/, '')}/profissional`;
|
||||
// Use the role-specific landing as the redirect_url so the magic link
|
||||
// redirects users directly to the app path (e.g. /profissional).
|
||||
// Use the role-specific landing as the redirect_url so the server-side
|
||||
// flow redirects users directly to the app path (e.g. /profissional).
|
||||
const redirect_url = emailRedirectTo;
|
||||
// generate a secure-ish random password on the client so the caller can receive it
|
||||
const password = gerarSenhaAleatoria();
|
||||
@ -2711,46 +2711,7 @@ export async function criarUsuarioPaciente(paciente: { email: string; full_name:
|
||||
}
|
||||
|
||||
|
||||
export async function sendMagicLink(
|
||||
email: string,
|
||||
options?: { emailRedirectTo?: string; target?: 'paciente' | 'medico' | 'admin' | 'default'; redirectBase?: string }
|
||||
): Promise<{ success: boolean; message?: string }> {
|
||||
if (!email) throw new Error('Email obrigatório para enviar magic link');
|
||||
const url = `${API_BASE}/auth/v1/otp`;
|
||||
const payload: any = { email };
|
||||
|
||||
const redirectUrl = buildRedirectUrl(options?.target, options?.emailRedirectTo, options?.redirectBase);
|
||||
if (redirectUrl) {
|
||||
// include both keys for broader compatibility across different Supabase setups
|
||||
payload.options = { emailRedirectTo: redirectUrl, redirect_to: redirectUrl, redirect_url: redirectUrl };
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
apikey: ENV_CONFIG.SUPABASE_ANON_KEY,
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const text = await res.text();
|
||||
let json: any = null;
|
||||
try { json = text ? JSON.parse(text) : null; } catch { json = null; }
|
||||
|
||||
if (!res.ok) {
|
||||
const msg = (json && (json.error || json.msg || json.message)) ?? text ?? res.statusText;
|
||||
throw new Error(String(msg));
|
||||
}
|
||||
|
||||
return { success: true, message: (json && (json.message || json.msg)) ?? 'Magic link enviado. Verifique seu email.' };
|
||||
} catch (err: any) {
|
||||
console.error('[sendMagicLink] erro ao enviar magic link', err);
|
||||
throw new Error(err?.message ?? 'Falha ao enviar magic link');
|
||||
}
|
||||
}
|
||||
|
||||
// ===== CEP (usado nos formulários) =====
|
||||
export async function buscarCepAPI(cep: string): Promise<{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user