Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 118 additions & 93 deletions src/pages/Adopter/AdopterList.tsx

Large diffs are not rendered by default.

161 changes: 112 additions & 49 deletions src/pages/Adoption/AdoptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { motion, AnimatePresence } from "framer-motion";
import { useAnimals } from "../../context/AnimalsContext";
import { deleteAdoptionById, getAdoptions, updateAdoption } from "../../services/adoptionService.ts";
import EditAdoptionForm from "../../Components/EditAdoptionForm/EditAdoptionForm.tsx";
import {getAdopters} from "../../services/adopterService.ts";
import {getStaff} from "../../services/staffService.ts";
import { getAdopters } from "../../services/adopterService.ts";
import { getStaff } from "../../services/staffService.ts";

export type Adoption = {
id: string;
Expand Down Expand Up @@ -37,6 +37,9 @@ export default function AdoptionList() {
const [searchTerm, setSearchTerm] = useState("");
const navigate = useNavigate();

const [currentPage, setCurrentPage] = useState(1);
const itemsPerPage = 8;

useEffect(() => {
const fetchAdoptions = async () => {
setLoading(true);
Expand Down Expand Up @@ -140,9 +143,32 @@ export default function AdoptionList() {
.some(field => field.toLowerCase().includes(searchTerm.toLowerCase()))
);

const totalPages = Math.max(1, Math.ceil(filteredAdoptions.length / itemsPerPage));
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = Math.min(filteredAdoptions.length, currentPage * itemsPerPage);
const paginatedAdoptions = filteredAdoptions.slice(startIndex, endIndex);

const getPageNumbers = () => Array.from({ length: totalPages }).map((_, i) => i + 1);

const goToPage = (page: number) => {
if (page < 1 || page > totalPages) return;
setCurrentPage(page);
window.scrollTo({ top: 0, behavior: "smooth" });
};
const prevPage = () => goToPage(currentPage - 1);
const nextPage = () => goToPage(currentPage + 1);

useEffect(() => {
const tp = Math.max(1, Math.ceil(filteredAdoptions.length / itemsPerPage));
if (currentPage > tp) setCurrentPage(tp);
}, [currentPage, filteredAdoptions.length]);

useEffect(() => {
setCurrentPage(1);
}, [searchTerm]);

return (
<div className="p-6 flex flex-col gap-6">
{/* Header */}
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
<h1 className="text-3xl font-bold text-gray-800">Adoções</h1>
<div className="flex items-center gap-3 w-full sm:w-auto">
Expand All @@ -161,67 +187,104 @@ export default function AdoptionList() {
</div>
</div>

{/* Lista */}
{loading ? (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{[...Array(6)].map((_, i) => (
{[...Array(itemsPerPage)].map((_, i) => (
<div key={i} className="rounded-2xl shadow-md bg-white overflow-hidden animate-pulse h-60"></div>
))}
</div>
) : filteredAdoptions.length === 0 ? (
<div className="text-center text-gray-500 py-20">Nenhuma adoção encontrada.</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{filteredAdoptions.map(a => {
const animalData = animals.find(an => an.id === a.animalId);
return (
<div key={a.id} className="rounded-2xl shadow-md hover:shadow-xl transition bg-white overflow-hidden group">
<div className="h-40 bg-gray-100 flex items-center justify-center relative">
{animalData?.image ? (
<img src={animalData.image} alt={a.animalName} className="w-full h-full object-cover" />
) : (
<span className="text-gray-400">Animal</span>
)}
<div className="absolute top-2 right-2 flex gap-2">
<>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{paginatedAdoptions.map(a => {
const animalData = animals.find(an => an.id === a.animalId);
return (
<div key={a.id} className="rounded-2xl shadow-md hover:shadow-xl transition bg-white overflow-hidden group">
<div className="h-40 bg-gray-100 flex items-center justify-center relative">
{animalData?.image ? (
<img src={animalData.image} alt={a.animalName} className="w-full h-full object-cover" />
) : (
<span className="text-gray-400">Animal</span>
)}
<div className="absolute top-2 right-2 flex gap-2">
<button
onClick={() => setDeleteAdoption(a)}
className="text-red-500 bg-white p-1 rounded-full hover:bg-red-50 transition"
>
<Trash2 size={16} />
</button>
</div>
</div>
<div className="p-4 flex flex-col gap-2">
<div className="flex justify-between items-center">
<h2 className="font-semibold text-gray-800 text-lg">{a.animalName}</h2>
<span
className={`text-xs px-2 py-1 rounded-full font-medium ${
a.status === "Adotado"
? "bg-green-100 text-green-600"
: a.status === "Devolvido"
? "bg-yellow-100 text-yellow-600"
: "bg-blue-100 text-blue-600"
}`}
>
{a.status}
</span>
</div>
<p className="text-sm text-gray-600">Adotante: {a.adopterName}</p>
<p className="text-sm text-gray-600">Responsável: {a.employeeName}</p>
<button
onClick={() => setDeleteAdoption(a)}
className="text-red-500 bg-white p-1 rounded-full hover:bg-red-50 transition"
onClick={() => setSelectedAdoption(a)}
className="w-full mt-2 px-3 py-2 border border-gray-200 rounded-xl hover:bg-gray-100 transition text-sm font-medium"
>
<Trash2 size={16} />
Ver detalhes
</button>
</div>
</div>
<div className="p-4 flex flex-col gap-2">
<div className="flex justify-between items-center">
<h2 className="font-semibold text-gray-800 text-lg">{a.animalName}</h2>
<span
className={`text-xs px-2 py-1 rounded-full font-medium ${
a.status === "Adotado"
? "bg-green-100 text-green-600"
: a.status === "Devolvido"
? "bg-yellow-100 text-yellow-600"
: "bg-blue-100 text-blue-600"
}`}
>
{a.status}
</span>
</div>
<p className="text-sm text-gray-600">Adotante: {a.adopterName}</p>
<p className="text-sm text-gray-600">Responsável: {a.employeeName}</p>
<button
onClick={() => setSelectedAdoption(a)}
className="w-full mt-2 px-3 py-2 border border-gray-200 rounded-xl hover:bg-gray-100 transition text-sm font-medium"
>
Ver detalhes
</button>
</div>
</div>
);
})}
</div>
);
})}
</div>

<div className="flex flex-col gap-5 items-center justify-between mt-6">
<div className="flex items-center gap-2">
<button
onClick={prevPage}
disabled={currentPage === 1}
aria-disabled={currentPage === 1}
className={`px-3 py-1 rounded-md border border-gray-300 ${currentPage === 1 ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-gray-100"}`}
>
Anterior
</button>

{getPageNumbers().map(n => (
<button
key={n}
onClick={() => goToPage(n)}
aria-current={n === currentPage ? "page" : undefined}
className={`px-3 py-1 rounded-md border ${n === currentPage ? "bg-blue-600 text-white border-blue-600" : "border-gray-300 hover:bg-gray-100"} cursor-pointer`}
>
{n}
</button>
))}

<button
onClick={nextPage}
disabled={currentPage === totalPages}
aria-disabled={currentPage === totalPages}
className={`px-3 py-1 rounded-md border border-gray-300 ${currentPage === totalPages ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-gray-100"}`}
>
Próxima
</button>
</div>

<div className="text-sm text-gray-600">
Mostrando {startIndex + 1}–{endIndex} de {filteredAdoptions.length}
</div>
</div>
</>
)}

{/* Modais */}
<AnimatePresence>
{selectedAdoption && (
<motion.div
Expand Down
1 change: 0 additions & 1 deletion src/pages/Animal/AnimalList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// src/pages/Animal/AnimalList.tsx
import React, { useState, useEffect } from "react";
import { Plus, X, Trash2 } from "lucide-react";
import { useNavigate } from "react-router-dom";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export default function AntiparasiticRegister() {
<motion.button
whileTap={{ scale: 0.95 }}
type="button"
onClick={() => navigate("/health-card")}
onClick={() => navigate("/HealthCardList")}
className="w-full sm:w-auto px-6 py-3 rounded-2xl bg-gray-600 text-white shadow hover:bg-gray-700 transition font-medium"
>
Carteiras de Saúde
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Health/DewormingRegister/DewormingRegister.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export default function DewormingRegister() {
<motion.button
whileTap={{ scale: 0.95 }}
type="button"
onClick={() => navigate("/health-card")}
onClick={() => navigate("/HealthCardList")}
className="w-full sm:w-auto px-6 py-3 rounded-2xl bg-gray-600 text-white shadow hover:bg-gray-700 transition font-medium"
>
Carteiras de Saúde
Expand Down
Loading