fix: corrige tipagem do sistema de autenticação

- Adiciona tipos UserRole e WeakPassword
- Corrige tipagem do UserManagementPage
- Atualiza interface AuthContextType
- Melhora tratamento de erros no fetchUsers
- Adiciona tipagem explícita para User no filter
This commit is contained in:
Lucas Santana 2024-12-20 14:29:34 -03:00
parent 8e8936e9f4
commit eb77476d51
3 changed files with 70 additions and 39 deletions

View File

@ -1,13 +1,23 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { supabase } from '../lib/supabase' import { supabase } from '../lib/supabase'
import { User, Session } from '@supabase/supabase-js' import { User, Session } from '@supabase/supabase-js'
import type { WeakPassword } from '../types/supabase'
import { UserRole } from '../types/supabase'
interface AuthContextType { export interface AuthContextType {
user: User | null; user: User | null;
loading: boolean; loading: boolean;
error: string | null; error: string | null;
signIn: (email: string, password: string) => Promise<{ user: User; session: Session }>; userRole: UserRole | null;
signUp: (email: string, password: string) => Promise<{ user: User; session: Session }>; signIn: (email: string, password: string) => Promise<{
user: User;
session: Session;
weakPassword?: WeakPassword;
}>;
signUp: (email: string, password: string) => Promise<{
user: User;
session: Session;
}>;
signOut: () => Promise<void>; signOut: () => Promise<void>;
} }
@ -15,6 +25,7 @@ export function useAuth() {
const [user, setUser] = useState<User | null>(null) const [user, setUser] = useState<User | null>(null)
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
const [userRole, setUserRole] = useState<AuthContextType['userRole']>(null)
useEffect(() => { useEffect(() => {
// Verificar sessão atual // Verificar sessão atual
@ -31,6 +42,12 @@ export function useAuth() {
return () => subscription.unsubscribe() return () => subscription.unsubscribe()
}, []) }, [])
useEffect(() => {
if (user?.user_metadata?.role) {
setUserRole(user.user_metadata.role);
}
}, [user]);
const signIn = async (email: string, password: string) => { const signIn = async (email: string, password: string) => {
try { try {
const { data, error } = await supabase.auth.signInWithPassword({ const { data, error } = await supabase.auth.signInWithPassword({
@ -78,6 +95,7 @@ export function useAuth() {
user, user,
loading, loading,
error, error,
userRole,
signIn, signIn,
signUp, signUp,
signOut signOut

View File

@ -1,53 +1,45 @@
import React from 'react'; import React, { useState, useEffect } from 'react';
import { supabase } from '../../lib/supabase'; import { supabase } from '../../lib/supabase';
import { User, UserMetadata } from '@supabase/supabase-js'; import { User } from '@supabase/supabase-js';
import { UserMetadata } from '../../types/supabase';
interface AdminUserMetadata extends UserMetadata { interface AdminUser extends User {
role?: string; user_metadata: UserMetadata;
}
interface AdminUser extends Omit<User, 'user_metadata'> {
email: string;
user_metadata: AdminUserMetadata;
} }
export function UserManagementPage() { export function UserManagementPage() {
const [users, setUsers] = React.useState<AdminUser[]>([]); const [users, setUsers] = useState<AdminUser[]>([]);
const [loading, setLoading] = React.useState(true); const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState<string | null>(null); const [error, setError] = React.useState<string | null>(null);
const [updating, setUpdating] = React.useState<string | null>(null); const [updating, setUpdating] = React.useState<string | null>(null);
React.useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => { const fetchUsers = async () => {
try { try {
const { data: { users }, error } = await supabase.auth.admin.listUsers(); const { data: users, error } = await supabase.auth.admin.listUsers();
if (error) throw error;
const validUsers = users?.filter((user): user is AdminUser => if (error) {
typeof user.email === 'string' && setError(error.message);
user.email !== undefined && return;
user.user_metadata !== null
).map(user => ({
...user,
email: user.email!,
user_metadata: {
...user.user_metadata,
role: user.user_metadata?.role || ''
} }
})) || [];
const validUsers = users.filter((user: User) =>
user.user_metadata && user.user_metadata.role
) as AdminUser[];
setUsers(validUsers); setUsers(validUsers);
} catch (err) { } catch (err) {
console.error('Erro ao buscar usuários:', err); setError(err instanceof Error ? err.message : 'Erro ao carregar usuários');
setError('Não foi possível carregar os usuários');
} finally {
setLoading(false);
} }
}; };
useEffect(() => {
fetchUsers();
}, []);
const handleRefresh = async () => {
await fetchUsers();
};
const handleUpdateRole = async (userId: string, role: string) => { const handleUpdateRole = async (userId: string, role: string) => {
setUpdating(userId); setUpdating(userId);
try { try {

21
src/types/supabase.ts Normal file
View File

@ -0,0 +1,21 @@
export type UserRole = 'admin' | 'school' | 'teacher' | 'student';
export interface UserMetadata {
role: UserRole;
name: string;
school_id?: string;
class_id?: string;
}
export interface User {
id: string;
email: string;
user_metadata: UserMetadata;
created_at: string;
updated_at: string;
}
export interface WeakPassword {
message: string;
suggestions: string[];
}