From 1624cb4428d6837ed366e930fcbc6eeaa862a8e8 Mon Sep 17 00:00:00 2001 From: rishav_dml Date: Tue, 7 Jan 2025 14:52:05 +0530 Subject: [PATCH 1/5] Partial Done --- package-lock.json | 13 ++++++++++- package.json | 3 ++- src/components/Card.jsx | 15 ++++++------ src/components/Header.jsx | 2 +- src/hooks/useFetch.jsx | 12 ++++++---- src/pages/HomePage.jsx | 48 ++++++++++++++++++++++++++++----------- 6 files changed, 65 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cc2d13..7dcc4be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "axios": "^1.7.9", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^7.1.1" + "react-router-dom": "^7.1.1", + "react-spinners": "^0.15.0" }, "devDependencies": { "@eslint/js": "^9.17.0", @@ -5219,6 +5220,16 @@ "react-dom": ">=18" } }, + "node_modules/react-spinners": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.15.0.tgz", + "integrity": "sha512-ZO3/fNB9Qc+kgpG3SfdlMnvTX6LtLmTnOogb3W6sXIaU/kZ1ydEViPfZ06kSOaEsor58C/tzXw2wROGQu3X2pA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/package.json b/package.json index be42d8c..936f843 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "axios": "^1.7.9", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^7.1.1" + "react-router-dom": "^7.1.1", + "react-spinners": "^0.15.0" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/src/components/Card.jsx b/src/components/Card.jsx index 245a292..a06131a 100644 --- a/src/components/Card.jsx +++ b/src/components/Card.jsx @@ -1,13 +1,14 @@ import React from "react"; -const Card = ({movie}) => { - const { Title, Year, imdbID, Poster } = movie - console.log("Card", Title, Year, imdbID, Poster) +const Card = ({ movie }) => { + const { Title, Year, imdbID, Poster } = movie; return ( -
- {Title} -
{Title}
-

{Year}

+
+ {Title} +
+
{Title}
+

{Year}

+
); }; diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 109f016..4954f4e 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -2,7 +2,7 @@ import React from 'react' const Header = () => { return ( -
+
DigiFlix
) diff --git a/src/hooks/useFetch.jsx b/src/hooks/useFetch.jsx index a8f8036..c132583 100644 --- a/src/hooks/useFetch.jsx +++ b/src/hooks/useFetch.jsx @@ -3,22 +3,24 @@ import { useState, useEffect } from "react"; const useFetch = (url) => { const [data, setData] = useState({}); + const [loading, setLoading] = useState(false) + const [error, setError] = useState({}) useEffect(() => { // console.log("Inside fetch") const fetch = async () => { let response; try { + setLoading(true); response = await axios.get(url); - // console.log("USEFETCH:", response?.data); setData(response?.data); - } catch { - console.log("Error in useFetch: "); - return "Error Fetching Data"; + setLoading(false); + } catch(error) { + setError(error) } }; fetch(); }, [url]); - return data; + return { data, loading, error}; }; export default useFetch; diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 1ff1706..55981c6 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,25 +1,34 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import useFetch from "../hooks/useFetch"; +import { Pagination } from "@mui/material"; +import { ClipLoader } from "react-spinners"; + import Card from "../components/Card"; const HomePage = () => { + const url = import.meta.env.VITE_BASE_URL; + const [inputValue, setInputValue] = useState(""); const [searchValue, setSearchValue] = useState(""); - const [data, setData] = useState(""); + const [page, setPage] = useState(1); + const { data, loading, error } = useFetch( + url + "&s=" + searchValue + "&page=" + page + ); - const url = import.meta.env.VITE_BASE_URL; - const response = useFetch(url + "s=" + searchValue); - console.log(response) - useEffect(() => setData(response), [data]); + console.log(page); + + const handlePageChange = (e) => { + setPage(e?.target?.textContent); + }; const handleSearch = (event) => { event.preventDefault(); setSearchValue(inputValue); }; return ( -
+
-
+ { />
- {data?.Search?.length > 0 && -
- {data?.Search?.map((movie) => )} + {data?.Search?.length > 0 && ( +
+ +
+ {data?.Search?.map((movie) => ( + + ))} +
+
- } + )}
); }; -- 2.43.0 From 9c716978b3b939f12626e894c968cdaddd6fa169 Mon Sep 17 00:00:00 2001 From: rishav_dml Date: Wed, 8 Jan 2025 11:27:02 +0530 Subject: [PATCH 2/5] Fixed consoles and added custom spinner --- src/hooks/useFetch.jsx | 1 - src/pages/HomePage.jsx | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hooks/useFetch.jsx b/src/hooks/useFetch.jsx index c132583..abe64ef 100644 --- a/src/hooks/useFetch.jsx +++ b/src/hooks/useFetch.jsx @@ -6,7 +6,6 @@ const useFetch = (url) => { const [loading, setLoading] = useState(false) const [error, setError] = useState({}) useEffect(() => { - // console.log("Inside fetch") const fetch = async () => { let response; try { diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 55981c6..36c5432 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -16,8 +16,6 @@ const HomePage = () => { url + "&s=" + searchValue + "&page=" + page ); - console.log(page); - const handlePageChange = (e) => { setPage(e?.target?.textContent); }; @@ -50,7 +48,14 @@ const HomePage = () => {
{data?.Search?.length > 0 && (
- + {/* */} + {loading && ( + + )}
{data?.Search?.map((movie) => ( -- 2.43.0 From 4fdc869fd054025b89ff57e42d8323ea9bc7da67 Mon Sep 17 00:00:00 2001 From: rishav_dml Date: Wed, 8 Jan 2025 11:30:04 +0530 Subject: [PATCH 3/5] Removed package and imports for react-spinner --- package-lock.json | 13 +------------ package.json | 3 +-- src/pages/HomePage.jsx | 2 -- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7dcc4be..8cc2d13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,7 @@ "axios": "^1.7.9", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^7.1.1", - "react-spinners": "^0.15.0" + "react-router-dom": "^7.1.1" }, "devDependencies": { "@eslint/js": "^9.17.0", @@ -5220,16 +5219,6 @@ "react-dom": ">=18" } }, - "node_modules/react-spinners": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.15.0.tgz", - "integrity": "sha512-ZO3/fNB9Qc+kgpG3SfdlMnvTX6LtLmTnOogb3W6sXIaU/kZ1ydEViPfZ06kSOaEsor58C/tzXw2wROGQu3X2pA==", - "license": "MIT", - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/package.json b/package.json index 936f843..be42d8c 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,7 @@ "axios": "^1.7.9", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router-dom": "^7.1.1", - "react-spinners": "^0.15.0" + "react-router-dom": "^7.1.1" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 36c5432..7b9f261 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -2,7 +2,6 @@ import React, { useState } from "react"; import useFetch from "../hooks/useFetch"; import { Pagination } from "@mui/material"; -import { ClipLoader } from "react-spinners"; import Card from "../components/Card"; @@ -48,7 +47,6 @@ const HomePage = () => {
{data?.Search?.length > 0 && (
- {/* */} {loading && ( Date: Wed, 8 Jan 2025 18:30:03 +0530 Subject: [PATCH 4/5] Day02- Fixed: styles, Added:Favourite list --- src/components/Card.jsx | 19 ++++++++- src/components/Header.jsx | 3 +- src/components/Star.jsx | 56 +++++++++++++++++++++++++++ src/pages/HomePage.jsx | 81 ++++++++++++++++++++++++++------------- tailwind.config.js | 8 ++-- 5 files changed, 133 insertions(+), 34 deletions(-) create mode 100644 src/components/Star.jsx diff --git a/src/components/Card.jsx b/src/components/Card.jsx index a06131a..5bed6ce 100644 --- a/src/components/Card.jsx +++ b/src/components/Card.jsx @@ -1,9 +1,24 @@ import React from "react"; +import Star from "./Star"; -const Card = ({ movie }) => { +const Card = ({ movie, favouriteList, setFavouriteList }) => { const { Title, Year, imdbID, Poster } = movie; return ( -
+
+ {favouriteList?.includes(imdbID) ? ( + + ) : ( + + )} {Title}
{Title}
diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 4954f4e..6bba220 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -1,9 +1,10 @@ import React from 'react' +import { Link } from 'react-router-dom'; const Header = () => { return (
- DigiFlix + DigiFlix
) }; diff --git a/src/components/Star.jsx b/src/components/Star.jsx new file mode 100644 index 0000000..398b6be --- /dev/null +++ b/src/components/Star.jsx @@ -0,0 +1,56 @@ +import React from "react"; + +const Star = ({ + size = 5, + fill = "#00000000", + stroke = "#DAA520", + favouriteList, + setFavouriteList, + movie, +}) => { + // Calculate points for a five-pointed star + const points = []; + const outerRadius = size / 2; + const innerRadius = outerRadius * 0.382; // Golden ratio + + for (let i = 0; i < 10; i++) { + const radius = i % 2 === 0 ? outerRadius : innerRadius; + const angle = (Math.PI / 5) * i - Math.PI / 2; + const x = radius * Math.cos(angle) + size / 2; + const y = radius * Math.sin(angle) + size / 2; + points.push(`${x},${y}`); + } + + const handleFavouriteList = () => { + favouriteList?.includes(movie?.imdbID) + ? setFavouriteList((prevList) => + prevList?.filter((id) => id !== movie?.imdbID) + ) + : setFavouriteList((prevList) => [...prevList, movie?.imdbID]); + let localStorageData = JSON.parse(window.localStorage.getItem("favouriteMovies")); + console.log(localStorageData) + window.localStorage.setItem("favouriteMovies", JSON.stringify({movies: [...localStorageData, movie]})); + }; + + return ( + + + + ); +}; + +export default Star; diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 7b9f261..2470691 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -11,10 +11,11 @@ const HomePage = () => { const [inputValue, setInputValue] = useState(""); const [searchValue, setSearchValue] = useState(""); const [page, setPage] = useState(1); + const [favouriteList, setFavouriteList] = useState([]); + const [showFavourite, setShowFavourite] = useState(false); const { data, loading, error } = useFetch( url + "&s=" + searchValue + "&page=" + page ); - const handlePageChange = (e) => { setPage(e?.target?.textContent); }; @@ -24,7 +25,7 @@ const HomePage = () => { }; return (
-
+
{ onChange={(event) => setInputValue(event?.target?.value) } - className="p-1 text-quadnary bg-primary rounded outline-none border border-ternary" + className="p-1 text-quadnary bg-secondary focus:bg-secondary rounded outline-none border border-ternary" />
-
- {data?.Search?.length > 0 && ( -
- {loading && ( - - )} -
- {data?.Search?.map((movie) => ( - - ))} -
- + + setShowFavourite((prev) => !prev)} />
- )} +
+ {(showFavourite && ( +
+ {favouriteList?.map((movie) => ( + + ))} +
+ )) || + (data?.Search?.length > 0 && ( +
+ {loading && ( + + )} +
+ {data?.Search?.map((movie) => ( + + ))} +
+ +
+ ))}
); }; diff --git a/tailwind.config.js b/tailwind.config.js index 73fb346..e21705e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -2,10 +2,10 @@ export default { content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], theme: { colors: { - primary: "#191A19", - secondary: "#1E5128", - ternary: "#4E9F3D", - quadnary: "#D8E9A8", + primary: "#6B8A7A", + secondary: "#254336", + ternary: "#B7B597", + quadnary: "#DAD3BE", }, extend: {}, }, -- 2.43.0 From 40ed26f5afe35e91378d53ea2057ba264107e854 Mon Sep 17 00:00:00 2001 From: rishav_dml Date: Thu, 9 Jan 2025 12:05:25 +0530 Subject: [PATCH 5/5] Added: Favourite list feature --- src/components/Card.jsx | 4 +- src/components/Star.jsx | 10 ++-- src/hooks/{useFetch.jsx => useFetch.js} | 0 src/pages/HomePage.jsx | 72 +++++++++++++++++++++---- 4 files changed, 67 insertions(+), 19 deletions(-) rename src/hooks/{useFetch.jsx => useFetch.js} (100%) diff --git a/src/components/Card.jsx b/src/components/Card.jsx index 5bed6ce..ae43117 100644 --- a/src/components/Card.jsx +++ b/src/components/Card.jsx @@ -2,10 +2,10 @@ import React from "react"; import Star from "./Star"; const Card = ({ movie, favouriteList, setFavouriteList }) => { - const { Title, Year, imdbID, Poster } = movie; + const { Title, Year, Poster } = movie; return (
- {favouriteList?.includes(imdbID) ? ( + {favouriteList?.includes(movie) ? ( { - favouriteList?.includes(movie?.imdbID) + favouriteList?.includes(movie) ? setFavouriteList((prevList) => - prevList?.filter((id) => id !== movie?.imdbID) + prevList?.filter((movieItem) => movieItem !== movie) ) - : setFavouriteList((prevList) => [...prevList, movie?.imdbID]); - let localStorageData = JSON.parse(window.localStorage.getItem("favouriteMovies")); - console.log(localStorageData) - window.localStorage.setItem("favouriteMovies", JSON.stringify({movies: [...localStorageData, movie]})); + : setFavouriteList((prevList) => [...prevList, movie]); + }; return ( diff --git a/src/hooks/useFetch.jsx b/src/hooks/useFetch.js similarity index 100% rename from src/hooks/useFetch.jsx rename to src/hooks/useFetch.js diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 2470691..11f8304 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import useFetch from "../hooks/useFetch"; import { Pagination } from "@mui/material"; @@ -11,8 +11,16 @@ const HomePage = () => { const [inputValue, setInputValue] = useState(""); const [searchValue, setSearchValue] = useState(""); const [page, setPage] = useState(1); - const [favouriteList, setFavouriteList] = useState([]); + const [favouriteList, setFavouriteList] = useState( + JSON.parse(window.localStorage.getItem("favouriteMovies")) ?? [] + ); const [showFavourite, setShowFavourite] = useState(false); + + useEffect(() => { + window.localStorage.setItem("favouriteMovies", JSON.stringify(favouriteList)) + console.log(favouriteList); + }, [favouriteList]); + const { data, loading, error } = useFetch( url + "&s=" + searchValue + "&page=" + page ); @@ -57,15 +65,15 @@ const HomePage = () => {
{(showFavourite && (
- {favouriteList?.map((movie) => ( - - ))} -
+ {favouriteList?.map((movie) => ( + + ))} +
)) || (data?.Search?.length > 0 && (
@@ -101,3 +109,45 @@ const HomePage = () => { }; export default HomePage; + +function SearchBar({ + inputValue, + event, + setInputValue, + target, + value, + handleSearch, + setShowFavourite, + prev, +}) { + return ( +
+
+ setInputValue(event?.target?.value)} + className="p-1 text-quadnary bg-secondary focus:bg-secondary rounded outline-none border border-ternary" + /> + +
+
+ + setShowFavourite((prev) => !prev)} + /> +
+
+ ); +} -- 2.43.0