"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Alert, AlertDescription } from "@/components/ui/alert" import { Badge } from "@/components/ui/badge" import { Textarea } from "@/components/ui/textarea" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { Edit2, Plus, Save, X, Loader2, RefreshCw, History } from "lucide-react" // Usar as variáveis de ambiente para as URLs const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000/api/v1" interface PriceHistory { startDate: string endDate: string | null price: number } interface Product { _id: string name: string description: string priceHistory: PriceHistory[] createdAt: string updatedAt: string __v: number } interface ProductsResponse { msg: string products: Product[] } interface CreateProductRequest { name: string description: string price: number } interface UpdateProductRequest { name?: string description?: string price?: number } export default function ProductManagement() { const [products, setProducts] = useState([]) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState("") const [success, setSuccess] = useState("") // Estados para criação de produto const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false) const [isCreating, setIsCreating] = useState(false) const [createForm, setCreateForm] = useState({ name: "", description: "", price: 0, }) // Estados para edição de produto const [editingId, setEditingId] = useState(null) const [editForm, setEditForm] = useState({ name: "", description: "", price: 0, }) const [isUpdating, setIsUpdating] = useState(false) // Estados para histórico de preços const [historyDialogOpen, setHistoryDialogOpen] = useState(false) const [selectedProduct, setSelectedProduct] = useState(null) const getAuthHeaders = () => { const token = localStorage.getItem("access_token") return { Authorization: `Bearer ${token}`, "Content-Type": "application/json", } } const fetchProducts = async () => { setIsLoading(true) setError("") try { const response = await fetch(`${API_BASE_URL}/billing/products`, { method: "GET", headers: getAuthHeaders(), }) if (response.ok) { const result: ProductsResponse = await response.json() setProducts(result.products || []) } else { const errorData = await response.json() // Para erro 400, exibir a mensagem específica da API if (response.status === 400 && errorData.msg) { setError(errorData.msg) } else { setError(errorData.message || errorData.msg || "Erro ao buscar produtos") } } } catch (err) { console.log(err) setError("Erro de conexão com o servidor") } finally { setIsLoading(false) } } const createProduct = async () => { if (!createForm.name || !createForm.description || createForm.price <= 0) { setError("Preencha todos os campos corretamente") return } setIsCreating(true) setError("") setSuccess("") try { const response = await fetch(`${API_BASE_URL}/billing/product`, { method: "POST", headers: getAuthHeaders(), body: JSON.stringify(createForm), }) if (response.ok) { setSuccess("Produto criado com sucesso!") setCreateForm({ name: "", description: "", price: 0 }) setIsCreateDialogOpen(false) await fetchProducts() } else { const errorData = await response.json() // Para erro 400, exibir a mensagem específica da API if (response.status === 400 && errorData.msg) { setError(errorData.msg) } else { setError(errorData.message || errorData.msg || "Erro ao criar produto") } } } catch (err) { console.log(err) setError("Erro de conexão com o servidor") } finally { setIsCreating(false) } } const updateProduct = async (productId: string) => { // Verificar se há pelo menos um campo para atualizar if (Object.keys(editForm).length === 0) { setError("Nenhuma alteração para salvar") return } // Se o preço estiver definido, verificar se é válido if (editForm.price !== undefined && (isNaN(editForm.price) || editForm.price <= 0)) { setError("Digite um preço válido") return } setIsUpdating(true) setError("") setSuccess("") try { const response = await fetch(`${API_BASE_URL}/billing/product/${productId}`, { method: "PATCH", headers: getAuthHeaders(), body: JSON.stringify(editForm), }) if (response.ok) { setSuccess("Produto atualizado com sucesso!") setEditingId(null) setEditForm({}) await fetchProducts() } else { const errorData = await response.json() // Para erro 400, exibir a mensagem específica da API if (response.status === 400 && errorData.msg) { setError(errorData.msg) } else { setError(errorData.message || errorData.msg || "Erro ao atualizar produto") } } } catch (err) { console.log(err) setError("Erro de conexão com o servidor") } finally { setIsUpdating(false) } } const startEdit = (product: Product) => { setEditingId(product._id) const currentPrice = getCurrentPrice(product) setEditForm({ name: product.name, description: product.description, price: currentPrice, }) } const cancelEdit = () => { setEditingId(null) setEditForm({}) } const getCurrentPrice = (product: Product): number => { return product.priceHistory.find((p) => p.endDate === null)?.price || 0 } const formatDate = (dateString: string): string => { return new Date(dateString).toLocaleString("pt-BR") } const formatDateCompact = (dateString: string): string => { const date = new Date(dateString) return `${date.getDate().toString().padStart(2, "0")}/${(date.getMonth() + 1).toString().padStart(2, "0")}/${date.getFullYear()}, ${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")}` } const showHistory = (product: Product) => { setSelectedProduct(product) setHistoryDialogOpen(true) } useEffect(() => { fetchProducts() }, []) return (
{/* Cabeçalho com botão de criar */}

Produtos Cadastrados

Gerencie produtos e seus preços

Criar Novo Produto Preencha as informações do novo produto
setCreateForm((prev) => ({ ...prev, name: e.target.value }))} placeholder="Ex: Produto HIT" />