Skip to content

First commit #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion src/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export const Footer = () => (
<footer className="footer mt-auto py-3 text-center">
<p>
Check the <a target="_blank" href="https://4geeks.com/docs/start/start-react-advanced-project">template documentation</a> <i class="fa-solid fa-file"></i> for help.
Check the <a target="_blank" href="https://4geeks.com/docs/start/start-react-advanced-project">template documentation</a> <i className="fa-solid fa-file"></i> for help.
</p>
<p>
Made with <i className="fa fa-heart text-danger" /> by{" "}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export const Navbar = () => {
<nav className="navbar navbar-light bg-light">
<div className="container">
<Link to="/">
<span className="navbar-brand mb-0 h1">React Boilerplate</span>
<span className="navbar-brand mb-0 h1">Agenda</span>
</Link>
<div className="ml-auto">
<Link to="/demo">
<button className="btn btn-primary">Check the Context in action</button>
<button className="btn btn-primary">Agregar Contactos</button>
</Link>
</div>
</div>
Expand Down
34 changes: 34 additions & 0 deletions src/components/card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import rigobaby from "../assets/img/rigo-baby.jpg"
export const Card = ({ id, name, address, phone, email,onDelete,onEdit }) => {

return (
<div className="card mb-3" style={{ maxWidth: "540px" }}>
<div className="row g-0">
<div className="col-md-4 p-3">
<img src={rigobaby} className="img-fluid rounded-start" alt={name} />
</div>
<div className="col-md-8">
<div className="card-body">
<div className="d-flex justify-content-between">


<h1 className="card-title">{name}</h1>
<div>
<button type="button" className="btn btn-outline-info me-2" onClick={()=>onEdit()} data-bs-toggle="modal" data-bs-target="#exampleModalEdit">
<i className="fa fa-pen"></i>
</button>
<button type="button" className="btn btn-outline-danger me-2"
onClick={()=>onDelete()} data-bs-toggle="modal" data-bs-target="#exampleModal">
<i className="fa fa-trash"></i>
</button>
</div>
</div>
<p className="card-text">📍Address: {address}</p>
<p className="card-text">☎️ Phone: {phone}</p>
<p className="card-text">📧 E-Mail: {email}</p>
</div>
</div>
</div>
</div>
)
}
26 changes: 26 additions & 0 deletions src/components/modalDelete.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import useGlobalReducer from "../hooks/useGlobalReducer"
import { borrarContacto } from "../store"

export const ModalDelete = ({ id, name }) => {
const { store, dispatch } = useGlobalReducer()

return (
<div className="modal fade" id="exampleModal" tabIndex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalLabel">Eliminar Contacto</h1>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
Estas seguro que desea borrar a {name} de contactos?
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">cancelar</button>
<button type="button" className="btn btn-danger" data-bs-dismiss="modal" onClick={() => borrarContacto(dispatch, id)}>borrar</button>
</div>
</div>
</div>
</div>
)
}
91 changes: 91 additions & 0 deletions src/components/modalEdite.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import useGlobalReducer from "../hooks/useGlobalReducer"
import { editarContacto } from "../store"
import { useEffect, useState } from "react"

export const ModalEdit = ({ id, contact }) => {
const { store, dispatch } = useGlobalReducer()
const [nombre, setNombre] = useState("")
const [direccion, setDireccion] = useState("")
const [mail, setMail] = useState("")
const [telefono, setTelefono] = useState("")

const editar = (e) => {
e.preventDefault()
if (nombre == "") {
alert("Debe ingresar nombre completo")
return
}
if (mail == "") {
alert("Debe ingresar E-mail")
return
}
if (direccion == "") {
alert("Debe ingresar direccion")
return
}
if (telefono == "") {
alert("Debe ingresar numero de telefono")
return
}
const newContact = {
"name": nombre,
"phone": telefono,
"email": mail,
"address": direccion,
}
editarContacto(dispatch, newContact, id)
setNombre("")
setTelefono("")
setDireccion("")
setMail("")
}

const infoContact = () => {
setNombre(contact?.name)
setTelefono(contact?.phone)
setDireccion(contact?.address)
setMail(contact?.mail)
}

useEffect(() => {
infoContact()
}, [])

return (
<div className="modal fade" id="exampleModalEdit" tabIndex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalLabel">Editar Contacto</h1>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">Nombre Completo</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={nombre} onChange={(e) => setNombre(e.target.value)} />
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">Numero de telefono</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={telefono} onChange={(e) => setTelefono(e.target.value)} />
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">E-mail</span>
<input type="mail" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={mail} onChange={(e) => setMail(e.target.value)} />
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">direccion</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={direccion} onChange={(e) => setDireccion(e.target.value)} />
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">cancelar</button>
<button type="button" className="btn btn-success" data-bs-dismiss="modal"
onClick={(e)=>editar(e)}
>editar
</button>
</div>
</div>
</div>
</div>
)
}
93 changes: 61 additions & 32 deletions src/pages/Demo.jsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,72 @@
// Import necessary components from react-router-dom and other parts of the application.
import { Link } from "react-router-dom";
import useGlobalReducer from "../hooks/useGlobalReducer"; // Custom hook for accessing the global state.
import { useState } from "react";
import { crearContacto } from "../store";

export const Demo = () => {
// Access the global state and dispatch function using the useGlobalReducer hook.
const { store, dispatch } = useGlobalReducer()

return (
<div className="container">
<ul className="list-group">
{/* Map over the 'todos' array from the store and render each item as a list element */}
{store && store.todos?.map((item) => {
return (
<li
key={item.id} // React key for list items.
className="list-group-item d-flex justify-content-between"
style={{ background: item.background }}>

{/* Link to the detail page of this todo. */}
<Link to={"/single/" + item.id}>Link to: {item.title} </Link>

<p>Open file ./store.js to see the global store that contains and updates the list of colors</p>

<button className="btn btn-success"
onClick={() => dispatch({
type: "add_task",
payload: { id: item.id, color: '#ffa500' }
})}>
Change Color
</button>
</li>
);
})}
</ul>
<br />
const [nombre,setNombre] = useState("")
const [direccion,setDireccion] = useState("")
const [mail,setMail] = useState("")
const [telefono,setTelefono] = useState("")

<Link to="/">
<button className="btn btn-primary">Back home</button>
</Link>
const agregarContacto =(e)=>{
e.preventDefault()
if (nombre == ""){
alert ("Debe ingresar nombre completo")
return
}
if (mail == ""){
alert ("Debe ingresar E-mail")
return
}
if (direccion == ""){
alert ("Debe ingresar direccion")
return
}
if (telefono == ""){
alert ("Debe ingresar numero de telefono")
return
}
const newContact = {
"name": nombre,
"phone": telefono,
"email": mail,
"address": direccion,
}
crearContacto (dispatch,newContact)
setNombre("")
setTelefono("")
setDireccion("")
setMail("")
}
return (
<div className="container mt-5 mb-5 p-5">
<h2 className="text-center">Agregar Contacto</h2>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">Nombre Completo</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={nombre} onChange={(e)=>setNombre(e.target.value)}/>
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">Numero de telefono</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={telefono} onChange={(e)=>setTelefono(e.target.value)}/>
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">E-mail</span>
<input type="mail" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={mail} onChange={(e)=>setMail(e.target.value)}/>
</div>
<div className="input-group mb-3">
<span className="input-group-text" id="inputGroup-sizing-default">direccion</span>
<input type="text" className="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" value={direccion} onChange={(e)=>setDireccion(e.target.value)}/>
</div>
<div className="d-flex justify-content-center">
<button className="btn btn-success" onClick={(e)=>agregarContacto(e)}>
Agregar Contacto
</button>
</div>
</div>
);
};
};
61 changes: 54 additions & 7 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,63 @@
import rigoImageUrl from "../assets/img/rigo-baby.jpg";
import { useEffect, useState } from "react";
import useGlobalReducer from "../hooks/useGlobalReducer.jsx";
import { obtenerContactos } from "../store.js";
import { Card } from "../components/card.jsx";
import { ModalDelete } from "../components/modalDelete.jsx";
import { ModalEdit } from "../components/modalEdite.jsx";

export const Home = () => {

const {store, dispatch} =useGlobalReducer()
const { store, dispatch } = useGlobalReducer()
const [showModalDelete, setShowModalDelete] = useState({
showModal: false,
id: undefined,
name: undefined,
})
const [showModalEdit, setShowModalEdit] = useState({
showModal: false,
id: undefined,
contact: undefined,
})

useEffect(() => {
obtenerContactos(dispatch)
}, [])

console.log(store.contacts)
return (
<div className="text-center mt-5">
<h1>Hello Rigo!!</h1>
<p>
<img src={rigoImageUrl} />
</p>
<h1>Contact List</h1>
{store.contacts.length > 0 ? (
<div className="d-flex flex-column align-items-center">
{store.contacts.map((contacto) => (
<Card
key={contacto.id}
id={contacto.id}
name={contacto.name}
address={contacto.address}
phone={contacto.phone}
email={contacto.email}
onDelete={() => setShowModalDelete({ showModal: true, id: contacto.id, name: contacto.name })}
onEdit={() => setShowModalEdit({ showModal: true, id: contacto.id, contact: contacto })}
/>
))}
</div>
) : (
<p> no existen contactos</p>
)}

<ModalDelete
id={showModalDelete.id}
name={showModalDelete.name}
show={showModalDelete.showModal}
onClose={() => setShowModalDelete({ showModal: false })}
/>
<ModalEdit
id={showModalEdit.id}
contact={showModalEdit.contact}
show={showModalEdit.showModal}
onClose={() => setShowModalEdit({ showModal: false })}
/>
</div>
);
};
};
2 changes: 1 addition & 1 deletion src/pages/Single.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ Single.propTypes = {
// Although 'match' prop is defined here, it is not used in the component.
// Consider removing or using it as needed.
match: PropTypes.object
};
};
Loading