diff --git a/README.md b/README.md index a020848..121d9a1 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,27 @@ -# Movie Project +![Home1](./public/Home1.PNG) +![Home2](./public/home2.PNG) +![Home3](./public/home3.PNG) -## Overview +Description : +Neocine is a movie and actor information website that allows users to explore the latest movies, popular actors, and more. It provides a user-friendly interface to browse through movie details, actor profiles, and related content. Neocine is powered by The Movie Database (TMDb) API to fetch real-time movie and actor data. -Working with APIs to make our websites interactive sits at the core of frontend web development. At the end, frontend websites work as interfaces that give us the ability to interace with data. All this data is coming from some form of an API. +Tools Used : -The API you will be interacting with is a movie API that can be used to retreive information about movies and actors. It is quite extensive and serves many purposes for your needs. In addition to that, it has quite a versatile searching mechanism that gives you the ability to reach for the information you need. +Next.js +Material UI +Figma (for design and prototyping) +Prettier +Husky +Commitizen +Git Workflow -## How to make use of this WIKI? +Team Linkedin -As you can see, the only thing you received from us is a bunch of `.md` (Markdown) files like the one you're reading now. We want you to learn to build your own projects from scratch and see how the process is done. So, we have created the following things in the wiki to help you out with the preparation: +- [Sidahmed Slikh](https://www.linkedin.com/in/sidahmed-zinedine) +- [Benarba Tewfik](www.linkedin.com/in/mohammed-tewfik-benarba) +- [Bouchra Ikram](https://www.linkedin.com/in/bouchra-ikram-aboura-1750b5169/) +- [Youssef Sergma](https://www.linkedin.com/in/sergma) +- [Imane Omari](https://www.linkedin.com/in/iman-omari) +- [Melissa Sidi Said](https://www.linkedin.com/in/milyssa-sidisaid-46170a232/) -1. Setup - This page contains the steps you need to setup the project. **Only one of you will do it, while the others watch and support them** -2. Requirements - This page contains the requirements that you need to do for the project. -3. Presentation - This page contains the requirements that you need to do when presenting. -4. Score guide - We're introducing a new score system. This page contains the breakdown of the score. - -To make the best use of this Wiki, go first to the requirements, understand them, then go to the score guide, understand it, then finally head to the setup page so you can do the setup with everything in mind. - -## Key takeaways πŸŽ‰ - -If you finish this project you can be absolutely sure that you can work on any project in the future. Generally, you will be able to use the same tools and techniques you used here to build any website in the future. - -#### Things you will practice while working on this project - -You will be able to practice: - -- Dividing tasks as components between the team and avoiding most conflict issues. -- Using states and setters to change the state of the component. -- Using props to pass data from one component to another. -- Using static-site generation and server-side rendering to fetch data and add them to pages. -- Preparing folder structure in a way that makes your, and everyone elses work easier. -- Adding new dependencies and how to use them. -- Reading the documentation of the packages you use. -- Reading the documentation of APIs and how to understand them. -- Using Authentication tokens in your -- Using routes to navigate between pages. -- Using local storage to store information. -- Using UI Kits to make styling components easier. - -#### Concerns to avoid - -The following thoughts are traps; steer away from them: - -- *`This project is huge! I don't think I'm going to be able to do it.`* From your previous experiences, you know for a fact that everything starts big in the beginning but when you plan things and work on them they usually are not as big and scary as you thought. -- *`I don't know how to use [insert tool here] how am I going to deal with all of this?`* Again, don't worry. You have dealt with so many unknown things and just like you learned how to use them, you will be able to learn how to use any tool you want as long as you check its documentation. -- *`[Right from the beginning] How am I going to fix the bonus topic?`* DON'T GO THERE UNLESS YOU FINISH THE MAIN REQUIREMENTS FIRST! -- *`[After spending hours on an issue to fix it without reading the documentation or searching the issue on google] I will spend extra hours on this until I fix it`* This is a trap. You should always read the documentation and search for the solution. -- *`I'm so tired now!!!😩 I've been trying to fix this bug for 3 hours!!!`* In times like these, consider steping away from your computer and doing something else like playing with your pet, watching something funny, looking outside your window and enjoying cool air. - -#### Confidence boosters - -In times of doubts remember these: - -- *`This project will be a huge addition to my already big list of projects that will increase my future prospects of getting hired`* -- *`The internet is FULL of resources that any one can use to learn about anything.`* -- *`I've worked on 3 projects. They seemed difficult in the beginning but I still aced them. I'm awesome!`* -- *`3 months ago, my biggest issues and worries are how to write the correct class name to change an HTML element's color. Now, I'm dealing with bigger things because I've learned so much more. My current worries and issues will be my HTML and CSS of my future.`* -- *`I'm not alone on this team. There are 2 more people who got my back.`* +--- diff --git a/Requirements.md b/Requirements.md index 37d9fde..811e980 100644 --- a/Requirements.md +++ b/Requirements.md @@ -50,12 +50,12 @@ Your website need to have the following pages: 7. Director's name 8. Overview of the movie 9. The main 5 actors of the movies in the credit section (Use the API for this) - 10. A related movies section which includes at least five related movies (Use the API for this) + 10. A related movies section which includes at least five related movies (Use the API for this) 11. A trailer section that has the movie trailer from youtube 12. The movie production company name and logo. 2. Functionality: - 1. Clicking an actor in the main actors should go to the single actor page. - 2. Clicking on a movie in the related movies section should take you to the Single movie page (#3) + 1. Clicking an actor in the main actors should go to the single actor page. + 2. Clicking on a movie in the related movies section should take you to the Single movie page (#3) 4. Actors page - Shows a list of all popular actors. Clicking on an actor takes you to the Single actors page (#5) 5. Single actors page - Shows information about the current actor. 1. The information includes: @@ -92,7 +92,7 @@ src/ β”‚ β”œβ”€ index.jsx // Home page β”‚ β”œβ”€ movies/ β”‚ β”œβ”€ index.jsx // Movies page -β”‚ β”œβ”€ [movieId].jsx // Single movie page +β”‚ β”œβ”€ [movieId].jsx // Single movie page β”œβ”€ components/ β”‚ β”œβ”€ Navbar/ β”‚ β”œβ”€ Navbar.jsx @@ -169,8 +169,8 @@ After finishing the project, do the following: 1. Deploy the project on netlify so you can have a link to use it in your portfolio. Don't forget to add a link in your website that points to this project. 2. Remove everything from this README.md file and add the following content to it: - 1. A screenshot of the website. - 2. Your project's name. - 3. Description of the project. - 4. Tools used. - 5. Your names. + 1. A screenshot of the website. + 2. Your project's name. + 3. Description of the project. + 4. Tools used. + 5. Your names. diff --git a/Score-guide.md b/Score-guide.md index 6264f43..a0d8150 100644 --- a/Score-guide.md +++ b/Score-guide.md @@ -3,7 +3,7 @@ This project will be graded. We will follow the following score guide so keep it in mind. | Criteria | Score | -|---------------------------------------------|-------| +| ------------------------------------------- | ----- | | Project Requirements | 3 | | Used Github issues correctly | 1 | | Used Github PRs correctly (Github workflow) | 1 | diff --git a/Setup.md b/Setup.md index 5356ca9..07e68cb 100644 --- a/Setup.md +++ b/Setup.md @@ -46,7 +46,7 @@ Create a new file called `.prettierrc.js` in the root folder and put the followi module.exports = { semi: false, singleQuote: false, // Do you want to use double or single quotations? - trailingComma: 'all', + trailingComma: "all", } ``` @@ -91,7 +91,7 @@ npx lint-staged Now run `npm run prepare` that we created previously to initialize the new changes we created. -### 4. [Commitizen](https://github.com/commitizen/cz-cli) + [Commitlint]() [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) +### 4. [Commitizen](https://github.com/commitizen/cz-cli) + [Commitlint]() [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) Commitizen and Conventional Commits are used to force correct code commit messages in the project. Commitizen is the tool while Conventional commits is the standard while Commitlint is a tool used to enforce that you follow the conventions. @@ -128,7 +128,8 @@ npm install --save-dev @commitlint/{config-conventional,cli} npm install --save-dev @commitlint/config-conventional @commitlint/cli ``` -Create configuration file with the following command +Create configuration file with the following command + ``` echo "module.exports = { extends: ['@commitlint/config-conventional'], @@ -156,7 +157,9 @@ echo "module.exports = { }, };" > commitlint.config.js ``` + Now let's finalize this by adding the precommit message + ``` npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}' ``` @@ -208,4 +211,4 @@ Now go to `.eslintrc.json` and add change it to Now run `npm run dev` your project should be ready. -If everything is running correctly, let's create our first commit using `git cz` then choose `chore` by going down the list and add the scope `project structure` and small short message that explains what you did. Press enter to leave the longer description empty (if you want) \ No newline at end of file +If everything is running correctly, let's create our first commit using `git cz` then choose `chore` by going down the list and add the scope `project structure` and small short message that explains what you did. Press enter to leave the longer description empty (if you want) diff --git a/package-lock.json b/package-lock.json index 5e005c8..d340aa4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,17 @@ "name": "neocine", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.14.9", + "@mui/material": "^5.14.9", + "@mui/system": "^5.14.9", "eslint": "8.49.0", "eslint-config-next": "13.4.19", "next": "13.4.19", - "react": "18.2.0", - "react-dom": "18.2.0" + "react": "^18.2.0", + "react-dom": "18.2.0", + "react-multi-carousel": "^2.8.4" }, "devDependencies": { "@commitlint/cli": "^17.7.1", @@ -35,7 +41,6 @@ "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, "dependencies": { "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" @@ -48,7 +53,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -60,7 +64,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -74,7 +77,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -82,14 +84,12 @@ "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -98,7 +98,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -107,7 +106,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -115,11 +113,29 @@ "node": ">=4" } }, - "node_modules/@babel/helper-validator-identifier": { + "node_modules/@babel/helper-module-imports": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.19.tgz", + "integrity": "sha512-Tinq7ybnEPFFXhlYOYFiSjespWQk0dq2dRNAiMdRTOYQzEGqnnNyrTxPYHP5r6wGjlF1rFgABdDV0g8EwD6Qbg==", "engines": { "node": ">=6.9.0" } @@ -128,7 +144,6 @@ "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -142,7 +157,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -154,7 +168,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -168,7 +181,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -176,14 +188,12 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -192,7 +202,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -201,7 +210,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -220,6 +228,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/types": { + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.19", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@commitlint/cli": { "version": "17.7.1", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.7.1.tgz", @@ -541,6 +562,139 @@ "node": ">=12" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -593,6 +747,40 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.2.tgz", + "integrity": "sha512-olUakR5nr9v2ueVr1yomoJnBTkHGqHzL/iK4AhforiJS/wKJgFphAYpZHZzADLv/zNUFuQwqLH3bcoUhFh2E1Q==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.3.tgz", + "integrity": "sha512-uvnFKtPgzLnpzzTRfhDlvXX0kLYi9lDRQbcDmT8iXl71Rx+uwSuaUIQl3DNC7w5OweAQ7XQMDObML+KaYDQfng==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -648,6 +836,262 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.15", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.15.tgz", + "integrity": "sha512-Xtom3YSdi0iwYPtyVRFUEGoRwi6IHWixPwifDKaK+4PkEPtUWMU5YOIJfTsmC59ri+dFvA3oBNSiTPUGGrklZw==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "@floating-ui/react-dom": "^2.0.2", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.9", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.9.tgz", + "integrity": "sha512-JAU/R5hM3l2zP1Q4KnioDRhq5V3vZ4mmjEZ+TwARDb2xFhg3p59McacQuzkSu0sUHJnH9aJos36+hU5sPQBcFQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.9.tgz", + "integrity": "sha512-xTRQbDsogsJo7tY5Og8R9zbuG2q+KIPVIM6JQoKxtJlz9DPOw1u0T2fGrvwD+XAOVifQf6epNMcGCDLfJAz4Nw==", + "dependencies": { + "@babel/runtime": "^7.22.15" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.9.tgz", + "integrity": "sha512-pbBy5kc5iUGXPxgbb+t+yEPvLK5nE3bPUb8WbAafJ8iZ40ZGui0xC4xiiIyzbVexzsLmyN7MaSo4LkxLmPKqUQ==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "@mui/base": "5.0.0-beta.15", + "@mui/core-downloads-tracker": "^5.14.9", + "@mui/system": "^5.14.9", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.9", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.9.tgz", + "integrity": "sha512-0PzoUFqFXTXiNchhR7K4b7kZunasPOjx6Qf7AagCmfZDNASHedA0x6evHVhnST918x/AHY9xykYNKfB0Z4xMBg==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "@mui/utils": "^5.14.9", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.9.tgz", + "integrity": "sha512-LEQxLrW9oWvea33pge08+oyNeTz704jb6Nhe26xEJKojXWd34Rr327Zzx3dmo70AcS4h0b99vQjEpUzm6ASqUw==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.9.tgz", + "integrity": "sha512-Z00Wj590QXk5+SIxmxayBo7SWrao+y433LKGChneJxO4QcT/caSCeEWtyeoLs1Q8ys0zOzl2kkKee6n8TaKzhQ==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "@mui/private-theming": "^5.14.9", + "@mui/styled-engine": "^5.14.9", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.9", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.9.tgz", + "integrity": "sha512-9ysB5e+RwS7ofn0n3nwAg1/3c81vBTmSvauD3EuK9LmqMzhmF//BFDaC44U4yITvB/0m1kWyDqg924Ll3VHCcg==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@next/env": { "version": "13.4.19", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.19.tgz", @@ -828,6 +1272,15 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", @@ -888,6 +1341,39 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/react": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", + "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", @@ -1282,6 +1768,43 @@ "dequal": "^2.0.3" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-plugin-macros/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1589,6 +2112,14 @@ "node": ">=0.8" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1751,6 +2282,11 @@ "node": ">=14" } }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, "node_modules/cosmiconfig": { "version": "8.3.5", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.5.tgz", @@ -1811,6 +2347,11 @@ "node": ">= 8" } }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, "node_modules/cz-conventional-changelog": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", @@ -2061,6 +2602,15 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -2100,7 +2650,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -2791,8 +3340,7 @@ "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "node_modules/find-up": { "version": "5.0.0", @@ -3220,6 +3768,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3415,8 +3971,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-async-function": { "version": "2.0.0", @@ -3826,8 +4381,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -3955,8 +4509,7 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { "version": "14.0.1", @@ -4963,7 +5516,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -5171,6 +5723,29 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-multi-carousel": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.8.4.tgz", + "integrity": "sha512-7Is5Wr+m2ebkR+oq2Su2tjUdBwpVtB2O6Tjb74KDNfxWe/FrsTQwezTJTk/r9cKCrRp9Li308v822/5bZm7XKg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -5688,6 +6263,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -5916,6 +6499,11 @@ } } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5987,6 +6575,14 @@ "node": ">=0.6.0" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 3126dcb..c9670e8 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,17 @@ "prepare": "husky install" }, "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.14.9", + "@mui/material": "^5.14.9", + "@mui/system": "^5.14.9", "eslint": "8.49.0", "eslint-config-next": "13.4.19", "next": "13.4.19", - "react": "18.2.0", - "react-dom": "18.2.0" + "react": "^18.2.0", + "react-dom": "18.2.0", + "react-multi-carousel": "^2.8.4" }, "devDependencies": { "@commitlint/cli": "^17.7.1", diff --git a/public/Home1.PNG b/public/Home1.PNG new file mode 100644 index 0000000..d69dc9e Binary files /dev/null and b/public/Home1.PNG differ diff --git a/public/footerbg.svg b/public/footerbg.svg new file mode 100644 index 0000000..51669b9 --- /dev/null +++ b/public/footerbg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/home2.PNG b/public/home2.PNG new file mode 100644 index 0000000..07eeea1 Binary files /dev/null and b/public/home2.PNG differ diff --git a/public/home3.PNG b/public/home3.PNG new file mode 100644 index 0000000..98f1b51 Binary files /dev/null and b/public/home3.PNG differ diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..43ed7c2 --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/play.svg b/public/play.svg new file mode 100644 index 0000000..f96259f --- /dev/null +++ b/public/play.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Buttons.jsx b/src/components/Buttons.jsx new file mode 100644 index 0000000..c57bed2 --- /dev/null +++ b/src/components/Buttons.jsx @@ -0,0 +1,11 @@ +import * as React from "react" +import Stack from "@mui/material/Stack" +import Button from "@mui/material/Button" + +export default function Buttons({ btext }) { + return ( + + ) +} diff --git a/src/components/Cards.jsx b/src/components/Cards.jsx new file mode 100644 index 0000000..0a237c2 --- /dev/null +++ b/src/components/Cards.jsx @@ -0,0 +1,50 @@ +import * as React from "react" +import Card from "@mui/material/Card" +import CardActions from "@mui/material/CardActions" +import CardContent from "@mui/material/CardContent" +import CardMedia from "@mui/material/CardMedia" +import Button from "@mui/material/Button" +import Typography from "@mui/material/Typography" +import styles from "@/styles/cards.module.css" + +export default function Cards({ + title, + overview, + poster_path, + release_date, + popularity, +}) { + const images = `https://image.tmdb.org/t/p/original${poster_path}` + + return ( + + + + +

