Compare commits
No commits in common. "f8ce4e8a6b407e36d6725c6a88660ae001e9c1bf" and "2f57426444bd8d0cfb8d6d7779b5e6737c95ddbf" have entirely different histories.
f8ce4e8a6b
...
2f57426444
|
@ -1,29 +1,13 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Star from "./Star";
|
|
||||||
|
|
||||||
const Card = ({ movie, favouriteList, setFavouriteList }) => {
|
const Card = ({movie}) => {
|
||||||
const { Title, Year, Poster } = movie;
|
const { Title, Year, imdbID, Poster } = movie
|
||||||
|
console.log("Card", Title, Year, imdbID, Poster)
|
||||||
return (
|
return (
|
||||||
<div className="relative h-[30vh] w-[10vw] overflow-hidden border rounded-lg border-quadnary bg-secondary">
|
<div className="h-16 w-10">
|
||||||
{favouriteList?.includes(movie) ? (
|
<img src={Poster} alt={Title} className="h-12 w-full" />
|
||||||
<Star
|
<h6 className="text-quadnary">{Title}</h6>
|
||||||
fill="#FFD700"
|
<p className="text-quadnary">{Year}</p>
|
||||||
favouriteList={favouriteList}
|
|
||||||
setFavouriteList={setFavouriteList}
|
|
||||||
movie={movie}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Star
|
|
||||||
favouriteList={favouriteList}
|
|
||||||
setFavouriteList={setFavouriteList}
|
|
||||||
movie={movie}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<img src={Poster} alt={Title} className="h-[85%] w-full" />
|
|
||||||
<div className="flex justify-between px-3 pt-1 text-sm">
|
|
||||||
<h6 className="text-quadnary">{Title}</h6>
|
|
||||||
<p className="text-quadnary font-semibold">{Year}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="fixed z-20 w-full h-[5vh] py-3 px-6 bg-secondary">
|
<header className="fixed w-full h-[5vh] py-3 px-6 bg-secondary">
|
||||||
<Link href="/" className='text-quadnary text-2xl font-semibold'>DigiFlix</Link>
|
<a href="/">DigiFlix</a>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
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)
|
|
||||||
? setFavouriteList((prevList) =>
|
|
||||||
prevList?.filter((movieItem) => movieItem !== movie)
|
|
||||||
)
|
|
||||||
: setFavouriteList((prevList) => [...prevList, movie]);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
height="1em"
|
|
||||||
width="1em"
|
|
||||||
viewBox={`0 0 ${size} ${size}`}
|
|
||||||
className="absolute top-1 right-1"
|
|
||||||
onClick={handleFavouriteList}
|
|
||||||
>
|
|
||||||
<polygon
|
|
||||||
height="1em"
|
|
||||||
width="1em"
|
|
||||||
points={points.join(" ")}
|
|
||||||
fill={fill}
|
|
||||||
stroke={stroke}
|
|
||||||
strokeWidth={size / 15}
|
|
||||||
className="drop-shadow-2xl shadow-[#000] shadow-2xl"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Star;
|
|
|
@ -3,23 +3,22 @@ import { useState, useEffect } from "react";
|
||||||
|
|
||||||
const useFetch = (url) => {
|
const useFetch = (url) => {
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
const [error, setError] = useState({})
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// console.log("Inside fetch")
|
||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
|
||||||
response = await axios.get(url);
|
response = await axios.get(url);
|
||||||
|
// console.log("USEFETCH:", response?.data);
|
||||||
setData(response?.data);
|
setData(response?.data);
|
||||||
setLoading(false);
|
} catch {
|
||||||
} catch(error) {
|
console.log("Error in useFetch: ");
|
||||||
setError(error)
|
return "Error Fetching Data";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetch();
|
fetch();
|
||||||
}, [url]);
|
}, [url]);
|
||||||
return { data, loading, error};
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useFetch;
|
export default useFetch;
|
|
@ -1,40 +1,25 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import useFetch from "../hooks/useFetch";
|
import useFetch from "../hooks/useFetch";
|
||||||
|
|
||||||
import { Pagination } from "@mui/material";
|
|
||||||
|
|
||||||
import Card from "../components/Card";
|
import Card from "../components/Card";
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
const url = import.meta.env.VITE_BASE_URL;
|
|
||||||
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
const [searchValue, setSearchValue] = useState("");
|
const [searchValue, setSearchValue] = useState("");
|
||||||
const [page, setPage] = useState(1);
|
const [data, setData] = useState("");
|
||||||
const [favouriteList, setFavouriteList] = useState(
|
|
||||||
JSON.parse(window.localStorage.getItem("favouriteMovies")) ?? []
|
|
||||||
);
|
|
||||||
const [showFavourite, setShowFavourite] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const url = import.meta.env.VITE_BASE_URL;
|
||||||
window.localStorage.setItem("favouriteMovies", JSON.stringify(favouriteList))
|
const response = useFetch(url + "s=" + searchValue);
|
||||||
console.log(favouriteList);
|
console.log(response)
|
||||||
}, [favouriteList]);
|
useEffect(() => setData(response), [data]);
|
||||||
|
|
||||||
const { data, loading, error } = useFetch(
|
|
||||||
url + "&s=" + searchValue + "&page=" + page
|
|
||||||
);
|
|
||||||
const handlePageChange = (e) => {
|
|
||||||
setPage(e?.target?.textContent);
|
|
||||||
};
|
|
||||||
const handleSearch = (event) => {
|
const handleSearch = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setSearchValue(inputValue);
|
setSearchValue(inputValue);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className=" min-h-[90vh] w-full pt-[10vh] bg-primary flex flex-col items-center ">
|
<div className=" min-h-[90vh] w-full pt-[10vh] bg-primary flex justify-center">
|
||||||
<div className="flex items-center gap-10">
|
<div>
|
||||||
<form className="flex gap-3 items-center">
|
<form className="">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="search"
|
name="search"
|
||||||
|
@ -43,111 +28,24 @@ const HomePage = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setInputValue(event?.target?.value)
|
setInputValue(event?.target?.value)
|
||||||
}
|
}
|
||||||
className="p-1 text-quadnary bg-secondary focus:bg-secondary rounded outline-none border border-ternary"
|
className="p-1 text-quadnary bg-primary rounded outline-none border border-ternary"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="px-4 py-1 font-semibold h-full rounded border border-quadnary text-quadnary bg-secondary"
|
className="text-quadnary"
|
||||||
onClick={handleSearch}
|
onClick={handleSearch}
|
||||||
>
|
>
|
||||||
Search
|
Search
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div className="">
|
|
||||||
<label htmlFor="favourite">Favourites</label>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
name="favourite"
|
|
||||||
id="favourite"
|
|
||||||
onClick={() => setShowFavourite((prev) => !prev)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{(showFavourite && (
|
{data?.Search?.length > 0 &&
|
||||||
<div className="grid grid-cols-5 gap-4 mb-6 justify-center">
|
<div>
|
||||||
{favouriteList?.map((movie) => (
|
{data?.Search?.map((movie) => <Card key={movie?.imdbID} movie={movie}/>)}
|
||||||
<Card
|
|
||||||
key={movie?.imdbID}
|
|
||||||
movie={movie}
|
|
||||||
setFavouriteList={setFavouriteList}
|
|
||||||
favouriteList={favouriteList}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)) ||
|
}
|
||||||
(data?.Search?.length > 0 && (
|
|
||||||
<div className="flex flex-col items-center m-10">
|
|
||||||
{loading && (
|
|
||||||
<svg
|
|
||||||
className="animate-spin h-12 w-12 border-4 border-[#fff] mb-6"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="#fff"
|
|
||||||
></svg>
|
|
||||||
)}
|
|
||||||
<div className="grid grid-cols-5 gap-4 mb-6 justify-center">
|
|
||||||
{data?.Search?.map((movie) => (
|
|
||||||
<Card
|
|
||||||
key={movie?.imdbID}
|
|
||||||
movie={movie}
|
|
||||||
setFavouriteList={setFavouriteList}
|
|
||||||
favouriteList={favouriteList}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<Pagination
|
|
||||||
sx={{ bgcolor: "#6B8A7A" }}
|
|
||||||
onChange={handlePageChange}
|
|
||||||
page={Number(page)}
|
|
||||||
count={Math.ceil(data?.totalResults / 10)}
|
|
||||||
variant="outlined"
|
|
||||||
shape="rounded"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HomePage;
|
export default HomePage;
|
||||||
|
|
||||||
function SearchBar({
|
|
||||||
inputValue,
|
|
||||||
event,
|
|
||||||
setInputValue,
|
|
||||||
target,
|
|
||||||
value,
|
|
||||||
handleSearch,
|
|
||||||
setShowFavourite,
|
|
||||||
prev,
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center gap-10">
|
|
||||||
<form className="flex gap-3 items-center">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="search"
|
|
||||||
id="search"
|
|
||||||
value={inputValue}
|
|
||||||
onChange={(event) => setInputValue(event?.target?.value)}
|
|
||||||
className="p-1 text-quadnary bg-secondary focus:bg-secondary rounded outline-none border border-ternary"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="px-4 py-1 font-semibold h-full rounded border border-quadnary text-quadnary bg-secondary"
|
|
||||||
onClick={handleSearch}
|
|
||||||
>
|
|
||||||
Search
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<div className="">
|
|
||||||
<label htmlFor="favourite">Favourites</label>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
name="favourite"
|
|
||||||
id="favourite"
|
|
||||||
onClick={() => setShowFavourite((prev) => !prev)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ export default {
|
||||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
primary: "#6B8A7A",
|
primary: "#191A19",
|
||||||
secondary: "#254336",
|
secondary: "#1E5128",
|
||||||
ternary: "#B7B597",
|
ternary: "#4E9F3D",
|
||||||
quadnary: "#DAD3BE",
|
quadnary: "#D8E9A8",
|
||||||
},
|
},
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue