197 lines
6.6 KiB
TypeScript
197 lines
6.6 KiB
TypeScript
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;
|