mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-17 05:47:52 +00:00
Adicionar User Role
This commit is contained in:
parent
c0aa725fa6
commit
4b431358e0
112
src/pages/admin/UserManagementPage.tsx
Normal file
112
src/pages/admin/UserManagementPage.tsx
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { supabase } from '../../lib/supabase';
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
user_metadata?: {
|
||||||
|
role?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserManagementPage() {
|
||||||
|
const [users, setUsers] = React.useState<User[]>([]);
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
|
const [error, setError] = React.useState<string | null>(null);
|
||||||
|
const [updating, setUpdating] = React.useState<string | null>(null);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
fetchUsers();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fetchUsers = async () => {
|
||||||
|
try {
|
||||||
|
const { data: { users }, error } = await supabase.auth.admin.listUsers();
|
||||||
|
if (error) throw error;
|
||||||
|
setUsers(users || []);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Erro ao buscar usuários:', err);
|
||||||
|
setError('Não foi possível carregar os usuários');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdateRole = async (userId: string, role: string) => {
|
||||||
|
setUpdating(userId);
|
||||||
|
try {
|
||||||
|
const { error } = await supabase.auth.admin.updateUserById(
|
||||||
|
userId,
|
||||||
|
{ user_metadata: { role } }
|
||||||
|
);
|
||||||
|
if (error) throw error;
|
||||||
|
await fetchUsers();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Erro ao atualizar papel:', err);
|
||||||
|
setError('Não foi possível atualizar o papel do usuário');
|
||||||
|
} finally {
|
||||||
|
setUpdating(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <div>Carregando...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-8">
|
||||||
|
<h1 className="text-2xl font-bold mb-6">Gerenciamento de Usuários</h1>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<div className="mb-4 p-4 bg-red-50 text-red-600 rounded-lg">
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="bg-white rounded-xl shadow-sm border border-gray-200">
|
||||||
|
<table className="min-w-full divide-y divide-gray-200">
|
||||||
|
<thead className="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Email
|
||||||
|
</th>
|
||||||
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Papel Atual
|
||||||
|
</th>
|
||||||
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Ações
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
|
{users.map((user) => (
|
||||||
|
<tr key={user.id}>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
{user.email}
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
||||||
|
{user.user_metadata?.role || 'Não definido'}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<select
|
||||||
|
value={user.user_metadata?.role || ''}
|
||||||
|
onChange={(e) => handleUpdateRole(user.id, e.target.value)}
|
||||||
|
disabled={updating === user.id}
|
||||||
|
className="mt-1 block w-full rounded-lg border-gray-300 shadow-sm focus:border-purple-500 focus:ring-purple-500"
|
||||||
|
>
|
||||||
|
<option value="">Selecione um papel</option>
|
||||||
|
<option value="school">Escola</option>
|
||||||
|
<option value="teacher">Professor</option>
|
||||||
|
<option value="student">Aluno</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
16
src/pages/api/updateRole.ts
Normal file
16
src/pages/api/updateRole.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { supabase } from '../../lib/supabase';
|
||||||
|
|
||||||
|
export async function updateRole(email: string, role: string) {
|
||||||
|
const { data: { user }, error } = await supabase.auth.admin.updateUserById(
|
||||||
|
email,
|
||||||
|
{
|
||||||
|
user_metadata: { role }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
14
src/pages/api/updateUserRole.ts
Normal file
14
src/pages/api/updateUserRole.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { supabase } from '../../lib/supabase';
|
||||||
|
|
||||||
|
export async function updateUserRole(userId: string, role: string) {
|
||||||
|
const { data, error } = await supabase.auth.admin.updateUserById(
|
||||||
|
userId,
|
||||||
|
{ user_metadata: { role: role } }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
33
src/scripts/updateUserRole.ts
Normal file
33
src/scripts/updateUserRole.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { createClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
|
const supabase = createClient(
|
||||||
|
'SUA_URL_DO_SUPABASE',
|
||||||
|
'SUA_ANON_KEY'
|
||||||
|
);
|
||||||
|
|
||||||
|
async function updateUserRole(email: string, role: 'school' | 'teacher' | 'student') {
|
||||||
|
try {
|
||||||
|
// Primeiro fazer login como o usuário
|
||||||
|
const { data: authData, error: authError } = await supabase.auth.signInWithPassword({
|
||||||
|
email: email,
|
||||||
|
password: 'SENHA_DO_USUARIO' // Substitua pela senha real
|
||||||
|
});
|
||||||
|
|
||||||
|
if (authError) throw authError;
|
||||||
|
|
||||||
|
// Depois atualizar os metadados
|
||||||
|
const { data, error } = await supabase.auth.updateUser({
|
||||||
|
data: { role: role }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
console.log('Papel do usuário atualizado com sucesso:', data);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Erro ao atualizar papel do usuário:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exemplo de uso:
|
||||||
|
updateUserRole('email@escola.com', 'school');
|
||||||
20
src/utils/updateUserRole.ts
Normal file
20
src/utils/updateUserRole.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { supabase } from '../lib/supabase';
|
||||||
|
|
||||||
|
export async function updateUserRole(userId: string, role: 'school' | 'teacher' | 'student') {
|
||||||
|
try {
|
||||||
|
const { data, error } = await supabase.auth.updateUser({
|
||||||
|
data: { role }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
console.log('Role atualizado com sucesso:', data);
|
||||||
|
return data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Erro ao atualizar role:', err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uso:
|
||||||
|
// await updateUserRole('id-do-usuario', 'school');
|
||||||
Loading…
Reference in New Issue
Block a user