Beta - Main
Descrição:
Título: Melhoria na experiência do usuário com notificações e layout responsivo
Descrição:
Este PR introduz várias melhorias significativas na experiência do usuário, focando em notificações mais amigáveis para dispositivos móveis e um layout mais responsivo para a tabela de transações. As principais alterações incluem:
- Implementação de um componente Toast personalizado para notificações móveis
- Atualização do hook
useTransactions
para usar o novo sistema de notificações - Criação de um modal personalizado para notificações de login/sessão expirada
- Melhoria no layout da tabela de transações para melhor visualização em dispositivos móveis
Detalhes das alterações:
- Novo componente Toast:
// components/ui/Toast.tsx
import { useState, useEffect } from 'react'
import { X } from 'lucide-react'
interface ToastProps {
message: string
type: 'success' | 'error' | 'warning'
duration?: number
onClose: () => void
}
export function Toast({ message, type, duration = 3000, onClose }: ToastProps) {
const [isVisible, setIsVisible] = useState(true)
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(false)
onClose()
}, duration)
return () => clearTimeout(timer)
}, [duration, onClose])
if (!isVisible) return null
const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-yellow-500'
return (
<div className={`fixed bottom-4 left-4 right-4 ${bgColor} text-white p-4 rounded-md shadow-lg flex justify-between items-center`}>
<p>{message}</p>
<button onClick={() => setIsVisible(false)} className="text-white">
<X size={20} />
</button>
</div>
)
}
- Atualização do hook
useTransactions
:
// hooks/useTransactions.ts
export function useTransactions() {
// ... (código existente)
const showToast = (message: string, type: 'success' | 'error' | 'warning') => {
setToast({ message, type })
}
// Exemplo de uso do novo sistema de notificações
const addTransaction = async (transaction: Partial<ITransaction>) => {
try {
const response = await fetch('/api/transactions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(transaction)
})
if (response.ok) {
await fetchTransactions()
showToast('Transação adicionada com sucesso!', 'success');
} else if (response.status === 401) {
handleAuthError();
} else {
showToast('Falha ao adicionar transação. Por favor, tente novamente.', 'error');
}
} catch (error) {
console.error('Error adding transaction:', error)
showToast('Ocorreu um erro ao adicionar a transação. Por favor, tente novamente.', 'error');
}
}
// ... (resto do código)
return {
transactions,
addTransaction,
editTransaction,
deleteTransaction,
getTransaction,
toast,
setToast
}
}
- Modal personalizado para notificações de login:
// Dentro do hook useTransactions
const handleAuthError = useCallback(() => {
const modal = document.createElement('div')
modal.innerHTML = `
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-white p-8 rounded-lg shadow-xl max-w-md w-full">
<img src="/logo.png" alt="Logo" class="mx-auto mb-4 w-24 h-24" />
<h2 class="text-2xl font-bold mb-4 text-center">Sessão Expirada</h2>
<p class="mb-6 text-center">Sua sessão expirou. Por favor, faça login novamente para continuar usando nossa plataforma.</p>
<div class="flex justify-center space-x-4">
<button id="loginBtn" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">Login</button>
<button id="registerBtn" class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">Cadastrar</button>
</div>
</div>
</div>
`
document.body.appendChild(modal)
// ... (código para lidar com os botões)
}, [router])
- Layout responsivo para a tabela de transações:
// components/TransactionsTable.tsx
export function TransactionsTable({ transactions, onEditTransaction, onDeleteTransaction }: TransactionsTableProps) {
// ... (código existente)
return (
<>
{/* Visão para desktop */}
<div className="hidden md:block">
<Table>
{/* ... (conteúdo da tabela para desktop) */}
</Table>
</div>
{/* Visão para mobile */}
<div className="md:hidden space-y-4">
{transactions.map((transaction) => (
<div key={transaction._id?.toString()} className={`p-4 rounded-lg shadow ${transaction.type === 'income' ? 'bg-green-50' : 'bg-red-50'}`}>
{/* ... (conteúdo do card para mobile) */}
</div>
))}
</div>
{/* ... (diálogos de edição e exclusão) */}
</>
)
}
Estas alterações visam melhorar significativamente a experiência do usuário, especialmente em dispositivos móveis, tornando as notificações menos intrusivas e a visualização de dados mais adequada para telas menores.