{title}

+
{release_date}
+
+ + {overview} + + + Popularity: {popularity} + +
+
+ ) +} diff --git a/src/components/CardsSlider.jsx b/src/components/CardsSlider.jsx new file mode 100644 index 0000000..f2f76d2 --- /dev/null +++ b/src/components/CardsSlider.jsx @@ -0,0 +1,76 @@ +import React, { useState, useEffect } from "react" +import Box from "@mui/material/Box" +import { useTheme } from "@mui/material/styles" +import MobileStepper from "@mui/material/MobileStepper" +import Button from "@mui/material/Button" +import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft" +import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight" +import Card from "@mui/material/Card" +import CardActions from "@mui/material/CardActions" +import CardContent from "@mui/material/CardContent" +import CardMedia from "@mui/material/CardMedia" +import Buttons from "@/components/Buttons" +import "@/styles/slider.module.css" +import Image from "next/image" +import Cards from "@/components/Cards" +import SmallCards from "@/components/SmallCards" + +export default function CardsSlider({ movies }) { + const theme = useTheme() + const [activeStep, setActiveStep] = useState(0) + const itemsPerRow = 5 + const maxSteps = Math.ceil(movies.length / itemsPerRow) + const [loading, setLoading] = useState(true) + + const handleNext = () => { + setActiveStep((prevActiveStep) => + Math.min(prevActiveStep + 1, maxSteps - 1), + ) + } + + const handleBack = () => { + setActiveStep((prevActiveStep) => Math.max(prevActiveStep - 1, 0)) + } + + const startIndex = activeStep * itemsPerRow + const endIndex = Math.min(startIndex + itemsPerRow, movies.length) + const displayedMovies = movies.slice(startIndex, endIndex) + + useEffect(() => { + const timer = setTimeout(() => { + setLoading(false) + }, 2000) + + return () => clearTimeout(timer) + }, []) + + return ( + + + + + } + backButton={ + + } + /> +
+ {loading ? ( + + ) : ( + displayedMovies.map((movie, index) => ( +
+ +
+ )) + )} +
+
+ ) +} diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx new file mode 100644 index 0000000..8ce1dbb --- /dev/null +++ b/src/components/Footer/Footer.jsx @@ -0,0 +1,80 @@ +import styles from "@/styles/footer.module.css" +import GitHubIcon from "@mui/icons-material/GitHub" +export default function Footer() { + return ( +
+
+ + NeoCine Logo + +
+
+

team

+

Sidahmed slikh

+

Benarba Tewfik

+

Bouchra ikram aboura

+

Youssef sergma

+

imane omari

+

Melissa Sidi Said

+
+
+

linkedin

+ + linkedin/Sidahmed slikh + + + linkedin/Benarba Tewfik + + + linkedin/Bouchra ikram aboura + + linkedin/Youssef sergma + + linkedin/imane omari + + + linkedin/Melissa Sidi Said + +
+
+

github

+ + Zino0031 + + + Ben-Tewfik + + + ikoworld + + + ysergma + + + iman-om + + + milyssaSidisaid + +
+
+

source code:

+ + + +
+
+ ) +} diff --git a/src/components/GenresList.jsx b/src/components/GenresList.jsx new file mode 100644 index 0000000..8adcee1 --- /dev/null +++ b/src/components/GenresList.jsx @@ -0,0 +1,112 @@ +import * as React from "react" +import { styled, alpha } from "@mui/material/styles" +import Button from "@mui/material/Button" +import Menu from "@mui/material/Menu" +import MenuItem from "@mui/material/MenuItem" +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown" + +const StyledMenu = styled((props) => ( + +))(({ theme }) => ({ + "& .MuiPaper-root": { + borderRadius: 6, + marginTop: theme.spacing(1), + minWidth: 180, + color: + theme.palette.mode === "light" + ? "rgb(55, 65, 81)" + : theme.palette.grey[300], + boxShadow: + "rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px", + "& .MuiMenu-list": { + padding: "4px 0", + }, + "& .MuiMenuItem-root": { + "& .MuiSvgIcon-root": { + fontSize: 18, + color: theme.palette.text.secondary, + marginRight: theme.spacing(1.5), + }, + "&:active": { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity, + ), + }, + }, + }, +})) + +export default function GenresList({ Genres, tag, onGenreSelect }) { + const [anchorEl, setAnchorEl] = React.useState(null) + const open = Boolean(anchorEl) + const handleClick = (event) => { + setAnchorEl(event.currentTarget) + } + const handleClose = () => { + setAnchorEl(null) + } + const handleGenreSelect = (genreId) => { + onGenreSelect(genreId) + console.log("genre id is ", genreId) + handleClose() + } + + return ( +
+ + + {Genres && Genres.genres ? ( + Genres.genres.map((genre) => ( + handleGenreSelect(genre.id)} + key={genre.id} + disableRipple + > + {genre.name} + + )) + ) : ( + No genres available + )} + +
+ ) +} diff --git a/src/components/Layout.js b/src/components/Layout.js new file mode 100644 index 0000000..89536ff --- /dev/null +++ b/src/components/Layout.js @@ -0,0 +1,35 @@ +import { useEffect, useState } from "react" +import { fetcher } from "../../util/API" +import Navbar from "@/components/Navbar" +import Footer from "./Footer/Footer" + +const Layout = ({ children }) => { + const [genresMovie, setGenresMovie] = useState(null) + const [searchResults, setSearchResults] = useState([]) + const [selectedGenreId, setSelectedGenreId] = useState(null) + + const onSearch = async (query) => { + try { + const response = await fetcher( + `search/multi?query=${query}&include_adult=false&language=en-US&page=1`, + ) + + if (response.results && Array.isArray(response.results)) { + return response.results + } + } catch (error) { + console.error("Error fetching search results:", error) + return [] + } + } + + return ( +
+ + {children(genresMovie, searchResults)} +
+
+ ) +} + +export default Layout diff --git a/src/components/MoviesList.jsx b/src/components/MoviesList.jsx new file mode 100644 index 0000000..99e6a4a --- /dev/null +++ b/src/components/MoviesList.jsx @@ -0,0 +1,128 @@ +import React, { useState, useEffect } from "react" +import { styled, alpha } from "@mui/material/styles" +import Button from "@mui/material/Button" +import Menu from "@mui/material/Menu" +import MenuItem from "@mui/material/MenuItem" +import EditIcon from "@mui/icons-material/Edit" +import Divider from "@mui/material/Divider" +import ArchiveIcon from "@mui/icons-material/Archive" +import FileCopyIcon from "@mui/icons-material/FileCopy" +import MoreHorizIcon from "@mui/icons-material/MoreHoriz" +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown" +import { Box } from "@mui/material" +import { fetcher } from "../../util/API" +import { useRouter } from "next/router" + +const StyledMenu = styled((props) => ( + +))(({ theme }) => ({ + "& .MuiPaper-root": { + borderRadius: 6, + marginTop: theme.spacing(1), + minWidth: 180, + color: + theme.palette.mode === "light" + ? "rgb(55, 65, 81)" + : theme.palette.grey[300], + boxShadow: + "rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px", + "& .MuiMenu-list": { + padding: "4px 0", + }, + "& .MuiMenuItem-root": { + "& .MuiSvgIcon-root": { + fontSize: 18, + color: theme.palette.text.secondary, + marginRight: theme.spacing(1.5), + }, + "&:active": { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity, + ), + }, + }, + }, +})) + +export function MoviesList() { + const router = useRouter() + const { list } = router.query + const [movies, setMovies] = useState("") + const [selectedMovieList, setSelectedMovieList] = useState( + list || "top_rated", + ) + + const handleListSelect = (selectedMovieList) => { + router.push(`/movies?list=${selectedMovieList}`) + setAnchorEl(null) + } + + useEffect(() => { + setSelectedMovieList(list || "top_rated") + }, [list]) + + const [anchorEl, setAnchorEl] = React.useState(null) + const open = Boolean(anchorEl) + const handleClick = (event) => { + setAnchorEl(event.currentTarget) + } + const handleClose = () => { + setAnchorEl(null) + } + + return ( +
+ + + handleListSelect("popular")}>Popular + handleListSelect("top_rated")}> + Top Rated + + handleListSelect("now_playing")}> + Now Playing + + handleListSelect("upcoming")}> + Upcoming + + +
+ ) +} diff --git a/src/components/Moviescredits.jsx b/src/components/Moviescredits.jsx new file mode 100644 index 0000000..79c5887 --- /dev/null +++ b/src/components/Moviescredits.jsx @@ -0,0 +1,39 @@ +import React, { useState, useEffect } from "react" +import { fetcher } from "../../util/API" +import Cards from "./Cards" + +const Moviescredits = ({ actor_id }) => { + const [credits, setCredits] = useState([]) + const apiRoute = `person/88/movie_credits?language=en-US ` + const fetchCredits = async () => { + const data = await fetcher(apiRoute) + console.log(data.cast) + setCredits(data.cast) + } + useEffect(() => { + fetchCredits() + }, []) + { + if (credits) { + return ( +
+

Similar movies

+ {credits.map((credit, index) => ( +
+ {credit.title} + +
+ ))} +
+ ) + } else { + return "" + } + } +} + +export default Moviescredits diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx new file mode 100644 index 0000000..8bce3e5 --- /dev/null +++ b/src/components/Navbar.jsx @@ -0,0 +1,318 @@ +import * as React from "react" +import { styled, alpha } from "@mui/material/styles" +import AppBar from "@mui/material/AppBar" +import Box from "@mui/material/Box" +import Toolbar from "@mui/material/Toolbar" +import InputBase from "@mui/material/InputBase" +import SearchIcon from "@mui/icons-material/Search" +import Button from "@mui/material/Button" +import Menu from "@mui/material/Menu" +import Image from "next/image" +import GernresList from "./GenresList" +import { MoviesList } from "./MoviesList" +import Drawer from "@mui/material/Drawer" +import GenresList from "./GenresList" +import Link from "next/link" +import { useState, useEffect } from "react" +import { fetcher } from "../../util/API" +import { useRouter } from "next/router" +import Cards from "./Cards" +import styles from "@/styles/navbarSearch.module.css" + +// search component +const Search = styled("div")(({ theme }) => ({ + position: "relative", + borderRadius: theme.shape.borderRadius, + backgroundColor: alpha(theme.palette.common.white, 0.15), + "&:hover": { + backgroundColor: alpha(theme.palette.common.white, 0.25), + }, + marginLeft: 0, + width: "100%", + [theme.breakpoints.up("sm")]: { + marginLeft: theme.spacing(1), + width: "auto", + }, +})) + +const SearchIconWrapper = styled("div")(({ theme }) => ({ + padding: theme.spacing(0, 2), + height: "100%", + position: "absolute", + pointerEvents: "none", + display: "flex", + alignItems: "center", + justifyContent: "center", + fontSize: "1rem", +})) + +const StyledInputBase = styled(InputBase)(({ theme }) => ({ + color: "inherit", + "& .MuiInputBase-input": { + padding: theme.spacing(1, 1, 1, 0), + + paddingLeft: `calc(1em + ${theme.spacing(4)})`, + transition: theme.transitions.create("width"), + width: "100%", + [theme.breakpoints.up("sm")]: { + width: "12ch", + "&:focus": { + width: "20ch", + }, + }, + }, +})) + +const DrawerWrapper = styled(Box)(({ theme }) => ({ + width: "250px", + flexShrink: 0, + "& .MuiDrawer-paper": { + width: "250px", + }, +})) + +export default function Navbar({ + movieGenresList, + movieslist, + onSearch, + onGenreSelect, +}) { + const [anchorEl, setAnchorEl] = React.useState(null) + const [searchQuery, setSearchQuery] = React.useState("") + const [searchResults, setSearchResults] = React.useState([]) + const [isDrawerOpen, setDrawerOpen] = React.useState(false) + const [selectedGenre, setSelectedGenre] = React.useState(null) + const [selectedGenreId, setSelectedGenreId] = useState(null) + const [genresMovie, setGenresMovie] = useState(null) + const router = useRouter() + + const navigateToMovies = () => { + setTimeout(() => { + router.push("/movies") + }, 5000) + } + + useEffect(() => { + const fetchData = async () => { + const response = await fetcher("genre/movie/list?language=en") + setGenresMovie(response) + } + + fetchData() + }, []) + + const handleGenreSelect = (genreId) => { + setSelectedGenre(genreId) + router.push(`/movies?genre=${genreId}`) + console.log("genre in navbar is ", genreId) + } + + const open = Boolean(anchorEl) + + const handleClick = (event) => { + setAnchorEl(event.currentTarget) + } + + const handleClose = () => { + setAnchorEl(null) + } + + const handleSearch = async () => { + if (searchQuery.trim() === "") { + setSearchResults([]) + } + + const results = await onSearch(searchQuery) + setSearchResults(results) + setDrawerOpen(true) + } + + const closeDrawer = () => { + setDrawerOpen(false) + } + + return ( + + + +
+ + NeoCine Logo + +
+
+ + + + + + + +
+ + + + + setSearchQuery(e.target.value)} + onKeyPress={(e) => { + if (e.key === "Enter") { + handleSearch() + } + }} + /> + + + +
+
+ + +
+

