2025-05-25 14:26:09 +02:00
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
|
2025-05-25 00:00:13 +02:00
|
|
|
import PersonList from "./components/PersonList";
|
2025-05-24 23:43:23 +02:00
|
|
|
|
2025-05-25 12:08:25 +02:00
|
|
|
const SearchArea = ({ onChangeHandler }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
search name: <input onChange={onChangeHandler} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-25 12:11:55 +02:00
|
|
|
const AddPersonForm = ({
|
|
|
|
|
onSubmitHandler,
|
|
|
|
|
onNameChangeHandler,
|
|
|
|
|
nameValue,
|
|
|
|
|
onNumberChangeHandler,
|
|
|
|
|
numberValue,
|
|
|
|
|
}) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<form onSubmit={onSubmitHandler}>
|
|
|
|
|
<div>
|
|
|
|
|
name: <input value={nameValue} onChange={onNameChangeHandler} />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
number: <input value={numberValue} onChange={onNumberChangeHandler} />
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<button type="submit">add</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-24 23:43:23 +02:00
|
|
|
const App = () => {
|
2025-05-25 14:26:09 +02:00
|
|
|
const [persons, setPersons] = useState([]);
|
2025-05-25 12:04:02 +02:00
|
|
|
const [searchString, setSearchString] = useState("");
|
2025-05-24 23:43:23 +02:00
|
|
|
const [newName, setNewName] = useState("");
|
2025-05-25 11:55:15 +02:00
|
|
|
const [newNumber, setNewNumber] = useState("");
|
2025-05-24 23:43:23 +02:00
|
|
|
|
2025-05-26 00:27:20 +02:00
|
|
|
const getPersons = () => {
|
|
|
|
|
return axios.get("http://localhost:3001/persons");
|
|
|
|
|
};
|
|
|
|
|
const addPerson = () => {
|
|
|
|
|
return axios.post("http://localhost:3001/persons", {
|
|
|
|
|
name: newName,
|
|
|
|
|
number: newNumber,
|
|
|
|
|
id: newName,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-25 14:26:09 +02:00
|
|
|
useEffect(() => {
|
2025-05-26 00:27:20 +02:00
|
|
|
getPersons().then((response) => {
|
2025-05-25 14:26:09 +02:00
|
|
|
console.log(response.data);
|
|
|
|
|
setPersons(response.data);
|
|
|
|
|
});
|
|
|
|
|
}, []);
|
|
|
|
|
|
2025-05-25 00:00:13 +02:00
|
|
|
const handleOnSubmit = (event) => {
|
|
|
|
|
event.preventDefault();
|
2025-05-25 00:10:10 +02:00
|
|
|
if (
|
|
|
|
|
persons.some((person) => {
|
|
|
|
|
return person.name === newName;
|
|
|
|
|
})
|
|
|
|
|
) {
|
|
|
|
|
alert(`${newName} is already in the phonebook.`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-05-25 12:04:02 +02:00
|
|
|
|
2025-05-26 00:27:20 +02:00
|
|
|
addPerson().then((response) => {
|
|
|
|
|
setPersons(persons.concat(response.data));
|
|
|
|
|
});
|
2025-05-25 12:04:02 +02:00
|
|
|
setNewName("");
|
|
|
|
|
setNewNumber("");
|
2025-05-25 00:00:13 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleNameChange = (event) => {
|
|
|
|
|
setNewName(event.target.value);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-25 11:55:15 +02:00
|
|
|
const handleNumberChange = (event) => {
|
|
|
|
|
setNewNumber(event.target.value);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-25 12:04:02 +02:00
|
|
|
const handleSearchChange = (event) => {
|
|
|
|
|
setSearchString(event.target.value);
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-24 23:43:23 +02:00
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h2>Phonebook</h2>
|
2025-05-25 12:08:25 +02:00
|
|
|
<SearchArea onChangeHandler={handleSearchChange} />
|
2025-05-25 12:04:02 +02:00
|
|
|
<h3>Add new</h3>
|
2025-05-25 12:11:55 +02:00
|
|
|
<AddPersonForm
|
|
|
|
|
onSubmitHandler={handleOnSubmit}
|
|
|
|
|
onNameChangeHandler={handleNameChange}
|
|
|
|
|
nameValue={newName}
|
|
|
|
|
onNumberChangeHandler={handleNumberChange}
|
|
|
|
|
numberValue={newNumber}
|
|
|
|
|
/>
|
2025-05-25 12:04:02 +02:00
|
|
|
<h3>Numbers</h3>
|
|
|
|
|
<PersonList
|
|
|
|
|
persons={persons.filter((person) =>
|
|
|
|
|
person.name.toUpperCase().includes(searchString.toUpperCase())
|
|
|
|
|
)}
|
|
|
|
|
/>
|
2025-05-24 23:43:23 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default App;
|