Skip to content
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
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
"@tanstack/react-query-devtools": "^5.0.0-alpha.91",
"axios": "^1.7.2",
"cors": "^2.8.5",
"formik": "^2.4.6",
"next": "14.2.4",
"react": "^18",
"react-dom": "^18"
"react-dom": "^18",
"yup": "^1.4.0"
},
"devDependencies": {
"eslint": "^8",
Expand Down
18 changes: 18 additions & 0 deletions src/app/containers/create-movie/formField.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Field } from "formik";

export const FormField = ({ label, placeholder, name, type, error }) => (
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-1">
{label}
</label>
<Field
placeholder={placeholder}
name={name}
type={type}
className={`shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md ${
error ? "border-red-500" : ""
}`}
/>
{error && <div className="text-red-600 text-sm mt-1">{error}</div>}
</div>
);
51 changes: 28 additions & 23 deletions src/app/containers/create-movie/index.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
'use client'
import { useMutation } from "@tanstack/react-query";
import axios from "axios";
import MovieForm from "./movieForm";

import { useMutation } from "@tanstack/react-query"
import axios from "axios"

const createMovie = async () => {
const response = await axios.post('/api/movies', {id: 7, name: "Dune" })

return response.data
}
const createMovie = async (movieData) => {
const response = await axios.post("/api/movies", movieData);
return response.data;
};

export const CreateMovie = () => {
const { mutate, data, isSuccess, isError, error } = useMutation({
mutationFn: createMovie,
mutationKey: ["create-movie"]
})
const { mutate : handleMovieSubmit, data, isSuccess, isError, error } = useMutation({
mutationFn: createMovie,
mutationKey: ["create-movie"],
});

return <>
{isError && <div className="text-red-600">{error.message}</div>}
<button onClick={() => mutate()}>Create movie</button>
{isSuccess && <div>
Newly created movie
<p>This is id: {data.id}</p>
<p>This is movie name: {data.name}</p>
</div>}
</>

}
return (
<div className="max-w-md mx-auto bg-white p-8 rounded-md shadow-md">
<MovieForm handleSubmit={handleMovieSubmit} />
{isError && (
<div className="text-red-600 mt-4">
{error.response?.data?.message || "An error occurred"}
</div>
)}
{isSuccess && (
<div className="text-green-600 mt-4">
Newly created movie
<p>Movie name: {data.title}</p>
</div>
)}
</div>
);
};
104 changes: 104 additions & 0 deletions src/app/containers/create-movie/movieForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"use client";
import React from "react";
import { Formik, Form } from "formik";
import { FormField } from "./FormField";
import * as yup from "yup";

const initialValues = {
title: "",
description: "",
genres: {
id: "",
name: "",
},
cast: {
role: "",
crew: {
id: "",
nae: "",
},
},
};

const validationSchema = yup.object().shape({
title: yup.string().required("Title is required"),
description: yup.string().required("Description is required"),
genres: yup.object().shape({
id: yup.number().required("Genre ID is required"),
name: yup.string().required("Genre name is required"),
}),
cast: yup.object().shape({
role: yup.string().required("Cast role is required"),
crew: yup.object().shape({
id: yup.number().required("Crew ID is required"),
name: yup.string().required("Crew name is required"),
}),
}),
});

const MovieForm = ({ handleSubmit }) => {
return (
<Formik
initialValues={initialValues}
onSubmit={(values) => {
handleSubmit(values);
}}
validationSchema={validationSchema}
>
{({ errors }) => (
<Form className="max-w-md mx-auto bg-white p-8 rounded-md shadow-md">
<FormField
label="Title"
name="title"
type="text"
error={errors.title}
/>
<FormField
label="Description"
name="description"
type="text"
error={errors.description}
/>
<FormField
label="Genre ID"
name="genres.id"
type="Number"
error={errors.genres?.id}
/>
<FormField
label="Genre Name"
name="genres.name"
type="text"
error={errors.genres?.name}
/>
<FormField
label="Cast Role"
name="cast.role"
type="text"
error={errors.cast?.role}
/>
<FormField
label="Crew ID"
name="cast.crew.id"
type="Number"
error={errors.cast?.crew?.id}
/>
<FormField
label="Crew Name"
name="cast.crew.name"
type="text"
error={errors.cast?.crew?.name}
/>
<button
type="submit"
className="w-full bg-slate-600 text-white py-2 px-4 rounded hover:bg-slate-900"
>
Submit
</button>
</Form>
)}
</Formik>
);
};

export default MovieForm;
2 changes: 1 addition & 1 deletion src/app/containers/movies/content.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Content = () => {
<h1>Movies List</h1>
<ul>
{isSuccess && data.map(movie => (
<li key={movie.id}>{movie.name}</li>
<li key={movie.genres.id}>{movie.title}</li>
))}
</ul>
{isError && (
Expand Down
14 changes: 10 additions & 4 deletions src/app/create-movie/page.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
'use client'
import { CreateMovie } from "../containers/create-movie"


const CreateMoviePage = () => {
return <div>
Create Movie
<CreateMovie />

return (
<div >
<h1 className="text-2xl font-bold mb-6 text-center">Create Movie</h1>
<CreateMovie />
</div>
}
);

};

export default CreateMoviePage
2 changes: 1 addition & 1 deletion src/app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function RootLayout({ children }) {
return (
<html lang="en" className="h-full">
<body
className={`${inter.className} bg-[url('../assets/background.jpg')] h-full bg-center bg-cover bg-no-repeat`}
// className={`${inter.className} bg-[url('../assets/background.jpg')] h-full bg-center bg-cover bg-no-repeat`}
>
<Providers>
<Header />
Expand Down
8 changes: 5 additions & 3 deletions src/pages/api/movies.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ const handler = (req, res) => {
const data = JSON.parse(fs.readFileSync(dataFilePath, "utf8"));

const alreadyExists = data.some(
(movie) => movie.id === newData.id || movie.name === newData.name,
(movie) =>
movie.title === newData.title &&
movie.genres.id === newData.genres.id
);

if (alreadyExists) {
res.status(419).end("The movie already exists");
res.status(419).json({ message: "The movie already exists" });
return;
}
data.push(newData);
Expand All @@ -29,7 +31,7 @@ const handler = (req, res) => {

res.status(200).json(newData);
} catch {
res.status(500).end("Something went wrong");
res.status(500).end("Something went wrong" );
}

return;
Expand Down
Loading