From beef3da64724c4ffa78f2e3bc6eed0ebc0b331c9 Mon Sep 17 00:00:00 2001 From: Lucas Santana Date: Fri, 20 Dec 2024 11:42:59 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20adiciona=20gera=C3=A7=C3=A3o=20de=20sen?= =?UTF-8?q?ha=20mnem=C3=B4nica=20no=20cadastro=20de=20alunos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implementa gerador de senhas mnemônicas (cor + animal + número) - Adiciona campo de senha com opção de copiar e regenerar - Remove geração de senha temporária aleatória - Integra senha mnemônica com envio de email - Adiciona feedback visual ao copiar senha --- .../dashboard/students/AddStudentPage.tsx | 83 +++++++++++++++---- src/pages/student-dashboard/index.ts | 5 ++ src/utils/passwordGenerator.ts | 12 +++ 3 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 src/pages/student-dashboard/index.ts create mode 100644 src/utils/passwordGenerator.ts diff --git a/src/pages/dashboard/students/AddStudentPage.tsx b/src/pages/dashboard/students/AddStudentPage.tsx index f5a98d9..f6d85a7 100644 --- a/src/pages/dashboard/students/AddStudentPage.tsx +++ b/src/pages/dashboard/students/AddStudentPage.tsx @@ -1,9 +1,10 @@ import React from 'react'; import { useNavigate } from 'react-router-dom'; -import { ArrowLeft } from 'lucide-react'; +import { ArrowLeft, Copy, RefreshCw } from 'lucide-react'; import { useDatabase } from '../../../hooks/useDatabase'; import { supabase } from '../../../lib/supabase'; import { sendStudentCredentialsEmail } from '../../../services/email'; +import { generateMnemonicPassword } from '../../../utils/passwordGenerator'; interface Class { id: string; @@ -22,8 +23,10 @@ export function AddStudentPage() { guardian_name: '', guardian_email: '', guardian_phone: '', + password: generateMnemonicPassword() }); const [formError, setFormError] = React.useState(null); + const [successMessage, setSuccessMessage] = React.useState(null); const [isLoading, setIsLoading] = React.useState(false); React.useEffect(() => { @@ -56,6 +59,23 @@ export function AddStudentPage() { fetchClasses(); }, []); + const handleRegeneratePassword = () => { + setFormData(prev => ({ + ...prev, + password: generateMnemonicPassword() + })); + }; + + const handleCopyPassword = async () => { + try { + await navigator.clipboard.writeText(formData.password); + setSuccessMessage('Senha copiada!'); + setTimeout(() => setSuccessMessage(null), 2000); + } catch (err) { + console.error('Erro ao copiar senha:', err); + } + }; + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); @@ -75,13 +95,10 @@ export function AddStudentPage() { if (schoolError) throw schoolError; - // Gerar senha temporária - const tempPassword = generateTempPassword(); - - // Criar usuário para o aluno + // Criar usuário para o aluno com a senha mnemônica const { data: userData, error: userError } = await supabase.auth.signUp({ email: formData.email, - password: tempPassword, + password: formData.password, options: { data: { role: 'student', @@ -116,7 +133,7 @@ export function AddStudentPage() { const emailSent = await sendStudentCredentialsEmail({ studentName: formData.name, studentEmail: formData.email, - password: tempPassword, + password: formData.password, guardianName: formData.guardian_name, guardianEmail: formData.guardian_email }); @@ -186,6 +203,47 @@ export function AddStudentPage() { /> +
+ +
+
+ + +
+ +
+

+ Senha gerada automaticamente para fácil memorização +

+
+ + {successMessage && ( +
+ {successMessage} +
+ )} +
); -} - -// Função auxiliar para gerar senha temporária -function generateTempPassword() { - const length = 12; - const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*'; - let password = ''; - for (let i = 0; i < length; i++) { - password += charset.charAt(Math.floor(Math.random() * charset.length)); - } - return password; } \ No newline at end of file diff --git a/src/pages/student-dashboard/index.ts b/src/pages/student-dashboard/index.ts new file mode 100644 index 0000000..d74fcf6 --- /dev/null +++ b/src/pages/student-dashboard/index.ts @@ -0,0 +1,5 @@ +export { StudentDashboardLayout } from './StudentDashboardLayout'; +export { StudentDashboardPage } from './StudentDashboardPage'; +export { StudentStoriesPage } from './StudentStoriesPage'; +export { CreateStoryPage } from './CreateStoryPage'; +export { StoryPage } from './StoryPage'; \ No newline at end of file diff --git a/src/utils/passwordGenerator.ts b/src/utils/passwordGenerator.ts new file mode 100644 index 0000000..a21e63b --- /dev/null +++ b/src/utils/passwordGenerator.ts @@ -0,0 +1,12 @@ +const ANIMALS = ['leao', 'tigre', 'gato', 'cao', 'panda', 'urso', 'lobo', 'rato', 'sapo', 'peixe']; +const COLORS = ['azul', 'verde', 'rosa', 'roxo', 'ouro', 'prata', 'coral', 'jade', 'ruby', 'safira']; +const NUMBERS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; + +export function generateMnemonicPassword(): string { + const randomAnimal = ANIMALS[Math.floor(Math.random() * ANIMALS.length)]; + const randomColor = COLORS[Math.floor(Math.random() * COLORS.length)]; + const randomNumber = NUMBERS[Math.floor(Math.random() * NUMBERS.length)] + + NUMBERS[Math.floor(Math.random() * NUMBERS.length)]; + + return `${randomColor}${randomAnimal}${randomNumber}`; +} \ No newline at end of file