diff --git a/components/AccountMenu.tsx b/components/AccountMenu.tsx index a59a48d..01ab6b3 100644 --- a/components/AccountMenu.tsx +++ b/components/AccountMenu.tsx @@ -1,9 +1,25 @@ import React from 'react' import { signOut } from 'next-auth/react' -const AccountMenu = () => { +interface AccountMenuProps { + visible?: boolean; +} + +const AccountMenu: React.FC = ({visible}) => { + if(!visible){ + return null; + } return ( -
AccountMenu
+
+
+
+ Immagine Profilo +

Username

+
+
+
signOut()} className='px-3 text-center text-white text-sm hover:underline'>Logout
+
+
) } diff --git a/components/Billboard.tsx b/components/Billboard.tsx new file mode 100644 index 0000000..e2cf7da --- /dev/null +++ b/components/Billboard.tsx @@ -0,0 +1,28 @@ +import useBillBoard from "@/hooks/useBillboard"; +import React from "react"; +import {AiOutlineInfoCircle} from "react-icons/ai" + +const Billboard = () => { + const { data } = useBillBoard(); + return ( +
+ +
+

+ {data?.title} +

+

+ {data?.description} +

+
+ +
+
+
+ ) +} + +export default Billboard; \ No newline at end of file diff --git a/components/MovieCard.tsx b/components/MovieCard.tsx new file mode 100644 index 0000000..ddc20d2 --- /dev/null +++ b/components/MovieCard.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { BsFillPlayFill } from "react-icons/bs"; + +interface MovieCardProps { + data: Record[]; +} + +const MovieCard: React.FC = ({ data }) => { + return ( +
+ Thumbnail +
+ Thumbnail +
+
+
{}}> + +
+
+

+ New 2023 +

+
+

{data.duration}

+
+
+

{data.genre}

+
+
+
+
+ ) +} + +export default MovieCard; \ No newline at end of file diff --git a/components/MovieList.tsx b/components/MovieList.tsx new file mode 100644 index 0000000..30dd024 --- /dev/null +++ b/components/MovieList.tsx @@ -0,0 +1,29 @@ +import React from 'react' +import { isEmpty } from 'lodash'; +import MovieCard from './MovieCard'; + +interface MovieListProps { + data: Record[]; + title: string; +} + + +const MovieList: React.FC = ({ data, title }) => { + if (isEmpty(data)) { + return null; + } + return ( +
+
+

{title}

+
+ {data.map((film) => ( + + ))} +
+
+
+ ) +} + +export default MovieList; \ No newline at end of file diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 9d5b41d..eacc5a7 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -1,17 +1,42 @@ import MobileMenu from "./MobileMenu" import NavbarItem from "./NavbarItem" import { BsChevronDown,BsSearch,BsBell } from "react-icons/bs" -import { useCallback,useState } from "react" +import { useCallback,useState,useEffect } from "react" import AccountMenu from "./AccountMenu"; function Navbar() { const [showMobileMenu,setShowMobileMenu] = useState(false); + const [showAccountMenu,setshowAccountMenu] = useState(false); + const [showBackground,setShowBackground] = useState(false); + + const TOP_OFFSET = 66; + + useEffect(() => { + const handleScroll = () => { + if(window.scrollY >= TOP_OFFSET){ + setShowBackground(true); + }else{ + setShowBackground(false) + } + } + window.addEventListener('scroll',handleScroll); + + return () => { + window.removeEventListener('scroll',handleScroll); + } + },[]) + const toggleMobileMenu = useCallback(()=>{ setShowMobileMenu((currentvisible) => !currentvisible) - },[]) + },[]); + + const toggleAccountMenu = useCallback(()=>{ + setshowAccountMenu((currentvisible) => !currentvisible) + },[]); + return ( diff --git a/hooks/useBillboard.ts b/hooks/useBillboard.ts new file mode 100644 index 0000000..4a032ba --- /dev/null +++ b/hooks/useBillboard.ts @@ -0,0 +1,17 @@ +import useSWR from "swr"; +import fetcher from "@/lib/fetcher"; + +const useBillBoard = () => { + const { data,error,isLoading } = useSWR('/api/random',fetcher,{ + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false + }); + return { + data, + error, + isLoading + } +} + +export default useBillBoard; \ No newline at end of file diff --git a/hooks/useMoviesList.ts b/hooks/useMoviesList.ts new file mode 100644 index 0000000..ca4f0d8 --- /dev/null +++ b/hooks/useMoviesList.ts @@ -0,0 +1,17 @@ +import useSWR from "swr"; +import fetcher from "@/lib/fetcher"; + +const useMoviesList = () => { + const {data,error,isLoading} = useSWR('/api/movies',fetcher,{ + revalidateIfStale: false, + revalidateOnReconnect: false, + revalidateOnFocus: false + }); + return { + data, + error, + isLoading + } +} + +export default useMoviesList; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index eb7e14d..d1dbb44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "bcrypt": "^5.1.0", "eslint": "8.42.0", "eslint-config-next": "13.4.4", + "loadash": "^1.0.0", + "lodash": "^4.17.21", "next": "13.4.4", "next-auth": "^4.22.1", "postcss": "8.4.24", @@ -30,6 +32,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/lodash": "^4.14.195", "prisma": "^4.13.0" } }, @@ -479,6 +482,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -2989,6 +2998,12 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/loadash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loadash/-/loadash-1.0.0.tgz", + "integrity": "sha512-xlX5HBsXB3KG0FJbJJG/3kYWCfsCyCSus3T+uHVu6QL6YxAdggmm3QeyLgn54N2yi5/UE6xxL5ZWJAAiHzHYEg==", + "deprecated": "Package is unsupport. Please use the lodash package instead." + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3003,6 +3018,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index a65004b..96fc930 100644 --- a/package.json +++ b/package.json @@ -11,27 +11,28 @@ "dependencies": { "@next-auth/prisma-adapter": "^1.0.6", "@prisma/client": "^4.13.0", - "axios": "^1.4.0", - "bcrypt": "^5.1.0", - "next-auth": "^4.22.1", - "react-icons": "^4.8.0", - "swr": "^2.1.5", "@types/node": "20.2.5", "@types/react": "18.2.8", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", + "axios": "^1.4.0", + "bcrypt": "^5.1.0", "eslint": "8.42.0", "eslint-config-next": "13.4.4", + "lodash": "^4.17.21", "next": "13.4.4", + "next-auth": "^4.22.1", "postcss": "8.4.24", "react": "18.2.0", "react-dom": "18.2.0", + "react-icons": "^4.8.0", + "swr": "^2.1.5", "tailwindcss": "3.3.2", "typescript": "5.1.3" }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/lodash": "^4.14.195", "prisma": "^4.13.0" } } - diff --git a/pages/api/movies/index.ts b/pages/api/movies/index.ts new file mode 100644 index 0000000..eb87e16 --- /dev/null +++ b/pages/api/movies/index.ts @@ -0,0 +1,18 @@ +import {NextApiRequest,NextApiResponse} from "next"; + +import prismadb from "@/lib/prismadb"; +import serverAuth from "@/lib/serverAuth"; + +export default async function handler(req: NextApiRequest,res: NextApiResponse) { + if(req.method !== "GET"){ + return res.status(405).end(); + } + try{ + await serverAuth(req); + const movies = await prismadb.movie.findMany(); + return res.status(200).json(movies); + }catch(error){ + console.log(error); + return res.status(400).end(); + } +} \ No newline at end of file diff --git a/pages/api/random.ts b/pages/api/random.ts new file mode 100644 index 0000000..0d04596 --- /dev/null +++ b/pages/api/random.ts @@ -0,0 +1,22 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import prismadb from "@/lib/prismadb"; +import serverAuth from "@/lib/serverAuth"; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method !== 'GET') { + return res.status(405).end + } + try { + await serverAuth(req); + const movieCount = await prismadb.movie.count(); + const randomIndex = Math.floor(Math.random() * movieCount); + const randomMovies = await prismadb.movie.findMany({ + take: 1, + skip: randomIndex + }); + return res.status(200).json(randomMovies[0]) + } catch (error) { + console.log(error); + return res.status(400).end() + } +} \ No newline at end of file diff --git a/pages/index.tsx b/pages/index.tsx index 1d55463..be3f03d 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,5 +1,8 @@ +import Billboard from "@/components/Billboard" +import MovieList from "@/components/MovieList" import Navbar from "@/components/Navbar" import useCurrentUser from "@/hooks/useCurrentUser" +import useMoviesList from "@/hooks/useMoviesList" import { NextPageContext } from "next" import { signOut,getSession } from "next-auth/react" @@ -20,9 +23,14 @@ export async function getServerSideProps(context: NextPageContext){ export default function Home() { + const { data: film = [] } = useMoviesList(); return ( <> + +
+ +
) }