diff --git a/.env b/.env
new file mode 100644
index 00000000..f5fdb484
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+VITE_API_KEY=13a32227ebd064212ea8575b58265a25
diff --git a/README.md b/README.md
index f768e33f..92f149d5 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,78 @@
-# React + Vite
+## Unit Assignment: Flixster
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+Submitted by: Zara Duruji
-Currently, two official plugins are available:
+Estimated time spent: **#** 40 Hours
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+Deployed Application (optional): [Flixster Deployed Site] https://flixster-starter-yhyt.onrender.com/
+
+### Application Features
+
+#### CORE FEATURES
+
+
+- [❌] **Display Movies**
+ - [ ❌] Users can view a list of current movies from The Movie Database API.
+ - [❌ ] For each movie displayed, users can see its title, poster image, and votes.
+ - [❌ ] Users can load more current movies by clicking a button at the bottom of the list (page should not be reloaded).
+- [ ❌] **Search Functionality**
+ - [ ❌] Users can search for movies and view the results in a grid.
+ - [ ❌] Users can clear results and view previous current movies displayed.
+- [ ❌] **Accessibility Features**
+ - ❌[ ] Website implements accessibility features (semantic HTML, color contrast, font sizing, alt text for images).
+- [❌ ] **Responsive Design**
+ - [❌ ] Website implements responsive web design.
+- [ ❌] **Movie Details**
+ - [ ❌] Users can view more details about a movie in a popup, such as runtime in minutes, backdrop poster, release date, genres, and/or an overview.
+- [ ❌] **Sorting Options**
+ - [❌ ] Users can click on a filter by drop down to sort product by type (alphabetic, release date, rating).
+- [ ❌] **Layout**
+ - [ ❌] Website displays header, banner, search, movie grid, about, contact, and footer section.
+
+#### STRETCH FEATURES
+
+- [❌ ] **Deployment**
+ - [ ❌] Website is deployed via Render.
+- [ ❌] **Embedded Movie Trailers**
+ - [❌ ] Within the popup displaying a movie's details, users can play the movie trailer.
+- [ ❌] **Watched Checkbox**
+ - [ ❌] For each movie displayed, users can mark the movie as watched.
+- [ ❌] **Favorite Button**
+ - [❌ ] For each movie displayed, users can favorite the movie.
+- [ ❌] **Sidebar**
+ - [ ❌] Users can open a sidebar
+ - [ ❌] The sidebar displays the user's favorited and watched movies
+
+### Walkthrough Video
+
+
+### Reflection
+
+* Did the topics discussed in your labs prepare you to complete the assignment? Be specific, which features in your weekly assignment did you feel unprepared to complete?
+
+The topics discussed in the labs provided a good foundation for completing the assignment, particularly in managing state with hooks, integrating APIs, and structuring the application with reusable components. However, there were areas where I felt less prepared. Designing responsive and visually appealing components like the modal and sidebar was challenging due to limited coverage of advanced CSS and styling techniques. Managing state across multiple components, especially for dynamic updates to the favorites and watched lists, was more complex than expected. Although basic event handling was covered, implementing features like toggling favorites and marking movies as watched required more advanced knowledge. Error handling with API requests and integrating external libraries like FontAwesome for icons were also areas where additional guidance would have been helpful. Overall, while the labs were beneficial, more focus on these advanced topics would have better prepared me for the assignment.
+
+* If you had more time, what would you have done differently? Would you have added additional features? Changed the way your project responded to a particular event, etc.
+
+If I had more time, I would have made several improvements and added additional features to enhance the project. Firstly, I would refine the user interface to ensure a more cohesive and visually appealing design, paying particular attention to responsiveness across different devices. This includes optimizing the layout of the modal and sidebar components and ensuring smooth animations for opening and closing these elements.
+
+Additionally, I would implement more robust error handling for API requests, providing clear feedback to users in case of network issues or data retrieval errors. Enhancing the state management logic to handle complex interactions more efficiently would also be a priority, ensuring a seamless user experience when toggling favorites and marking movies as watched.
+
+I would consider adding features such as user authentication to personalize the experience and allow users to save their favorite movies and watched lists across sessions. Another feature could be a recommendation system based on the user's viewing history and preferences.
+
+Finally, I would refine the event-handling mechanisms to make interactions more intuitive and responsive, ensuring that the project responds smoothly to user actions such as sorting, searching, and interacting with movie cards. These enhancements would significantly improve the overall functionality and user experience of the project.
+
+* Reflect on your project demo, what went well? Were there things that maybe didn't go as planned? Did you notice something that your peer did that you would like to try next time?
+
+Reflecting on my project demo, I was particularly pleased with the implementation of the modal, which provided a detailed and engaging way to display movie information and trailers. The modal design and functionality turned out to be intuitive and visually appealing, enhancing the overall user experience.
+
+However, I did encounter challenges while implementing the sidebar. Ensuring it updated correctly with favorite and watched movies, as well as making it responsive and user-friendly, proved to be more complex than anticipated. This was an area where things didn't go entirely as planned, and it highlighted the need for better state management and event handling in my project.
+
+During the demo, I noticed a peer who had seamlessly integrated a more advanced sorting and filtering system, which greatly enhanced the usability of their project. This is something I would like to try in my next project, as it would provide users with a more dynamic and interactive experience. Their approach to sorting and filtering was efficient and user-friendly, and incorporating a similar feature would be a valuable addition to my own projects in the future.
+
+### Open-source libraries used
+
+- [Add any links to open-source libraries used in your project.]
+
+### Shout out
+Instructor Sammy
diff --git a/package-lock.json b/package-lock.json
index 92a683d2..e8a5bca8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,10 @@
"name": "flixster",
"version": "0.0.0",
"dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.5.2",
+ "@fortawesome/free-regular-svg-icons": "^6.5.2",
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
+ "@fortawesome/react-fontawesome": "^0.2.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
@@ -811,6 +815,63 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz",
+ "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==",
+ "hasInstallScript": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz",
+ "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-regular-svg-icons": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz",
+ "integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz",
+ "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.5.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/react-fontawesome": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz",
+ "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==",
+ "dependencies": {
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "@fortawesome/fontawesome-svg-core": "~1 || ~6",
+ "react": ">=16.3"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
@@ -3193,7 +3254,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3457,7 +3517,6 @@
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
@@ -3519,8 +3578,7 @@
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-refresh": {
"version": "0.14.0",
diff --git a/package.json b/package.json
index eded5715..304d67da 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,10 @@
"preview": "vite preview"
},
"dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.5.2",
+ "@fortawesome/free-regular-svg-icons": "^6.5.2",
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
+ "@fortawesome/react-fontawesome": "^0.2.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
diff --git a/public/purplebackground.jpg b/public/purplebackground.jpg
new file mode 100644
index 00000000..71a44c73
Binary files /dev/null and b/public/purplebackground.jpg differ
diff --git a/src/App.css b/src/App.css
index 0bf65669..484d85fd 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,28 +1,128 @@
.App {
- text-align: center;
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ background-image: url(/public/purplebackground.jpg);
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ color: rgb(255, 255, 255);
}
-.App-header {
- background-color: #282c34;
+main {
+ flex: 1;
+ padding: 20px;
+ margin: 20px;
+ background-color: rgba(255, 255, 255, 0.2); /* Slightly lighten the main content for readability */
+ border-radius: 8px;
display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-evenly;
+ flex-direction: column;
+ min-height: 100vh;
+ background-image: url(/public/purplebackground.jpg);
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ color: rgb(255, 255, 255);
+}
+
+button {
+ padding: 10px 20px;
+ font-size: 16px;
+ background-color: #7d3b8a; /* Darker purple */
color: white;
- padding: 20px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ margin: 20px auto;
+ display: block;
+}
+
+button:hover {
+ background-color: #9c4bb5; /* Lighter purple */
+}
+
+/* src/App.css */
+
+.toggle-button {
+ background-color: #4b2e83; /* Purple background */
+ color: white;
+ border: none;
+ padding: 10px 20px;
+ font-size: 16px;
+ border-radius: 5px;
+ cursor: pointer;
+ margin-bottom: 20px; /* Adjust as needed */
+}
+
+.toggle-button:hover {
+ background-color: #7856b7; /* Darker purple on hover */
+}
+@media (max-width: 1024px) {
+ main {
+ padding: 15px;
+ margin: 15px;
+ }
+
+ .toggle-button {
+ font-size: 14px;
+ padding: 8px 16px;
+ }
+
+ button {
+ font-size: 14px;
+ padding: 8px 16px;
+ }
+}
+
+@media (max-width: 768px) {
+ .header {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .header-right {
+ margin-top: 10px;
+ }
+
+ main {
+ padding: 10px;
+ margin: 10px;
+ }
+
+ .toggle-button {
+ font-size: 12px;
+ padding: 6px 12px;
+ }
+
+ button {
+ font-size: 12px;
+ padding: 6px 12px;
+ }
+
+ .movie-card {
+ width: 90%;
+ margin: 10px auto;
+ }
}
@media (max-width: 600px) {
.movie-card {
width: 100%;
+ margin: 5px auto;
}
- .search-bar {
- flex-direction: column;
- gap: 10px;
+ main {
+ padding: 5px;
+ margin: 5px;
}
- .search-bar form {
- flex-direction: column;
+ .toggle-button {
+ font-size: 10px;
+ padding: 5px 10px;
+ }
+
+ button {
+ font-size: 10px;
+ padding: 5px 10px;
}
}
diff --git a/src/App.jsx b/src/App.jsx
index 48215b3f..ac468d23 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,10 +1,95 @@
-import { useState } from 'react'
-import './App.css'
+import { useState, useEffect } from 'react';
+import './App.css';
+import Header from './Header';
+import NowPlaying from './NowPlaying';
+import Searching from './Searching';
+import Sidebar from './Sidebar';
+import Footer from './Footer';
const App = () => {
-