Search Results:

+
    + {searchResults.map((result) => ( + <> +
  • + + {result.title} + +

    {result.title}

    + +

    + {result.release_date} +

    + +
  • + + ))} +
+
+
+
+
+ ) +} + +const StyledMenu = styled((props) => ( + +))(({ theme }) => ({ + "& .MuiPaper-root": { + borderRadius: 6, + marginTop: theme.spacing(1), + minWidth: 180, + color: + theme.palette.mode === "light" + ? "rgb(55, 65, 81)" + : theme.palette.grey[300], + boxShadow: + "rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px", + "& .MuiMenu-list": { + padding: "4px 0", + }, + "& .MuiMenuItem-root": { + "& .MuiSvgIcon-root": { + fontSize: 18, + color: theme.palette.text.secondary, + marginRight: theme.spacing(1.5), + }, + "&:active": { + backgroundColor: alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity, + ), + }, + }, + }, +})) + +export function ActorsBtn() { + return ( +
+ + + +
+ ) +} +export function HomeBtn() { + return ( +
+ + + +
+ ) +} diff --git a/src/components/Searchbar.jsx b/src/components/Searchbar.jsx new file mode 100644 index 0000000..86ea102 --- /dev/null +++ b/src/components/Searchbar.jsx @@ -0,0 +1,46 @@ +import { InputAdornment, TextField } from "@mui/material" +import IconButton from "@mui/material/IconButton" +import React, { useState } from "react" +import SearchIcon from "@mui/icons-material/Search" +import styles from "@/styles/movieSearchBar.module.css" + +export default function SearchBar({ onSearch, placeh = "Search..." }) { + const [searchTerm, setSearchTerm] = useState("") + + const handleChange = (event) => { + setSearchTerm(event.target.value) + } + + const handleSubmit = (event) => { + event.preventDefault() + onSearch(searchTerm) + } + + return ( +
+ + + + + + ), + }} + /> + + ) +} diff --git a/src/components/Slider.jsx b/src/components/Slider.jsx new file mode 100644 index 0000000..876be69 --- /dev/null +++ b/src/components/Slider.jsx @@ -0,0 +1,147 @@ +import * as React from "react" +import Box from "@mui/material/Box" +import { useTheme } from "@mui/material/styles" +import MobileStepper from "@mui/material/MobileStepper" +import Typography from "@mui/material/Typography" +import Button from "@mui/material/Button" +import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft" +import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight" +import Card from "@mui/material/Card" +import CardActions from "@mui/material/CardActions" +import CardContent from "@mui/material/CardContent" +import CardMedia from "@mui/material/CardMedia" +import Buttons from "@/components/Buttons" +import "@/styles/slider.module.css" +import { useState } from "react" +import styles from "@/styles/Home.module.css" +import Link from "next/link" + +export default function Slider({ movies }) { + const theme = useTheme() + const [activeStep, setActiveStep] = useState(0) + const maxSteps = movies.length + + const handleNext = () => { + setActiveStep((prevActiveStep) => prevActiveStep + 1) + } + + const handleBack = () => { + setActiveStep((prevActiveStep) => prevActiveStep - 1) + } + const linkStyle = { + textDecoration: "none", + color: "white", + transition: "color 0.3s, text-shadow 0.3s", + } + + const hoverStyle = { + color: "#Fcff09", + textShadow: "2px 2px 4px rgba(0, 0, 0, 0.5)", + } + + return ( + + +
+
+ + + + + + + + + + + +
+ +
+ + Object.assign(e.target.style, hoverStyle)} + onMouseLeave={(e) => Object.assign(e.target.style, linkStyle)} + > + + {movies[activeStep].title} + + + + + + + Continue + Watching + + } + /> + + +
+ + {theme.direction === "rtl" ? ( + + ) : ( + + )} + + } + backButton={ + + } + /> +
+ ) +} diff --git a/src/components/SmallCards.jsx b/src/components/SmallCards.jsx new file mode 100644 index 0000000..e9e37f0 --- /dev/null +++ b/src/components/SmallCards.jsx @@ -0,0 +1,81 @@ +import React from "react" +import PropTypes from "prop-types" +import Grid from "@mui/material/Grid" +import Box from "@mui/material/Box" +import Typography from "@mui/material/Typography" +import Skeleton from "@mui/material/Skeleton" +import Rating from "@mui/material/Rating" +import Link from "next/link" +function SmallCards({ + title, + vote_average, + release_date, + backdrop_path, + loading, + name, + id, +}) { + const imageSrc = `https://image.tmdb.org/t/p/original${backdrop_path}` + const linkStyle = { + textDecoration: "none", + color: "#F5C518", + } + + const hoverStyle = { + color: "#F7FF33", + textShadow: "2px 2px 4px rgba(255, 255, 255, 0.5)", + } + return ( + + + {loading ? ( + <> + + + + + + + ) : ( + <> + Object.assign(e.target.style, hoverStyle)} + onMouseLeave={(e) => Object.assign(e.target.style, linkStyle)} + > + {title} + + + {title || name} + + + {" "} + {release_date} + + + + + )} + + + ) +} + +SmallCards.propTypes = { + title: PropTypes.string, + overview: PropTypes.string, + poster_path: PropTypes.string, + loading: PropTypes.bool, +} + +export default SmallCards diff --git a/src/components/Tvcredits.jsx b/src/components/Tvcredits.jsx new file mode 100644 index 0000000..1b886d2 --- /dev/null +++ b/src/components/Tvcredits.jsx @@ -0,0 +1,39 @@ +import React, { useState, useEffect } from "react" +import { fetcher } from "../../util/API" +import Cards from "./Cards" + +const Tvcredits = ({ actor_id }) => { + const [credits, setCredits] = useState([]) + const apiRoute = `person/${actor_id}/tv_credits?language=en-US` + const fetchCredits = async () => { + const data = await fetcher(apiRoute) + console.log(data.cast) + setCredits(data.cast) + } + useEffect(() => { + fetchCredits() + }, []) + { + if (credits) { + return ( +
+

Similar Tv Shows

+ {credits.map((credit, index) => ( +
+ {credit.title} + +
+ ))} +
+ ) + } else { + return "" + } + } +} + +export default Tvcredits diff --git a/src/components/singleActor/ActorPages.jsx b/src/components/singleActor/ActorPages.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/singleMovie/BasicRating.jsx b/src/components/singleMovie/BasicRating.jsx new file mode 100644 index 0000000..95d5a61 --- /dev/null +++ b/src/components/singleMovie/BasicRating.jsx @@ -0,0 +1,18 @@ +import React from "react" +import Box from "@mui/material/Box" +import Rating from "@mui/material/Rating" +import Typography from "@mui/material/Typography" + +export default function BasicRating({ movie }) { + return ( + legend": { mt: 2 }, + display: "inline-block", + }} + > + || {movie.runtime} min + + + ) +} diff --git a/src/components/singleMovie/Container.jsx b/src/components/singleMovie/Container.jsx new file mode 100644 index 0000000..4a25b5f --- /dev/null +++ b/src/components/singleMovie/Container.jsx @@ -0,0 +1,41 @@ +import * as React from "react" +import SizeAvatars from "@/components/singleMovie/actorAvatar" +import Moviecards from "./similarMovies" +import styles from "@/styles/Home.module.css" +import CardsSlider from "@/components/CardsSlider" + +export default function TrailerActorContainer({ + relatedMovies, + actors, + video, +}) { + const array1 = actors.cast.slice(0, 5) + const array2 = relatedMovies.slice(0, 20) + + return ( + <> +
+
+
+

Trailer:

+ +
+ +
+

Actors:

+ +
+
+ +
+

Similar:

+ +
+ + ) +} diff --git a/src/components/singleMovie/Poster.jsx b/src/components/singleMovie/Poster.jsx new file mode 100644 index 0000000..59c4c29 --- /dev/null +++ b/src/components/singleMovie/Poster.jsx @@ -0,0 +1,24 @@ +//poster component +// import Card from "@mui/material/Card" +// import CardActions from "@mui/material/CardActions" +// import CardContent from "@mui/material/CardContent" +// import CardMedia from "@mui/material/CardMedia" +// import Button from "@mui/material/Button" +// import Typography from "@mui/material/Typography" +import * as React from "react" +import SimpleContainer from "./poster_components/SimpleContainer" + +export default function Poster({ movie, credits }) { + const imageUrl = `https://image.tmdb.org/t/p/w500/${movie.backdrop_path}` + + return ( + <> + + + ) +} diff --git a/src/components/singleMovie/actorAvatar.jsx b/src/components/singleMovie/actorAvatar.jsx new file mode 100644 index 0000000..369a7fc --- /dev/null +++ b/src/components/singleMovie/actorAvatar.jsx @@ -0,0 +1,42 @@ +//actor avatar component +import * as React from "react" +import Avatar from "@mui/material/Avatar" +import Stack from "@mui/material/Stack" +import Link from "next/link" + +export default function SizeAvatars({ array }) { + const linkStyle = { + textDecoration: "none", + color: "white", + transition: "color 0.3s, text-shadow 0.3s", + } + + const hoverStyle = { + color: "#Fcff09", + textShadow: "2px 2px 4px rgba(0, 0, 0, 0.5)", + } + return ( +
+ + {array.map((actor, index) => ( + Object.assign(e.target.style, hoverStyle)} + onMouseLeave={(e) => Object.assign(e.target.style, linkStyle)} + > +
+ + {actor.name} +
+ + ))} +
+
+ ) +} diff --git a/src/components/singleMovie/poster_components/SimpleContainer.jsx b/src/components/singleMovie/poster_components/SimpleContainer.jsx new file mode 100644 index 0000000..fc33cf7 --- /dev/null +++ b/src/components/singleMovie/poster_components/SimpleContainer.jsx @@ -0,0 +1,71 @@ +import * as React from "react" +import BasicRating from "../BasicRating" +import Buttons from "@/components/Buttons" +import Image from "next/image" +import styles from "@/styles/Single.module.css" +import Container from "@/components/singleMovie/Container" + +export default function SimpleContainer({ + movie, + image, + productionCompany, + director, +}) { + const direc = director.cast.find( + (member) => member.known_for_department === "Directing", + ) + + return ( + +
+
+
+

{movie.title}

+ +

{movie.overview}


+
+ {" "} +

Director:

+

{direc ? direc.name : "Not available"}

+
{" "} +
+ Release date : {movie.release_date}
language:{" "} + {movie.original_language}{" "} +
+
+ Actor Image +
+
+ + {" "} + +
+
+ Production companies:
+ {productionCompany.map((company) => ( +
+ {" "} +
+                  {company.name}{" "}
+                
+ logo +
+ ))} +
+
+
+
+ ) +} diff --git a/src/components/singleMovie/similarMovies.jsx b/src/components/singleMovie/similarMovies.jsx new file mode 100644 index 0000000..e0c4048 --- /dev/null +++ b/src/components/singleMovie/similarMovies.jsx @@ -0,0 +1,19 @@ +import React from "react" +import Cards from "../Cards" + +export default function Moviecards({ array }) { + return ( + <> +
+ {array.map((film, index) => ( + + ))} +
+ + ) +} diff --git a/src/pages/[movieId].js b/src/pages/[movieId].js new file mode 100644 index 0000000..f498508 --- /dev/null +++ b/src/pages/[movieId].js @@ -0,0 +1,41 @@ +import React from "react" +import Poster from "@/components/singleMovie/Poster" +import { fetcher } from "../../util/API" +import TrailerActorContainer from "@/components/singleMovie/Container" + +export default function MoviePage({ movie, credits, trailer, similar }) { + const video = trailer.results.find((result) => result) + const relatedMovies = similar.results.map((result) => result) + return ( + <> + +

+ + + ) +} + +// Define the getServerSideProps function to fetch data for a specific movie +export async function getServerSideProps(context) { + const { movieId } = context.query + + const movie = await fetcher(`/movie/${movieId}?language=en-US`) + const credits = await fetcher(`/movie/${movieId}/credits?language=en-US`) + const trailer = await fetcher(`/movie/${movieId}/videos?language=en-US`) + const similar = await fetcher( + `/movie/${movieId}/similar?language=en-US&page=1`, + ) + + return { + props: { + movie: movie, + credits: credits, + trailer: trailer, + similar: similar, + }, + } +} diff --git a/src/pages/_app.js b/src/pages/_app.js index 63b9c71..7b46437 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -1,5 +1,12 @@ +import "@/styles/slider.module.css" import "@/styles/globals.css" +import { fetcher } from "../../util/API" +import Layout from "@/components/Layout" -export default function App({ Component, pageProps }) { - return +export default function App({ Component, pageProps, genresMovie }) { + return ( + + {(genresMovie) => } + + ) } diff --git a/src/pages/_document.js b/src/pages/_document.js index 097cb7f..c7f48b1 100644 --- a/src/pages/_document.js +++ b/src/pages/_document.js @@ -1,13 +1,24 @@ +import Navbar from "@/components/Navbar" import { Html, Head, Main, NextScript } from "next/document" -export default function Document() { +export default function Document({ movieGenresList }) { return ( + {/* */} +
) } +export async function getStaticProps() { + const genresData = await fetcher("genre/movie/list?language=en") + return { + props: { + props: { movieGenresList: genresData }, + }, + } +} diff --git a/src/pages/actor/[actorId].js b/src/pages/actor/[actorId].js new file mode 100644 index 0000000..fcf27c8 --- /dev/null +++ b/src/pages/actor/[actorId].js @@ -0,0 +1,93 @@ +import React from "react" +import Poster from "@/components/singleMovie/Poster" +import { fetcher } from "../../../util/API" +import TrailerActorContainer from "@/components/singleMovie/Container" +import ActorPages from "@/components/singleActor/ActorPages" +import Moviecards from "@/components/singleMovie/similarMovies" +import CardsSlider from "@/components/CardsSlider" + +export default function ActorPage({ actor, similar }) { + const relatedMovies = similar.cast.map((result) => result) + const array2 = relatedMovies.slice(0, 20) + console.log("this is actor", actor) + return ( +
+
+
+ {actor.profile_path && ( + {actor.name} + )} +
+ {actor.name &&

{actor.name}

} + {actor.gender !== undefined && ( +

Gender: {actor.gender === 1 ? "Female" : "Male"}

+ )} + {actor.popularity !== undefined && ( +

Popularity: {actor.popularity}

+ )} + {actor.birthday &&

Birthday: {actor.birthday}

} + {actor.biography &&

Biography: {actor.biography}

} +
+
+ +
+
+

Similar:

+ +
+
+
+
+ ) +} + +// Define the getServerSideProps function to fetch data for a specific actor +export async function getServerSideProps(context) { + const { actorId } = context.query + + const actor = await fetcher(`person/${actorId}?language=en-US`) + const similar = await fetcher( + `person/${actorId}/movie_credits?language=en-US`, + ) + + return { + props: { + actor: actor, + similar: similar, + }, + } +} diff --git a/src/pages/actor/index.js b/src/pages/actor/index.js new file mode 100644 index 0000000..e2181e7 --- /dev/null +++ b/src/pages/actor/index.js @@ -0,0 +1,53 @@ +import { Grid } from "@mui/material" +import { fetcher } from "../../../util/API" +import Cards from "@/components/Cards" +import Link from "next/link" +import styles from "@/styles/movies.module.css" +import SearchBar from "@/components/Searchbar" +import { useState, useEffect } from "react" + +const Actors = ({ latestactor }) => { + const [searchTerm, setSearchTerm] = useState("") + const [searchResults, setSearchResults] = useState([]) + // search/person?query=1&include_adult=false&langua + const handleSearch = async (searchTerm) => { + const apiRoute = `search/person?query=${searchTerm}&include_adult=false&language=en-US` + const data = await fetcher(apiRoute) + setSearchResults(data.results) + } + useEffect(() => { + handleSearch(searchTerm) + }, [searchTerm]) + const actorsToDisplay = searchTerm ? searchResults : latestactor.results + return ( +
+ + + + {actorsToDisplay.map((actor) => { + return ( + + + + + + ) + })} + +
+ ) +} +export default Actors + +export async function getStaticProps() { + const data = await fetcher("person/popular?language=en-US&page=1") + return { + props: { + latestactor: data, + }, + } +} diff --git a/src/pages/actors.jsx b/src/pages/actors.jsx new file mode 100644 index 0000000..a748fcc --- /dev/null +++ b/src/pages/actors.jsx @@ -0,0 +1,10 @@ +import react from "react" +import * as React from "react" +import { Button } from "@mui/material/Button" + +function actor() { + ;
+ +