diff --git a/README.md b/README.md
index 4c8fd7876..de78f573c 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,15 @@
# Project Movies
-Replace this readme with your own information about your project.
+This is a multi-page React application designed to showcase the use of APIs in React. The project utilizes useState and useEffect hooks to display information about upcoming movie releases. It was developed through pair programming.
-Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
## The problem
-Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
+- working with an API and having it in an external folder 'utils' and then exporting it for the use of the project
+- first time working with React Router
+- using new React hooks
## View it live
-Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
+https://michelle-maja-movies.netlify.app/
+
diff --git a/code/package-lock.json b/code/package-lock.json
index bb51e893e..964acdc50 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -15,8 +15,11 @@
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "moment": "^2.29.4",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-moment": "^1.1.3",
+ "react-router-dom": "^6.9.0"
},
"devDependencies": {
"react-scripts": "5.0.1"
@@ -3124,6 +3127,14 @@
}
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.4.0.tgz",
+ "integrity": "sha512-BJ9SxXux8zAg991UmT8slpwpsd31K1dHHbD3Ba4VzD+liLQ4WAMSxQp2d2ZPRPfN0jN2NPRowcSSoM7lCaF08Q==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -12008,6 +12019,14 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -14375,6 +14394,16 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-moment": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/react-moment/-/react-moment-1.1.3.tgz",
+ "integrity": "sha512-8EPvlUL8u6EknPp1ISF5MQ3wx2OHJVXIP/iZc4wRh3iV3XozftZERDv9ANZeAtMlhNNQHdFoqcZHFUkBSTONfA==",
+ "peerDependencies": {
+ "moment": "^2.29.0",
+ "prop-types": "^15.7.0",
+ "react": "^16.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -14384,6 +14413,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.9.0.tgz",
+ "integrity": "sha512-51lKevGNUHrt6kLuX3e/ihrXoXCa9ixY/nVWRLlob4r/l0f45x3SzBvYJe3ctleLUQQ5fVa4RGgJOTH7D9Umhw==",
+ "dependencies": {
+ "@remix-run/router": "1.4.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.9.0.tgz",
+ "integrity": "sha512-/seUAPY01VAuwkGyVBPCn1OXfVbaWGGu4QN9uj0kCPcTyNYgL1ldZpxZUpRU7BLheKQI4Twtl/OW2nHRF1u26Q==",
+ "dependencies": {
+ "@remix-run/router": "1.4.0",
+ "react-router": "6.9.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
@@ -19509,6 +19568,11 @@
"source-map": "^0.7.3"
}
},
+ "@remix-run/router": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.4.0.tgz",
+ "integrity": "sha512-BJ9SxXux8zAg991UmT8slpwpsd31K1dHHbD3Ba4VzD+liLQ4WAMSxQp2d2ZPRPfN0jN2NPRowcSSoM7lCaF08Q=="
+ },
"@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -26117,6 +26181,11 @@
"minimist": "^1.2.6"
}
},
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -27678,12 +27747,35 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-moment": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/react-moment/-/react-moment-1.1.3.tgz",
+ "integrity": "sha512-8EPvlUL8u6EknPp1ISF5MQ3wx2OHJVXIP/iZc4wRh3iV3XozftZERDv9ANZeAtMlhNNQHdFoqcZHFUkBSTONfA==",
+ "requires": {}
+ },
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==",
"dev": true
},
+ "react-router": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.9.0.tgz",
+ "integrity": "sha512-51lKevGNUHrt6kLuX3e/ihrXoXCa9ixY/nVWRLlob4r/l0f45x3SzBvYJe3ctleLUQQ5fVa4RGgJOTH7D9Umhw==",
+ "requires": {
+ "@remix-run/router": "1.4.0"
+ }
+ },
+ "react-router-dom": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.9.0.tgz",
+ "integrity": "sha512-/seUAPY01VAuwkGyVBPCn1OXfVbaWGGu4QN9uj0kCPcTyNYgL1ldZpxZUpRU7BLheKQI4Twtl/OW2nHRF1u26Q==",
+ "requires": {
+ "@remix-run/router": "1.4.0",
+ "react-router": "6.9.0"
+ }
+ },
"react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
diff --git a/code/package.json b/code/package.json
index 7aad26ebc..db73fce7e 100644
--- a/code/package.json
+++ b/code/package.json
@@ -10,8 +10,11 @@
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "moment": "^2.29.4",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-moment": "^1.1.3",
+ "react-router-dom": "^6.9.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/code/public/index.html b/code/public/index.html
index e6730aa66..e974b1c67 100644
--- a/code/public/index.html
+++ b/code/public/index.html
@@ -13,7 +13,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
-
Technigo React App
+ Movies Page by Michelle and Maja
diff --git a/code/src/App.js b/code/src/App.js
index f2007d229..bbe9a860f 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -1,9 +1,52 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
+import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
+import NotFound from 'components/NotFound';
+import Details from 'components/Details';
+import ListMovies from 'components/ListMovies';
+import { LIST_URL } from 'utils/urls.js';
export const App = () => {
+ const [listMovies, setListMovies] = useState([]);
+ const [loading, setLoading] = useState(false);
+
+ // this is borrowed from the example project
+ useEffect(() => {
+ setLoading(true);
+ fetch(LIST_URL)
+ .then((response) => response.json())
+ .then((data) => {
+ setListMovies(data.results)
+ })
+ .catch((e) => {
+ console.error(e)
+ })
+ .finally(() => {
+ setLoading(false);
+ })
+ }, []);
+
+ if (loading) {
+ return (
+
Loading...
+ );
+ }
+ console.log(listMovies)
+
return (
-
- Find me in src/app.js!
-
+ // this is the main wrapper for the whole app
+
+
+
+
+ {/* path to a single component */}
+ } />
+ } />
+ } />
+ } />
+
+
+ {/* wrapper for every component that need to be linked to */}
+
+
);
-}
+}
\ No newline at end of file
diff --git a/code/src/assets/github.png b/code/src/assets/github.png
new file mode 100644
index 000000000..671a8a66a
Binary files /dev/null and b/code/src/assets/github.png differ
diff --git a/code/src/assets/movie.png b/code/src/assets/movie.png
new file mode 100644
index 000000000..3a7360d6e
Binary files /dev/null and b/code/src/assets/movie.png differ
diff --git a/code/src/components/Details.js b/code/src/components/Details.js
new file mode 100644
index 000000000..da332a825
--- /dev/null
+++ b/code/src/components/Details.js
@@ -0,0 +1,45 @@
+/* eslint-disable react/jsx-max-props-per-line */
+/* eslint-disable react/jsx-indent-props */
+/* eslint-disable react/jsx-first-prop-new-line */
+/* eslint-disable react/jsx-closing-tag-location */
+/* eslint-disable max-len */
+import React, { useEffect, useState } from 'react';
+import { useParams } from 'react-router-dom';
+import '../details.css';
+
+// Define the Details component
+const Details = () => {
+ // Get the id parameter from the URL using the useParams hook
+ const { id } = useParams();
+ // Define state for the movie details, initialized as an empty object
+ const [movieDetail, setMovieDetail] = useState({});
+
+ useEffect(() => {
+ fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=39168ef639d8a2d49b6d7a9893ad1b8c&language=en-US`)
+ .then((data) => data.json())
+ .then((configuredData) => setMovieDetail(configuredData))
+ }, [id]);
+
+ return (
+
+ {/* The ternary operator checks if the image paths property of the movieDetail object is truthy (i.e., not undefined, null, 0, false, etc.). If it is truthy, it
+ sets the src attribute of the imgtag to the URL of the image file. If it is falsy, it sets the src` attribute to an empty string. */}
+
+ Movies
+