saveinmed/saveinmed-frontend/src/components/PagamentoForm.tsx
Tiago Yamamoto b39caf0fd0 first commit
2025-12-17 13:58:26 -03:00

197 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import { Models } from 'appwrite';
// Interface para dados do pagamento
interface PagamentoData {
pedidos: string;
status: 'pendente' | 'pago' | 'cancelado';
metodo: 'pix' | 'cartao';
valor: number;
}
interface PagamentoFormProps {
onSubmit: (data: PagamentoData) => Promise<boolean>;
onCancel?: () => void;
initialData?: PagamentoData | null;
loading?: boolean;
}
const statusOptions = ['pendente', 'pago', 'cancelado'];
const metodoOptions = ['pix', 'cartao'];
const PagamentoForm: React.FC<PagamentoFormProps> = ({
onSubmit,
onCancel,
initialData,
loading = false
}) => {
const [formData, setFormData] = useState<PagamentoData>({
pedidos: '',
status: 'pendente',
metodo: 'pix',
valor: 0
});
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
useEffect(() => {
if (initialData) {
setFormData({
pedidos: initialData.pedidos || '',
status: initialData.status || 'pendente',
metodo: initialData.metodo || 'pix',
valor: Number(initialData.valor) || 0
});
} else {
setFormData({ pedidos: '', status: 'pendente', metodo: 'pix', valor: 0 });
}
}, [initialData]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const success = await onSubmit(formData);
if (success) {
setMessage({
type: 'success',
text: initialData ? '🔄 Pagamento atualizado com sucesso!' : '🎉 Pagamento cadastrado com sucesso!'
});
if (!initialData) {
setFormData({ pedidos: '', status: 'pendente', metodo: 'pix', valor: 0 });
}
setTimeout(() => setMessage(null), 3000);
} else {
setMessage({
type: 'error',
text: initialData ? 'Erro ao atualizar pagamento' : 'Erro ao cadastrar pagamento'
});
}
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData((prev: PagamentoData) => ({ ...prev, [name]: name === 'valor' ? Number(value) : value }));
if (message) setMessage(null);
};
return (
<div className="bg-white rounded-lg shadow-md p-6">
<div className="mb-6">
<h2 className="text-2xl font-bold text-gray-900 mb-2">
{initialData ? '✏️ Editar Pagamento' : 'Novo Pagamento'}
</h2>
<p className="text-gray-600">
{initialData ? 'Atualize os dados do pagamento.' : 'Cadastre um novo pagamento.'}
</p>
</div>
{message && (
<div className={`mb-4 p-4 rounded-md ${
message.type === 'success' ? 'bg-green-50 text-green-700 border border-green-200' : 'bg-red-50 text-red-700 border border-red-200'
}`}>
{message.text}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label htmlFor="pedidos" className="block text-sm font-medium text-gray-700 mb-2">
Pedido ID *
</label>
<input
type="text"
id="pedidos"
name="pedidos"
value={formData.pedidos}
onChange={handleInputChange}
required
disabled={loading}
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed"
placeholder="ID do pedido"
/>
</div>
<div>
<label htmlFor="status" className="block text-sm font-medium text-gray-700 mb-2">
Status *
</label>
<select
id="status"
name="status"
value={formData.status}
onChange={handleInputChange}
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed"
disabled={loading}
>
{statusOptions.map(option => (
<option key={option} value={option}>{option}</option>
))}
</select>
</div>
<div>
<label htmlFor="metodo" className="block text-sm font-medium text-gray-700 mb-2">
Método *
</label>
<select
id="metodo"
name="metodo"
value={formData.metodo}
onChange={handleInputChange}
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed"
disabled={loading}
>
{metodoOptions.map(option => (
<option key={option} value={option}>{option}</option>
))}
</select>
</div>
<div>
<label htmlFor="valor" className="block text-sm font-medium text-gray-700 mb-2">
Valor (R$) *
</label>
<input
type="number"
step="0.01"
id="valor"
name="valor"
value={formData.valor}
onChange={handleInputChange}
required
disabled={loading}
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed"
placeholder="0,00"
/>
</div>
</div>
<div className="flex gap-4">
<button
type="submit"
disabled={loading}
className="flex-1 bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors cursor-pointer"
>
{loading ? '⏳ Processando...' : (initialData ? '🔄 Atualizar' : ' Cadastrar')}
</button>
{onCancel && (
<button
type="button"
onClick={onCancel}
disabled={loading}
className="flex-1 bg-gray-600 text-white py-2 px-4 rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors cursor-pointer"
>
Cancelar
</button>
)}
</div>
</form>
</div>
);
};
export default PagamentoForm;