diff --git a/hooks/useMovieForm.js b/hooks/useMovieForm.js new file mode 100644 index 0000000..651f443 --- /dev/null +++ b/hooks/useMovieForm.js @@ -0,0 +1,39 @@ +import { useEffect, useState } from 'react'; + +export function useMovieForm(initialData = {}, onSubmit) { + const [formData, setFormData] = useState({ + title: '', + poster: '' + }); + + useEffect(() => { + if (initialData) { + setFormData({ + title: initialData.title || '', + poster: initialData.poster || '' + }); + } + }, [initialData]); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + onSubmit({ + ...initialData, + ...formData + }); + }; + + return { + formData, + handleChange, + handleSubmit + }; +} \ No newline at end of file diff --git a/hooks/useMovies.js b/hooks/useMovies.js new file mode 100644 index 0000000..7bf9667 --- /dev/null +++ b/hooks/useMovies.js @@ -0,0 +1,71 @@ +import { useEffect, useState } from 'react'; + +export function useMovies() { + const [movies, setMovies] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchMovies = async () => { + setLoading(true); + try { + const response = await fetch('http://localhost:3001/movies'); + if (!response.ok) throw new Error('Network response was not ok'); + const data = await response.json(); + setMovies(data); + } catch (err) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + fetchMovies(); + }, []); + + const addMovie = async (movieData) => { + try { + const response = await fetch('http://localhost:3001/movies', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(movieData), + }); + const newMovie = await response.json(); + setMovies(prev => [...prev, newMovie]); + return true; + } catch (err) { + setError(err.message); + return false; + } + }; + + const updateMovie = async (movieData) => { + try { + await fetch(`http://localhost:3001/movies/${movieData.id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(movieData), + }); + setMovies(prev => prev.map(m => m.id === movieData.id ? movieData : m)); + return true; + } catch (err) { + setError(err.message); + return false; + } + }; + + const deleteMovie = async (id) => { + try { + await fetch(`http://localhost:3001/movies/${id}`, { + method: 'DELETE', + }); + setMovies(prev => prev.filter(m => m.id !== id)); + return true; + } catch (err) { + setError(err.message); + return false; + } + }; + + return { movies, loading, error, addMovie, updateMovie, deleteMovie }; +} \ No newline at end of file diff --git a/report.docx b/report.docx index 2adb13c..85c82f3 100644 Binary files a/report.docx and b/report.docx differ diff --git a/src/pages/Movies.jsx b/src/pages/Movies.jsx index 19918f1..18ae87a 100644 --- a/src/pages/Movies.jsx +++ b/src/pages/Movies.jsx @@ -1,65 +1,38 @@ -import { useEffect, useState } from 'react' -import Footer from '../components/Footer' -import Header from '../components/Header' -import MovieCard from '../components/MovieCard' -import MovieForm from '../components/MovieForm' +import { useState } from 'react'; +import { useMovies } from '../../hooks/useMovies'; +import Footer from '../components/Footer'; +import Header from '../components/Header'; +import MovieCard from '../components/MovieCard'; +import MovieForm from '../components/MovieForm'; export default function Movies() { - const [movies, setMovies] = useState([]) - const [showForm, setShowForm] = useState(false) - const [editingMovie, setEditing] = useState(null) - - useEffect(() => { - fetch('http://localhost:3001/movies') - .then(res => res.json()) - .then(data => setMovies(data)) - }, []) + const { movies, addMovie, updateMovie, deleteMovie } = useMovies(); + const [showForm, setShowForm] = useState(false); + const [editingMovie, setEditingMovie] = useState(null); const handleAdd = () => { - setEditing(null) - setShowForm(true) - } + setEditingMovie(null); + setShowForm(true); + }; const handleEdit = (movie) => { - setEditing(movie) - setShowForm(true) - } + setEditingMovie(movie); + setShowForm(true); + }; - const handleDelete = (id) => { - fetch(`http://localhost:3001/movies/${id}`, { - method: 'DELETE', - }).then(() => { - setMovies(prev => prev.filter(m => m.id !== id)) - }) - } + const handleDelete = async (id) => { + await deleteMovie(id); + }; - const handleSubmit = (movieData) => { - if (editingMovie) { - fetch(`http://localhost:3001/movies/${movieData.id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(movieData), - }).then(() => { - setMovies(prev => prev.map(m => m.id === movieData.id ? movieData : m)) - setShowForm(false) - }) - } else { - fetch('http://localhost:3001/movies', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(movieData), - }) - .then(res => res.json()) - .then(newMovie => { - setMovies(prev => [...prev, newMovie]) - setShowForm(false) - }) + const handleSubmit = async (movieData) => { + const success = editingMovie + ? await updateMovie(movieData) + : await addMovie(movieData); + + if (success) { + setShowForm(false); } - } + }; return ( <> @@ -92,5 +65,5 @@ export default function Movies() {