-
Hello Rigo!!
diff --git a/src/front/pages/PetDetail.jsx b/src/front/pages/PetDetail.jsx
new file mode 100644
index 0000000000..e6f6df6c77
--- /dev/null
+++ b/src/front/pages/PetDetail.jsx
@@ -0,0 +1,197 @@
+import React, { useState, useEffect } from "react";
+import { useParams, Link, useNavigate } from "react-router-dom";
+
+export const PetDetail = () => {
+ const { id } = useParams();
+ const navigate = useNavigate();
+ const backendUrl = import.meta.env.VITE_BACKEND_URL;
+
+ const [loading, setLoading] = useState(true);
+ const [pet, setPet] = useState({
+ name: "",
+ genre: "male",
+ birthDate: "",
+ castrated: false,
+ chipNumber: "",
+ color: "",
+ photoUrl: "",
+ size: "medium",
+ idUser: "",
+ idShelter: "",
+ idBreed: ""
+ });
+
+ useEffect(() => {
+ const fetchPetDetail = async () => {
+ try {
+ const response = await fetch(`${backendUrl}/api/pets/${id}`);
+ if (response.ok) {
+ const data = await response.json();
+ setPet({
+ ...data,
+ birthDate: data.birthDate || "",
+ chipNumber: data.chipNumber || "",
+ photoUrl: data.photoUrl || ""
+ });
+ }
+ } catch (error) {
+ console.error("Error fetching pet details:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchPetDetail();
+ }, [id, backendUrl]);
+
+ const handleChange = (e) => {
+ const { name, value, type, checked } = e.target;
+ setPet({
+ ...pet,
+ [name]: type === "checkbox" ? checked : value
+ });
+ };
+
+ const handleSave = async (e) => {
+ e.preventDefault();
+ try {
+ const response = await fetch(`${backendUrl}/api/pets/${id}`, {
+ method: "PUT",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(pet)
+ });
+
+ if (response.ok) {
+ alert("Pet updated successfully!");
+ navigate("/pets");
+ } else {
+ alert("Failed to update pet");
+ }
+ } catch (error) {
+ console.error("Error updating pet:", error);
+ }
+ };
+
+ if (loading) {
+ return (
+
+
Loading pet details...
+
+ );
+ }
+
+ return (
+
+
+ ← Back to Pets List
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/front/pages/PetView.jsx b/src/front/pages/PetView.jsx
new file mode 100644
index 0000000000..cba2678114
--- /dev/null
+++ b/src/front/pages/PetView.jsx
@@ -0,0 +1,82 @@
+import React, { useState, useEffect } from "react";
+import { useParams, Link } from "react-router-dom";
+
+export const PetView = () => {
+ const { id } = useParams();
+ const backendUrl = import.meta.env.VITE_BACKEND_URL;
+
+ const [loading, setLoading] = useState(true);
+ const [pet, setPet] = useState(null);
+
+ useEffect(() => {
+ const fetchPetDetail = async () => {
+ try {
+ const response = await fetch(`${backendUrl}/api/pets/${id}`);
+ if (response.ok) {
+ const data = await response.json();
+ setPet(data);
+ }
+ } catch (error) {
+ console.error("Error fetching pet details:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchPetDetail();
+ }, [id, backendUrl]);
+
+ if (loading) {
+ return (
+
+
Loading pet details...
+
+ );
+ }
+
+ if (!pet) {
+ return (
+
+
Pet not found.
+
+ ← Back to Pets List
+
+
+ );
+ }
+
+ return (
+
+
+ ← Back to Pets List
+
+
+
+
+ {pet.photoUrl && (
+
+

+
+ )}
+
+
+
{pet.name}
+
+
Gender: {pet.genre}
+
Size: {pet.size}
+
Color: {pet.color}
+
Birth Date: {pet.birthDate || "Not provided"}
+
Chip Number: {pet.chipNumber || "No chip"}
+
Castrated: {pet.castrated ? "Yes" : "No"}
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/front/pages/PetsList.jsx b/src/front/pages/PetsList.jsx
new file mode 100644
index 0000000000..12982a3a64
--- /dev/null
+++ b/src/front/pages/PetsList.jsx
@@ -0,0 +1,61 @@
+import React, { useState, useEffect } from "react";
+import { Link } from "react-router-dom";
+import { PetCard } from "../components/PetCard";
+
+export const PetsList = () => {
+ const [pets, setPets] = useState([]);
+ const backendUrl = import.meta.env.VITE_BACKEND_URL;
+
+ const fetchPets = async () => {
+ try {
+ const response = await fetch(`${backendUrl}/api/pets`);
+ if (response.ok) {
+ const data = await response.json();
+ setPets(data);
+ }
+ } catch (error) {
+ console.error("Error fetching pets:", error);
+ }
+ };
+
+ useEffect(() => {
+ fetchPets();
+ }, []);
+
+ const handleDelete = async (id) => {
+ if (!window.confirm("Are you sure you want to delete this pet?")) return;
+
+ try {
+ const response = await fetch(`${backendUrl}/api/pets/${id}`, {
+ method: "DELETE"
+ });
+
+ if (response.ok) {
+ fetchPets();
+ }
+ } catch (error) {
+ console.error("Error deleting pet:", error);
+ }
+ };
+
+ return (
+
+
+
Pets List
+
+ + Create Pet
+
+
+
+ {pets.length === 0 ? (
+
No pets registered yet.
+ ) : (
+
+ {pets.map((pet) => (
+
+ ))}
+
+ )}
+
+ );
+};
\ No newline at end of file
diff --git a/src/front/pages/Shelter.jsx b/src/front/pages/Shelter.jsx
new file mode 100644
index 0000000000..5dc7bf556d
--- /dev/null
+++ b/src/front/pages/Shelter.jsx
@@ -0,0 +1,71 @@
+import { Link, useActionData } from "react-router-dom";
+import { useEffect, useState } from "react";
+import rigoImageUrl from "../assets/img/rigo-baby.jpg";
+import useGlobalReducer from "../hooks/useGlobalReducer.jsx";
+import { CardShelter } from "../components/CardShelter.jsx";
+
+
+export const Shelter = () => {
+
+const [shelter, setShelter] = useState([]);
+ const backendUrl = import.meta.env.VITE_BACKEND_URL;
+
+ const fetchShelter = async () => {
+ try {
+ const response = await fetch(`${backendUrl}/api/shelter`);
+ if (response.ok) {
+ const data = await response.json();
+ setShelter(data);
+ }
+ } catch (error) {
+ console.error("Error fetching shelters:", error);
+ }
+ };
+
+const handleDeleteShelter = (id) => {
+ setShelter(prev => prev.filter(item => item.id !== id));
+};
+
+
+ useEffect(() => {
+ fetchShelter();
+ }, []);
+
+
+
+ return (
+ <>
+
+
+
+
Refugios
+
+ {shelter.map((shelter, index) => (
+
+
+
+
+ ))}
+
+
+
+
+
+
+ Back home
+
+
+ >
+ );
+};
\ No newline at end of file
diff --git a/src/front/pages/User.jsx b/src/front/pages/User.jsx
new file mode 100644
index 0000000000..c67873014d
--- /dev/null
+++ b/src/front/pages/User.jsx
@@ -0,0 +1,72 @@
+import { Link, useActionData } from "react-router-dom";
+import { useEffect, useState } from "react";
+import rigoImageUrl from "../assets/img/rigo-baby.jpg";
+import useGlobalReducer from "../hooks/useGlobalReducer.jsx";
+//import { Link } from "react-router-dom";
+import { CardUser } from "../components/CardUser.jsx";
+
+
+export const User = () => {
+
+const [user, setUser] = useState([]);
+ const backendUrl = import.meta.env.VITE_BACKEND_URL;
+
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`${backendUrl}/api/user`);
+ if (response.ok) {
+ const data = await response.json();
+ setUser(data);
+ }
+ } catch (error) {
+ console.error("Error fetching user:", error);
+ }
+ };
+
+const handleDeleteUser = (id) => {
+ setUser(prev => prev.filter(item => item.id !== id));
+};
+
+
+ useEffect(() => {
+ fetchUser();
+ }, []);
+
+
+
+ return (
+ <>
+
+
+
+
Usuarios
+
+ {user.map((user, index) => (
+
+
+
+
+ ))}
+
+
+
+
+
+
+ Back home
+
+
+ >
+ );
+};
\ No newline at end of file
diff --git a/src/front/routes.jsx b/src/front/routes.jsx
index 0557df6141..53de3dbc05 100644
--- a/src/front/routes.jsx
+++ b/src/front/routes.jsx
@@ -1,30 +1,50 @@
// Import necessary components and functions from react-router-dom.
import {
- createBrowserRouter,
- createRoutesFromElements,
- Route,
+ createBrowserRouter,
+ createRoutesFromElements,
+ Route,
} from "react-router-dom";
import { Layout } from "./pages/Layout";
-import { Home } from "./pages/Home";
+import Breed from "./pages/Breed";
+import CreateBreed from "./pages/CreateBreed";
+import EditBreed from "./pages/EditBreed";
import { Single } from "./pages/Single";
import { Demo } from "./pages/Demo";
+import { Form } from "./pages/Form";
+import { Shelter } from "./pages/Shelter";
+import { User } from "./pages/User";
+import { PetsList } from "./pages/PetsList";
+import { CreatePet } from "./pages/CreatePet";
+import { PetDetail } from "./pages/PetDetail";
+import { PetView } from "./pages/PetView";
export const router = createBrowserRouter(
- createRoutesFromElements(
+ createRoutesFromElements(
// CreateRoutesFromElements function allows you to build route elements declaratively.
// Create your routes here, if you want to keep the Navbar and Footer in all views, add your new routes inside the containing Route.
// Root, on the contrary, create a sister Route, if you have doubts, try it!
// Note: keep in mind that errorElement will be the default page when you don't get a route, customize that page to make your project more attractive.
// Note: The child paths of the Layout element replace the Outlet component with the elements contained in the "element" attribute of these child paths.
- // Root Route: All navigation will start from here.
-
} errorElement={
Not found!
} >
-
- {/* Nested Routes: Defines sub-routes within the BaseHome component. */}
-
} />
-
} /> {/* Dynamic route for single items */}
-
} />
-
- )
+ // Root Route: All navigation will start from here.
+
} errorElement={
Not found!
} >
+
} />
+
} />
+
} />
+
} />
+
} /> {/* Dynamic route for single items */}
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
} />
+
+ )
);
\ No newline at end of file
diff --git a/src/front/store.js b/src/front/store.js
index 3062cd222d..5a562dab8f 100644
--- a/src/front/store.js
+++ b/src/front/store.js
@@ -1,4 +1,4 @@
-export const initialStore=()=>{
+/* export const initialStore=()=>{
return{
message: null,
todos: [
@@ -14,7 +14,16 @@ export const initialStore=()=>{
}
]
}
-}
+} */
+
+
+export const initialStore = () => {
+ return {
+ shelters: [],
+
+ };
+};
+
export default function storeReducer(store, action = {}) {
switch(action.type){
@@ -32,7 +41,15 @@ export default function storeReducer(store, action = {}) {
...store,
todos: store.todos.map((todo) => (todo.id === id ? { ...todo, background: color } : todo))
};
+
+ case "load_data": {
+ const { nuevosShelters } = action.payload; //es la informacion que tu das para que se haga lo que haya en el case, por ejemplo un ID, que te permitirá hacer "algo"
+ return {
+ ...store,
+ shelters: nuevosShelters
+ };
+ }
default:
throw Error('Unknown action.');
}
-}
+}
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index a93495e81e..e925c421df 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,14 +1,19 @@
-import {
- defineConfig
-} from 'vite'
-import react from '@vitejs/plugin-react'
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
export default defineConfig({
- plugins: [react()],
- server: {
- port: 3000
+ plugins: [react()],
+ server: {
+ host: "0.0.0.0",
+ port: 3000,
+ proxy: {
+ "/api": {
+ target: "http://127.0.0.1:3001",
+ changeOrigin: true,
+ },
},
- build: {
- outDir: 'dist'
- }
-})
\ No newline at end of file
+ },
+ build: {
+ outDir: "dist",
+ },
+});