aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.env7
-rw-r--r--.vscode/settings.json4
-rw-r--r--app/browse/page.tsx (renamed from src/pages/browse/index.tsx)247
-rw-r--r--app/components/AuthContext.tsx25
-rw-r--r--app/components/Genre.tsx24
-rw-r--r--app/components/Modal.tsx66
-rw-r--r--app/components/PreviewCard.tsx20
-rw-r--r--app/hello/page.tsx99
-rw-r--r--app/layout.js20
-rw-r--r--app/login/page.tsx125
-rw-r--r--app/password-recovery/page.tsx44
-rw-r--r--app/profiles/page.tsx (renamed from src/pages/index.tsx)25
-rw-r--r--app/register/page.tsx123
-rw-r--r--next.config.js3
-rw-r--r--package-lock.json1028
-rw-r--r--package.json3
-rw-r--r--services/firebase.tsx25
-rw-r--r--services/requests.tsx15
-rw-r--r--src/components/Genre.tsx27
-rw-r--r--src/components/PreviewCard.tsx19
-rw-r--r--src/pages/_app.tsx2
-rw-r--r--src/styles/globals.css1
-rw-r--r--tailwind.config.js1
-rw-r--r--tsconfig.json30
24 files changed, 1774 insertions, 209 deletions
diff --git a/.env b/.env
new file mode 100644
index 0000000..0f23f5c
--- /dev/null
+++ b/.env
@@ -0,0 +1,7 @@
+NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSyDWM4QIP4D6byd4vjmStT7hGrHlGE10mjE
+NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=reactnativeapp-12f61.firebaseapp.com
+NEXT_PUBLIC_FIREBASE_PROJECT_ID=reactnativeapp-12f61
+NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=reactnativeapp-12f61.appspot.com
+NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=588576830512
+NEXT_PUBLIC_FIREBASE_APP_ID=1:588576830512:web:b4d768e27ac4559794a9f5
+NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-J1W4WDDMQP \ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..bd3337f
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "typescript.tsdk": "node_modules\\typescript\\lib",
+ "typescript.enablePromptUseWorkspaceTsdk": true
+} \ No newline at end of file
diff --git a/src/pages/browse/index.tsx b/app/browse/page.tsx
index 90c13c2..7806738 100644
--- a/src/pages/browse/index.tsx
+++ b/app/browse/page.tsx
@@ -1,94 +1,153 @@
-import { link } from 'fs'
-import Link from 'next/link'
-import { BellIcon, MagnifyingGlassIcon, PlayIcon, ArrowSmallDownIcon} from '@heroicons/react/24/solid'
-import { InformationCircleIcon} from '@heroicons/react/24/outline'
-import { useEffect, useState } from 'react'
-import requests from '../../../services/requests'
-import Image from "next/image"
-import PreviewCard from '@prueba/components/PreviewCard'
-
-// import NetflixLogo from '../../../public/images/netflix_logo.svg'
-const baseURL ='https://api.themoviedb.org/3/'
-const imageURL = 'https://image.tmdb.org/t/p/original'
-
-export default function Home() {
- const [heroMovie, setHeroMovie] = useState()
- const [trendingMovies, setTrendingMovies] = useState()
- useEffect(() => {
- fetch(`${baseURL}${requests.fetchTopRated}`).then(res => res.json()).then((data) => {
- console.log(data.results)
- setHeroMovie(data.results[3])
- })
- }, [])
- useEffect(() => {
- fetch(`${baseURL}${requests.fetchTrending}`).then(res => res.json()).then((data) => {
- setTrendingMovies(data.results)
- })
- }, [])
-
- return (
- <div className="flex flex-col text-white justify-between gap-10 h-screen">
- <header className='flex justify-between pt-3 px-8 z-10 text-xs'>
- <div className='flex items-center gap-4'>
- <img className='scale-[65%] mr-4' src="../images/netflix_logo.svg" alt="SVG image"/>
- <a className='text-white font-bold'>Home</a>
- <a className='text-white'>TV Shows</a>
- <a className='text-white'>Movies</a>
- <a className='text-white'>News & Popular</a>
- <a className='text-white'>My List</a>
- <a className='text-white'>Browse by Language</a>
- </div>
- <div className='flex items-center gap-4'>
- <MagnifyingGlassIcon className='h-4 w-4'/>
- <a className='text-white'>Kids</a>
- <BellIcon className='h-4 w-4'/>
- <div className='h-8 w-8'>
- <Link href='../' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
- <img src='https://avatars.dicebear.com/api/male/124.svg' alt=""/>
- </Link>
- </div>
- <ArrowSmallDownIcon className='h-4 w-4'/>
- </div>
- </header>
- <section className='w-1/3 ml-10'>
- <div className='flex items-center'>
- <img className='scale-[65%] mr-5' src="../images/N.svg" alt="SVG image"/>
- <h1 className='text-sm font-mono tracking-[.4rem]'>MOVIES</h1>
- </div>
- <div className='h-fit text-[3rem]'>
- {heroMovie?.original_title}
- </div>
- <div className='flex items-center'>
- <img className='scale-[45%]' src="../images/Top10.svg" alt="SVG image"/>
- <h2 className='font-bold'>#1 in TV Shows Today</h2>
- </div>
- <div>
- <p className=' text-sm break-words text-justify'>
- {heroMovie?.overview}
- </p>
- </div>
- <div className='flex gap-4 mt-4'>
- <button className='flex items-center p-4 h-10 bg-white text-black text-xl justify-center font-semibold ring-black ring-offset-10 hover:ring-4 rounded'>
- <PlayIcon className='h-6 w-6 mr-2'/>Play
- </button>
- <button className='flex items-center p-4 h-10 bg-gray-700/80 justify-center ring-white hover:ring-4 rounded'>
- <InformationCircleIcon className='h-6 w-6 mr-2'/>More Info
- </button>
- </div>
- </section>
- <section className=' ml-10 mb-10 z-10'>
- <h2>Popular on Netflix</h2>
- <div className='flex flex-row gap-3 overflow-x-auto mt-4 items-center p-5 pl-10 -ml-10'>
- {
- trendingMovies?.map((movie, index) => (
- <PreviewCard key={index} movie={movie}/>
- ))}
- </div>
- </section>
- <div className='absolute h-full w-full bg-contain bg-center -z-20 bg-right' style={{backgroundImage: `url(${imageURL}${heroMovie?.backdrop_path})`}}></div>
- <div className='absolute w-full h-32 -z-10 bg-gradient-to-b from-black'></div>
- <div className='absolute bottom-0 w-full h-20 -z-10 bg-gradient-to-t from-black'></div>
- <div className='absolute w-2/3 h-full -z-10 bg-gradient-to-r from-black'></div>
- </div>
- )
-}
+'use client'
+import { link } from 'fs'
+import Link from 'next/link'
+import { BellIcon, MagnifyingGlassIcon, PlayIcon, ArrowSmallDownIcon} from '@heroicons/react/24/solid'
+import { InformationCircleIcon} from '@heroicons/react/24/outline'
+import { useEffect, useState, useContext } from 'react'
+import requests from '../../services/requests'
+import Image from "next/image"
+import PreviewCard from '../components/PreviewCard'
+import Modal from '../components/Modal'
+import { auth } from '../../services/firebase';
+import { useRouter } from 'next/navigation';
+import { signOut } from 'firebase/auth';
+import { AuthContext } from '../components/AuthContext'
+
+// import NetflixLogo from '../../../public/images/netflix_logo.svg'
+const baseURL ='https://api.themoviedb.org/3/'
+const imageURL = 'https://image.tmdb.org/t/p/original'
+
+const Home = () => {
+ const router = useRouter();
+ const [heroMovie, setHeroMovie] = useState()
+ const [trendingMovies, setTrendingMovies] = useState()
+ const [trendingTv, setTrendingTv] = useState()
+ const [modalVisible, setModalVisible] = useState(false)
+ const [modalContent, setModalContent] = useState()
+ const user = useContext(AuthContext);
+
+ useEffect(() => {
+ // Check if user is authenticated
+ if (!user) {
+ // Redirect or perform any necessary action
+ router.push('/login');
+ } else {
+ // User is authenticated, continue with desired logic
+ }
+ }, [user]);
+
+ useEffect(() => {
+ const user = auth.currentUser;
+ if (!user) {
+ // User is not signed in, redirect to the login page
+ router.push('/login');
+ }
+ }, []);
+
+ const logoutUser = () => {
+ signOut(auth)
+ .then(() => {
+ console.log('User signed Out!');
+ // Navigate to the home screen or other desired screen
+ router.push('/login');
+ })
+ .catch(error => {
+ console.error(error);
+ // Display an error message to the user
+ });
+ }
+
+ useEffect(() => {
+ fetch(`${baseURL}${requests.fetchTopRated}`).then(res => res.json()).then((data) => {
+ setHeroMovie(data.results[3])
+ })
+ }, [])
+ useEffect(() => {
+ fetch(`${baseURL}${requests.fetchTrendingMovies}`).then(res => res.json()).then((data) => {
+ setTrendingMovies(data.results)
+ console.log(data.results)
+ })
+ }, [])
+ useEffect(() => {
+ fetch(`${baseURL}${requests.fetchTrendingTv}`).then(res => res.json()).then((data) => {
+ setTrendingTv(data.results)
+ })
+ }, [])
+
+ return (
+ <div className="flex flex-col text-white justify-between gap-10 h-screen">
+ <header className='flex justify-between pt-3 px-8 z-10 text-xs'>
+ <div className='flex items-center gap-4'>
+ <img className='scale-[65%] mr-4' src="../images/netflix_logo.svg" alt="SVG image"/>
+ <a className='text-white font-bold'>Home</a>
+ <a className='text-white'>TV Shows</a>
+ <a className='text-white'>Movies</a>
+ <a className='text-white'>News & Popular</a>
+ <a className='text-white'>My List</a>
+ <a className='text-white'>Browse by Language</a>
+ </div>
+ <div className='flex items-center gap-4'>
+ <MagnifyingGlassIcon className='h-4 w-4'/>
+ <a className='text-white'>Kids</a>
+ <BellIcon className='h-4 w-4'/>
+ <div className='h-8 w-8'>
+ <Link href='../' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <img src='https://avatars.dicebear.com/api/male/124.svg' alt=""/>
+ </Link>
+ </div>
+ <ArrowSmallDownIcon className='h-4 w-4 cursor-pointer' onClick={logoutUser}/>
+ </div>
+ </header>
+ <section className='w-1/3 ml-10'>
+ <div className='flex items-center'>
+ <img className='scale-[65%] mr-5' src="../images/N.svg" alt="SVG image"/>
+ <h1 className='text-sm font-mono tracking-[.4rem]'>MOVIES</h1>
+ </div>
+ <div className='h-fit text-[3rem]'>
+ {heroMovie?.original_title}
+ </div>
+ <div className='flex items-center'>
+ <img className='scale-[45%]' src="../images/Top10.svg" alt="SVG image"/>
+ <h2 className='font-bold'>#1 in TV Shows Today</h2>
+ </div>
+ <div>
+ <p className=' text-sm break-words text-justify'>
+ {heroMovie?.overview}
+ </p>
+ </div>
+ <div className='flex gap-4 mt-4'>
+ <button className='flex items-center p-4 h-10 bg-white text-black text-xl justify-center font-semibold rounded hover:outline outline-offset-4 outline-4 outline-white'>
+ <PlayIcon className='h-6 w-6 mr-2'/>Play
+ </button>
+ <button className='flex items-center p-4 h-10 bg-gray-700/80 justify-center rounded hover:outline outline-offset-4 outline-4'>
+ <InformationCircleIcon className='h-6 w-6 mr-2'/>More Info
+ </button>
+ </div>
+ </section>
+ <section className=' ml-10 mb-10 z-10'>
+ <h2>Popular on Netflix</h2>
+ <div className='flex flex-row gap-3 overflow-x-auto mt-4 items-center p-6 pl-10 -ml-10'>
+ {
+ trendingMovies?.map((movie, index) => (
+ <PreviewCard key={index} movie={movie} setModalContentId={setModalContent} setModalVisible={setModalVisible}/>
+ ))}
+ </div>
+ </section>
+ <section className=' ml-10 mb-10 z-10'>
+ <h2>Tv Shows</h2>
+ <div className='flex flex-row gap-3 overflow-x-auto mt-4 items-center p-5 pl-10 -ml-10'>
+ {
+ trendingTv?.map((movie, index) => (
+ <PreviewCard key={index} movie={movie} setModalContentId={setModalContent} setModalVisible={setModalVisible}/>
+ ))}
+ </div>
+ </section>
+ <Modal modalContent={modalContent} setModalVisible={setModalVisible} modalVisible={modalVisible}/>
+ <div className='absolute h-full w-full bg-contain bg-right -z-20 bg-no-repeat' style={{backgroundImage: `url(${imageURL}${heroMovie?.backdrop_path})`}}></div>
+ <div className='absolute w-full h-32 -z-10 bg-gradient-to-b from-black'></div>
+ <div className='absolute bottom-0 w-full h-20 -z-10 bg-gradient-to-t from-black'></div>
+ <div className='absolute w-2/3 h-full -z-10 bg-gradient-to-r from-black'></div>
+ </div>
+ )
+}
+export default Home; \ No newline at end of file
diff --git a/app/components/AuthContext.tsx b/app/components/AuthContext.tsx
new file mode 100644
index 0000000..9c83744
--- /dev/null
+++ b/app/components/AuthContext.tsx
@@ -0,0 +1,25 @@
+'use client'
+import { createContext, useState, useEffect } from 'react';
+import { onAuthStateChanged } from 'firebase/auth';
+import { auth } from '../../services/firebase';
+
+export const AuthContext = createContext();
+
+export const AuthProvider = ({ children }) => {
+ const [user, setUser] = useState(null);
+
+ useEffect(() => {
+ const unsubscribe = onAuthStateChanged(auth, (user) => {
+ setUser(user);
+ });
+
+ // Cleanup the subscription when the component unmounts
+ return () => unsubscribe();
+ }, []);
+
+ return (
+ <AuthContext.Provider value={user}>
+ {children}
+ </AuthContext.Provider>
+ );
+}; \ No newline at end of file
diff --git a/app/components/Genre.tsx b/app/components/Genre.tsx
new file mode 100644
index 0000000..13e7ed2
--- /dev/null
+++ b/app/components/Genre.tsx
@@ -0,0 +1,24 @@
+import { useEffect, useState } from "react"
+
+const Genres = ({id}) => {
+
+ const [genres, setGenres] = useState()
+
+ useEffect(() => {
+ fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=8216fbb9997cd81a67471e6cb5a6f2df`).then((res) => res.json()).then((data) => {
+ setGenres(data?.genres)
+ })
+ }, [id])
+
+ return (
+ <div className="text-white/60 gap-x-3 text-xs flex flex-row flex-wrap relative">
+ {genres?.map((genre, index) => {
+ return (
+ <div key={index}>{genre.name}</div>
+ )
+ })}
+ </div>
+ )
+}
+
+export default Genres \ No newline at end of file
diff --git a/app/components/Modal.tsx b/app/components/Modal.tsx
new file mode 100644
index 0000000..e783cfa
--- /dev/null
+++ b/app/components/Modal.tsx
@@ -0,0 +1,66 @@
+import { useEffect, useState } from 'react'
+import { XMarkIcon } from '@heroicons/react/24/outline'
+import Genre from './Genre'
+
+const baseURL = 'https://api.themoviedb.org/3/'
+const API_KEY = '8216fbb9997cd81a67471e6cb5a6f2df'
+const Modal = ({ modalVisible, modalContent, setModalVisible, type }) => {
+ const [content, setContent] = useState()
+ const [video, setVideo] = useState()
+ const [similarMovies, setSimilarMovies] = useState()
+ useEffect(() => {
+ fetch(`${baseURL}/movie/${modalContent?.id}/similar?api_key=${API_KEY}`).then(res => res.json()).then((data) => {
+ setSimilarMovies(data.results)
+ })
+ }, [modalContent])
+ useEffect(() => {
+ if (modalContent) {
+ fetch(`${baseURL}/${modalContent.media_type}/${modalContent.id}/videos?api_key=${API_KEY}`)
+ .then((res) => res.json())
+ .then((data) => {
+ console.log('VIDEOS DATA', data.results[0].key)
+ setVideo(data.results[0].key)
+ })
+}
+ }, [modalContent])
+ return (
+ <div
+ className={`backdrop-blur-[2px] fixed inset-0 z-50 bg-black/40 flex items-center justify-center ${modalVisible ? '' : 'hidden'
+ }`} onClick={(e) => e.target === e.currentTarget && setModalVisible(false)}
+ >
+ <div className="flex flex-col bg-transparent shadow-2xl rounded-xl z-100">
+ {modalVisible && (
+ <iframe
+ className={'w-full bg-black'}
+ width="420"
+ height="315"
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+ src={`https://www.youtube.com/embed/${video}?autoplay=1`}
+ ></iframe>
+ )}
+ <div className={'px-8 py-4 w-[600px] bg-gray-800'}>
+ <Genre id={modalContent?.id} />
+ <h3 className={'text-xl'}>{modalContent?.original_name}{modalContent?.original_title}</h3>
+ <p className='w-full break-words h-[70px] overflow-y-auto'>{modalContent?.overview}</p>
+ <hr className='my-4'/>
+ <div className='flex flex-row overflow-x-auto gap-8'>
+ {
+ similarMovies?.map((movie, index) => (
+
+
+ <div
+ className={`
+ shrink-0 bg-contain bg-no-repeat w-[150px] h-[112px] bg-center z-40 ${movie?.backdrop_path === null ? 'hidden' : '' }
+ `}
+ style={{
+ backgroundImage: `url(https://image.tmdb.org/t/p/original${movie?.backdrop_path})`,
+ }}
+ ></div>
+ ))}
+ </div>
+ </div>
+ </div>
+ </div>
+ )
+}
+export default Modal
diff --git a/app/components/PreviewCard.tsx b/app/components/PreviewCard.tsx
new file mode 100644
index 0000000..132f50a
--- /dev/null
+++ b/app/components/PreviewCard.tsx
@@ -0,0 +1,20 @@
+const imageURL = 'https://image.tmdb.org/t/p/original';
+import Genre from "./Genre";
+const baseURL ='https://api.themoviedb.org/3/'
+
+const PreviewCard = ({ movie, setModalContentId, setModalVisible }) => {
+ return (
+ <div className="hover:z-10" onClick={ () => {setModalVisible(true), setModalContentId(movie)}}>
+ <div className="shadow-black hover:outline outline-offset-4 outline-4 outline-white rounded flex-col p-1 relative bg-cover h-32 w-60 shrink-0 flex justify-end cursor-pointer hover:scale-110 transition ease-in-out" style={{backgroundImage: `url(${imageURL}${movie?.backdrop_path})`}}>
+ <div className="absolute h-full w-full inset-0 bg-gradient-to-t from-black/70"></div>
+ <h3 className={"text-white text-sm relative"}>
+ {movie.original_title}
+ {movie.original_name}
+ </h3>
+ <Genre id={movie.id}/>
+ </div>
+ </div>
+ )}
+
+
+export default PreviewCard \ No newline at end of file
diff --git a/app/hello/page.tsx b/app/hello/page.tsx
new file mode 100644
index 0000000..89e730e
--- /dev/null
+++ b/app/hello/page.tsx
@@ -0,0 +1,99 @@
+'use client'
+import { signInWithEmailAndPassword } from "firebase/auth";
+import Link from "next/link";
+import { auth } from "../../services/firebase";
+
+export default function Hello() {
+ let email = ''
+ let isValidEmail = ''
+ let setIsValidEmail = ''
+ let password = ''
+ let isValidPassword = ''
+ let setIsValidPassword = ''
+ let setIsPasswordVisible = ''
+ let se
+
+ const emailValidation = () => {
+ const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+ if (!email || emailRegex.test(email) === false) {
+ setIsValidEmail(false);
+ return false;
+ }
+ setIsValidEmail(true);
+ return true;
+ };
+
+ const passwordValidation = () => {
+ const passwordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{8,}$/i;
+
+ if (!password || passwordRegex.test(password) === false) {
+ setIsValidPassword(false)
+ return false
+ }
+ setIsValidPassword(true)
+ return true
+ }
+
+ const debounce = fn => {
+ let id = null;
+
+ return (...args) => {
+ if (id) {
+ clearTimeout(id);
+ }
+ id = setTimeout(() => {
+ fn(...args);
+ id = null;
+ }, 300);
+ };
+ };
+
+ const loginUser = () => {
+ if (isValidEmail && isValidPassword) {
+ signInWithEmailAndPassword(auth, email, password)
+ .then(data => {console.log(data.user)
+
+ console.log('User signed in successfully!');
+ router.push('/browse');
+ })
+ // Navigate to the home screen or other desired screen
+ .catch(error => {
+ console.error(error);
+ // Display an error message to the user
+ });
+ }
+ };
+
+ return (
+ <div className='text-white flex flex-col items-center justify-center h-screen'>
+ <h1 className='text-2xl font-bold mb-6'>Login</h1>
+ <form className='w-64' >
+ <div className='mb-4'>
+ <label htmlFor='email' className='block font-medium mb-1'>Email:</label>
+ <input type="email" id='email' className='text-black w-full px-3 py-2 border rounded'/>
+ </div>
+ <div className='mb-4'>
+ <label htmlFor="password" className='block font-medium mb-1'>Password:</label>
+ <input type='password' id='password' className='text-black w-full px-3 py-2 border rounded'/>
+ </div>
+ <button type="submit" className='w-full py-2 bg-red-600 text-white font-medium rounded'>
+ Login
+ </button>
+ </form>
+
+ <div className="mt-4">
+ Don't have an account?{' '}
+ <Link href='../register' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Create account</p>
+ </Link>
+ </div>
+
+ <div className="mt-2">
+ Forgot your password?{' '}
+ <Link href='../password-recovery' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Recover</p>
+ </Link>
+ </div>
+ </div>
+ );
+}
diff --git a/app/layout.js b/app/layout.js
new file mode 100644
index 0000000..45773fb
--- /dev/null
+++ b/app/layout.js
@@ -0,0 +1,20 @@
+import '../src/styles/globals.css';
+import { Inter } from 'next/font/google';
+import { AuthProvider } from './components/AuthContext';
+
+const inter = Inter({
+ subsets: ['latin'],
+ variable: '--font-inter',
+});
+
+export default function RootLayout({ children }) {
+ return (
+ <html lang="en">
+ <AuthProvider>
+ <body className={`${inter.variable} font-sans bg-black h-screen`}>
+ {children}
+ </body>
+ </AuthProvider>
+ </html>
+ );
+} \ No newline at end of file
diff --git a/app/login/page.tsx b/app/login/page.tsx
new file mode 100644
index 0000000..35ed0aa
--- /dev/null
+++ b/app/login/page.tsx
@@ -0,0 +1,125 @@
+'use client';
+import { useState, useEffect, useContext } from 'react';
+import { signInWithEmailAndPassword } from 'firebase/auth';
+import { auth } from '../../services/firebase';
+import Link from 'next/link';
+import { useRouter } from 'next/navigation';
+import { AuthContext } from '../components/AuthContext'
+
+
+const Login = () => {
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [isValidEmail, setIsValidEmail] = useState(false);
+ const [isValidPassword, setIsValidPassword] = useState(false);
+ const [isPasswordVisible, setIsPasswordVisible] = useState(true);
+ const router = useRouter()
+ const user = useContext(AuthContext);
+
+ useEffect(() => {
+ // Check if user is authenticated
+ if (!user) {
+ // Redirect or perform any necessary action
+ } else {
+ // User is authenticated, continue with desired logic
+ router.push('/profiles');
+ }
+ }, [user]);
+
+ useEffect(() => {
+ debounce(emailValidation());
+ }, [email]);
+
+ useEffect(() => {
+ debounce(passwordValidation());
+ }, [password]);
+
+ const emailValidation = () => {
+ const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+ if (!email || emailRegex.test(email) === false) {
+ setIsValidEmail(false);
+ return false;
+ }
+ setIsValidEmail(true);
+ return true;
+ };
+
+ const passwordValidation = () => {
+ const passwordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{8,}$/i;
+
+ if (!password || passwordRegex.test(password) === false) {
+ setIsValidPassword(false)
+ return false
+ }
+ setIsValidPassword(true)
+ return true
+ }
+
+ const debounce = fn => {
+ let id = null;
+
+ return (...args) => {
+ if (id) {
+ clearTimeout(id);
+ }
+ id = setTimeout(() => {
+ fn(...args);
+ id = null;
+ }, 300);
+ };
+ };
+
+ const loginUser = () => {
+ if (isValidEmail && isValidPassword) {
+ signInWithEmailAndPassword(auth, email, password)
+ .then(data => {console.log(data.user)
+
+ console.log('User signed in successfully!');
+ router.push('/profiles');
+
+ })
+ // Navigate to the home screen or other desired screen
+ .catch(error => {
+ console.error(error);
+ // Display an error message to the user
+ });
+ }
+ };
+
+ return (
+ <div className='text-white flex flex-col items-center justify-center h-screen'>
+ <h1 className='text-2xl font-bold mb-6'>Login</h1>
+ <form className='w-64' onSubmit={e => {
+ e.preventDefault();
+ loginUser();
+ }}>
+ <div className='mb-4'>
+ <label htmlFor='email' className='block font-medium mb-1'>Email:</label>
+ <input type="email" id='email' className='text-black w-full px-3 py-2 border rounded' value={email} onChange={e => setEmail(e.target.value)} />
+ </div>
+ <div className='mb-4'>
+ <label htmlFor="password" className='block font-medium mb-1'>Password:</label>
+ <input type='password' id='password' className='text-black w-full px-3 py-2 border rounded' value={password} onChange={e => setPassword(e.target.value)} />
+ </div>
+ <button type="submit" className='w-full py-2 bg-red-600 text-white font-medium rounded'>
+ Login
+ </button>
+ </form>
+
+ <div className="mt-4">
+ Don't have an account?{' '}
+ <Link href='../register' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Create account</p>
+ </Link>
+ </div>
+
+ <div className="mt-2">
+ Forgot your password?{' '}
+ <Link href='../password-recovery' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Recover</p>
+ </Link>
+ </div>
+ </div>
+ );
+}
+export default Login; \ No newline at end of file
diff --git a/app/password-recovery/page.tsx b/app/password-recovery/page.tsx
new file mode 100644
index 0000000..6a56d7a
--- /dev/null
+++ b/app/password-recovery/page.tsx
@@ -0,0 +1,44 @@
+'use client'
+import { link } from 'fs'
+import Link from 'next/link'
+import { AuthContext } from '../components/AuthContext'
+import { useContext, useEffect, useState } from 'react';
+
+// import NetflixLogo from '../../../public/images/netflix_logo.svg'
+
+export default function PasswordRecovery() {
+ const user = useContext(AuthContext);
+ const [email, setEmail] = useState('');
+
+ useEffect(() => {
+ // Check if user is authenticated
+ if (!user) {
+ // Redirect or perform any necessary action
+ } else {
+ // User is authenticated, continue with desired logic
+ setEmail(user.email)
+ }
+ }, [user]);
+
+ return (
+ <div className='text-white flex flex-col items-center justify-center h-screen'>
+ <h1 className='text-2xl font-bold mb-6'>Password Recovery</h1>
+ <form className='w-64'>
+ <div className='mb-4'>
+ <label htmlFor='email' className='block font-medium mb-1'>Email:</label>
+ <input type="email" id='email' value={email} className='w-full px-3 py-2 border rounded text-black' onChange={e => setEmail(e.target.value)}/>
+ </div>
+ <button className='w-full py-2 bg-red-600 text-white font-medium rounded'>
+ Recover
+ </button>
+ </form>
+
+ <div className="mt-4">
+ Do you have an account?{' '}
+ <Link href='../login' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Login</p>
+ </Link>
+ </div>
+ </div>
+ );
+}
diff --git a/src/pages/index.tsx b/app/profiles/page.tsx
index 0a21d32..fca89a5 100644
--- a/src/pages/index.tsx
+++ b/app/profiles/page.tsx
@@ -1,7 +1,25 @@
+'use client'
import Link from "next/link"
import Image from "next/image"
+import { AuthContext } from '../components/AuthContext'
+import { useContext, useEffect } from "react";
+import { useRouter } from 'next/navigation';
+
+export default function Profiles() {
+
+ const user = useContext(AuthContext);
+ const router = useRouter();
+
+ useEffect(() => {
+ // Check if user is authenticated
+ if (!user) {
+ // Redirect or perform any necessary action
+ router.push('/login');
+ } else {
+ // User is authenticated, continue with desired logic
+ }
+ }, [user]);
-export default function Home() {
return (
<div className="bg-black w-screen h-screen flex flex-col items-center justify-center">
<h1>Netflix</h1>
@@ -10,7 +28,7 @@ export default function Home() {
{
USERS.map((user, index) => (
<div key={index} className="flex flex-col items-center justify-center">
- <Link href={user.link} className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <Link href={'/browse'} className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
<Image src={user.avatar} width={128} height={128} alt=""/>
</Link>
<p className="text-gray-400 text-xs">{user.name}</p>
@@ -24,17 +42,14 @@ export default function Home() {
const USERS = [
{
name:'Alberto',
- link:'/browse',
avatar:'https://avatars.dicebear.com/api/male/124.svg'
},
{
name:'Kids',
- link:'/',
avatar:'https://avatars.dicebear.com/api/male/122.svg'
},
{
name:'Add profile',
- link:'/',
avatar:'https://avatars.dicebear.com/api/female/12.svg'
// icon:'...'
}
diff --git a/app/register/page.tsx b/app/register/page.tsx
new file mode 100644
index 0000000..45941fd
--- /dev/null
+++ b/app/register/page.tsx
@@ -0,0 +1,123 @@
+'use client';
+import Link from 'next/link'
+import { useContext, useEffect, useState } from 'react';
+import { auth } from '../../services/firebase';
+import { createUserWithEmailAndPassword } from 'firebase/auth';
+import { useRouter } from 'next/navigation';
+import { AuthContext } from '../components/AuthContext'
+
+// import NetflixLogo from '../../../public/images/netflix_logo.svg'
+
+const Register = () => {
+
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [isValidEmail, setIsValidEmail] = useState(false);
+ const [isValidPassword, setIsValidPassword] = useState(false);
+ const [isPasswordVisible, setIsPasswordVisible] = useState(true);
+ const router = useRouter()
+ const user = useContext(AuthContext);
+
+
+ useEffect(() => {
+ // Check if user is authenticated
+ if (!user) {
+ // Redirect or perform any necessary action
+ } else {
+ // User is authenticated, continue with desired logic
+ router.push('/profiles');
+ }
+ }, [user]);
+
+ useEffect(() => {
+ debounce(emailValidation());
+ }, [email]);
+
+ useEffect(() => {
+ debounce(passwordValidation());
+ }, [password]);
+
+ const emailValidation = () => {
+ const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+ if (!email || emailRegex.test(email) === false) {
+ setIsValidEmail(false);
+ return false;
+ }
+ setIsValidEmail(true);
+ return true;
+ };
+
+ const passwordValidation = () => {
+ const passwordRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{8,}$/i;
+
+
+ if (!password || passwordRegex.test(password) === false) {
+ setIsValidPassword(false)
+ return false
+ }
+ setIsValidPassword(true)
+ return true
+ }
+
+ // Utility FN · Mover a carpeta utils/utils.js
+ const debounce = fn => {
+ let id = null;
+
+ return (...args) => {
+ if (id) {
+ clearTimeout(id);
+ }
+ id = setTimeout(() => {
+ fn(...args);
+ id = null;
+ }, 300);
+ };
+ };
+
+
+ const registerUser = () => {
+ if (isValidEmail && isValidPassword) {
+ createUserWithEmailAndPassword(auth, email, password)
+ .then(() => {
+ console.log('User account created & signed in!');
+ // Navigate to the home screen or other desired screen
+ router.push('/browse');
+ })
+ .catch(error => {
+ console.error(error);
+ // Display an error message to the user
+ });
+ }
+};
+
+ return (
+ <div className='text-white flex flex-col items-center justify-center h-screen'>
+ <h1 className='text-2xl font-bold mb-6'>Register</h1>
+ <form className='w-64' onSubmit={e => {
+ e.preventDefault();
+ registerUser();
+ }}>
+ <div className='mb-4'>
+ <label htmlFor='email' className='block font-medium mb-1'>Email:</label>
+ <input type="email" id='email' className='text-black w-full px-3 py-2 border rounded' value={email} onChange={e => setEmail(e.target.value)} />
+ </div>
+ <div className='mb-4'>
+ <label htmlFor="password" className='block font-medium mb-1'>Password:</label>
+ <input type='password' id='password' className='text-black w-full px-3 py-2 border rounded' value={password} onChange={e => setPassword(e.target.value)} />
+ </div>
+ <button type="submit" className='w-full py-2 bg-red-600 text-white font-medium rounded'>
+ Register
+ </button>
+ </form>
+
+ <div className="mt-4">
+ Do you have an account?{' '}
+ <Link href='../login' className="w-[128px] h-[128px] rounded-xl overflow-hidden bg-white">
+ <p>Login</p>
+ </Link>
+ </div>
+ </div>
+ );
+}
+
+export default Register; \ No newline at end of file
diff --git a/next.config.js b/next.config.js
index 94c7499..13614ba 100644
--- a/next.config.js
+++ b/next.config.js
@@ -3,6 +3,9 @@ const { hostname } = require('os')
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
+ experimental: {
+ appDir: true,
+ },
images: {
remotePatterns: [
{
diff --git a/package-lock.json b/package-lock.json
index 12d1955..58e4c04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,8 @@
"autoprefixer": "10.4.14",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
- "next": "13.3.0",
+ "firebase": "^9.21.0",
+ "next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -1989,6 +1990,608 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@firebase/analytics": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz",
+ "integrity": "sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-compat": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz",
+ "integrity": "sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q==",
+ "dependencies": {
+ "@firebase/analytics": "0.10.0",
+ "@firebase/analytics-types": "0.8.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-types": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz",
+ "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw=="
+ },
+ "node_modules/@firebase/app": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.9.tgz",
+ "integrity": "sha512-8jzuHtQ/t9XqK+0IAQ/lpylVYzXGKIUKm6U3v7LWor+MGIm+9Ucn+hbrd2iBjH8qfmNrjnQnmf7sWBbdSa54oA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "idb": "7.1.1",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/app-check": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.7.0.tgz",
+ "integrity": "sha512-y0raLJpEtiL+wonfInFMaSfBV/EDvr356ZHMWbpr5F7fR0/I3cC0h7U6SKpKhrbSHJ0fOYIe0xbih20KTlpcnA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-compat": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.6.tgz",
+ "integrity": "sha512-azHAeHi9igoaIo04E6Yfuc7aIbWoWuBXuqjyYyWbeCc8Zz/NfJvIAgmXugN4LdxsHJ7XGlZTvwJ6YaYROdSa7A==",
+ "dependencies": {
+ "@firebase/app-check": "0.7.0",
+ "@firebase/app-check-types": "0.5.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-interop-types": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz",
+ "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ=="
+ },
+ "node_modules/@firebase/app-check-types": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz",
+ "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ=="
+ },
+ "node_modules/@firebase/app-compat": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.9.tgz",
+ "integrity": "sha512-XdnkHNK3XdPrwChmuSJHDA6eYmo2KLAtaAG1SJLGMQ+n+S5/UcufmDkw9GvPh93H1xhPRAwd/vKdjHmE7xp3Zw==",
+ "dependencies": {
+ "@firebase/app": "0.9.9",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/app-types": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz",
+ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q=="
+ },
+ "node_modules/@firebase/auth": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.23.1.tgz",
+ "integrity": "sha512-QubckPA5Ad92HiY20szjdH7EnFxL8gsZzRLyNCmO2oqebVAVuh9pJp6Zb8EA+P/AuMQYMBo6rQ3oIHi9gUCstg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/auth-compat": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.1.tgz",
+ "integrity": "sha512-wCw+6Jz7zCWzMA2bN8vphqEUmxuIFxHfBJiF3rKFTCEFPPXG4ulIcmMT98uuZVVq4xDPk/hxm105xwHBFAwBng==",
+ "dependencies": {
+ "@firebase/auth": "0.23.1",
+ "@firebase/auth-types": "0.12.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/auth-interop-types": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz",
+ "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg=="
+ },
+ "node_modules/@firebase/auth-types": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz",
+ "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/component": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz",
+ "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==",
+ "dependencies": {
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.4.tgz",
+ "integrity": "sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==",
+ "dependencies": {
+ "@firebase/auth-interop-types": "0.2.1",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "faye-websocket": "0.11.4",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database-compat": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.4.tgz",
+ "integrity": "sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/database": "0.14.4",
+ "@firebase/database-types": "0.10.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database-types": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz",
+ "integrity": "sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==",
+ "dependencies": {
+ "@firebase/app-types": "0.9.0",
+ "@firebase/util": "1.9.3"
+ }
+ },
+ "node_modules/@firebase/firestore": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.11.0.tgz",
+ "integrity": "sha512-r9qUbjuIKOXAVYwqZaamgXuUJBuV8I2X0Kao5PUxQAPueV2mRapdIlby6awYgjknE8kq1Tlys5Nf5/TV6WtnAg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "@firebase/webchannel-wrapper": "0.10.0",
+ "@grpc/grpc-js": "~1.7.0",
+ "@grpc/proto-loader": "^0.6.13",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-compat": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.8.tgz",
+ "integrity": "sha512-VrTckDEVBqFWFsHGVdQgCb0Tht/Rrg/nKFp2aat0FaIjr8A9t4Pfcuu32Py25SbiCnr98pyh3RmVYs0kbF/lCA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/firestore": "3.11.0",
+ "@firebase/firestore-types": "2.5.1",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-types": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.1.tgz",
+ "integrity": "sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/functions": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.4.tgz",
+ "integrity": "sha512-3H2qh6U+q+nepO5Hds+Ddl6J0pS+zisuBLqqQMRBHv9XpWfu0PnDHklNmE8rZ+ccTEXvBj6zjkPfdxt6NisvlQ==",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.2.0",
+ "@firebase/auth-interop-types": "0.2.1",
+ "@firebase/component": "0.6.4",
+ "@firebase/messaging-interop-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-compat": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.4.tgz",
+ "integrity": "sha512-kxVxTGyLV1MBR3sp3mI+eQ6JBqz0G5bk310F8eX4HzDFk4xjk5xY0KdHktMH+edM2xs1BOg0vwvvsAHczIjB+w==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/functions": "0.9.4",
+ "@firebase/functions-types": "0.6.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-types": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz",
+ "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw=="
+ },
+ "node_modules/@firebase/installations": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.4.tgz",
+ "integrity": "sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "idb": "7.0.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.4.tgz",
+ "integrity": "sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/installations-types": "0.5.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-types": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz",
+ "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations/node_modules/idb": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz",
+ "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg=="
+ },
+ "node_modules/@firebase/logger": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz",
+ "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/messaging": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.4.tgz",
+ "integrity": "sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/messaging-interop-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "idb": "7.0.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz",
+ "integrity": "sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/messaging": "0.12.4",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-interop-types": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz",
+ "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ=="
+ },
+ "node_modules/@firebase/messaging/node_modules/idb": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz",
+ "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg=="
+ },
+ "node_modules/@firebase/performance": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz",
+ "integrity": "sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.4.tgz",
+ "integrity": "sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/performance": "0.6.4",
+ "@firebase/performance-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-types": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz",
+ "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA=="
+ },
+ "node_modules/@firebase/remote-config": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.4.tgz",
+ "integrity": "sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz",
+ "integrity": "sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/remote-config": "0.4.4",
+ "@firebase/remote-config-types": "0.3.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-types": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz",
+ "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA=="
+ },
+ "node_modules/@firebase/storage": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.2.tgz",
+ "integrity": "sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-compat": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.2.tgz",
+ "integrity": "sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/storage": "0.11.2",
+ "@firebase/storage-types": "0.8.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-types": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz",
+ "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/util": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz",
+ "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/webchannel-wrapper": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.0.tgz",
+ "integrity": "sha512-2I8y+vJVrPfPFJrnRGpao1Qc2Gu7wmYoo5ed2s5zK/DUGgcyY1Yr/xC0YdnKM4pi7rG3HqwW9ehAKUXoTMLdoA=="
+ },
+ "node_modules/@grpc/grpc-js": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.7.3.tgz",
+ "integrity": "sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==",
+ "dependencies": {
+ "@grpc/proto-loader": "^0.7.0",
+ "@types/node": ">=12.12.47"
+ },
+ "engines": {
+ "node": "^8.13.0 || >=10.10.0"
+ }
+ },
+ "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": {
+ "version": "0.7.7",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.7.tgz",
+ "integrity": "sha512-1TIeXOi8TuSCQprPItwoMymZXxWT0CPxUhkrkeCUH+D8U7QDwQ6b7SUz2MaLuWM2llT+J/TVFLmQI5KtML3BhQ==",
+ "dependencies": {
+ "@types/long": "^4.0.1",
+ "lodash.camelcase": "^4.3.0",
+ "long": "^4.0.0",
+ "protobufjs": "^7.0.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@grpc/grpc-js/node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@grpc/grpc-js/node_modules/protobufjs": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz",
+ "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+ },
+ "node_modules/@grpc/grpc-js/node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@grpc/grpc-js/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@grpc/proto-loader": {
+ "version": "0.6.13",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz",
+ "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==",
+ "dependencies": {
+ "@types/long": "^4.0.1",
+ "lodash.camelcase": "^4.3.0",
+ "long": "^4.0.0",
+ "protobufjs": "^6.11.3",
+ "yargs": "^16.2.0"
+ },
+ "bin": {
+ "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@heroicons/react": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.17.tgz",
@@ -2076,9 +2679,9 @@
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"node_modules/@next/env": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-13.3.0.tgz",
- "integrity": "sha512-AjppRV4uG3No7L1plinoTQETH+j2F10TEnrMfzbTUYwze5sBUPveeeBAPZPm8OkJZ1epq9OyYKhZrvbD6/9HCQ=="
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-13.3.1.tgz",
+ "integrity": "sha512-EDtCoedIZC7JlUQ3uaQpSc4aVmyhbLHmQVALg7pFfQgOTjgSnn7mKtA0DiCMkYvvsx6aFb5octGMtWrOtGXW9A=="
},
"node_modules/@next/eslint-plugin-next": {
"version": "13.3.0",
@@ -2089,9 +2692,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.0.tgz",
- "integrity": "sha512-DmIQCNq6JtccLPPBzf0dgh2vzMWt5wjxbP71pCi5EWpWYE3MsP6FcRXi4MlAmFNDQOfcFXR2r7kBeG1LpZUh1w==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.1.tgz",
+ "integrity": "sha512-UXPtriEc/pBP8luSLSCZBcbzPeVv+SSjs9cH/KygTbhmACye8/OOXRZO13Z2Wq1G0gLmEAIHQAOuF+vafPd2lw==",
"cpu": [
"arm64"
],
@@ -2104,9 +2707,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.0.tgz",
- "integrity": "sha512-oQoqFa88OGgwnYlnAGHVct618FRI/749se0N3S8t9Bzdv5CRbscnO0RcX901+YnNK4Q6yeiizfgO3b7kogtsZg==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.1.tgz",
+ "integrity": "sha512-lT36yYxosCfLtplFzJWgo0hrPu6/do8+msgM7oQkPeohDNdhjtjFUgOOwdSnPublLR6Mo2Ym4P/wl5OANuD2bw==",
"cpu": [
"x64"
],
@@ -2119,9 +2722,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.0.tgz",
- "integrity": "sha512-Wzz2p/WqAJUqTVoLo6H18WMeAXo3i+9DkPDae4oQG8LMloJ3if4NEZTnOnTUlro6cq+S/W4pTGa97nWTrOjbGw==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.1.tgz",
+ "integrity": "sha512-wRb76nLWJhonH8s3kxC/1tFguEkeOPayIwe9mkaz1G/yeS3OrjeyKMJsb4+Kdg0zbTo53bNCOl59NNtDM7yyyw==",
"cpu": [
"arm64"
],
@@ -2134,9 +2737,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.0.tgz",
- "integrity": "sha512-xPVrIQOQo9WXJYgmoTlMnAD/HlR/1e1ZIWGbwIzEirXBVBqMARUulBEIKdC19zuvoJ477qZJgBDCKtKEykCpyQ==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.1.tgz",
+ "integrity": "sha512-qz3BzjJRZ16Iq/jrp+pjiYOc0jTjHlfmxQmZk9x/+5uhRP6/eWQSTAPVJ33BMo6oK5O5N4644OgTAbzXzorecg==",
"cpu": [
"arm64"
],
@@ -2149,9 +2752,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.0.tgz",
- "integrity": "sha512-jOFlpGuPD7W2tuXVJP4wt9a3cpNxWAPcloq5EfMJRiXsBBOjLVFZA7boXYxEBzSVgUiVVr1V9T0HFM7pULJ1qA==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.1.tgz",
+ "integrity": "sha512-6mgkLmwlyWlomQmpl21I3hxgqE5INoW4owTlcLpNsd1V4wP+J46BlI/5zV5KWWbzjfncIqzXoeGs5Eg+1GHODA==",
"cpu": [
"x64"
],
@@ -2164,9 +2767,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.0.tgz",
- "integrity": "sha512-2OwKlzaBgmuet9XYHc3KwsEilzb04F540rlRXkAcjMHL7eCxB7uZIGtsVvKOnQLvC/elrUegwSw1+5f7WmfyOw==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.1.tgz",
+ "integrity": "sha512-uqm5sielhQmKJM+qayIhgZv1KlS5pqTdQ99b+Z7hMWryXS96qE0DftTmMZowBcUL6x7s2vSXyH5wPtO1ON7LBg==",
"cpu": [
"x64"
],
@@ -2179,9 +2782,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.0.tgz",
- "integrity": "sha512-OeHiA6YEvndxT46g+rzFK/MQTfftKxJmzslERMu9LDdC6Kez0bdrgEYed5eXFK2Z1viKZJCGRlhd06rBusyztA==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.1.tgz",
+ "integrity": "sha512-WomIiTj/v3LevltlibNQKmvrOymNRYL+a0dp5R73IwPWN5FvXWwSELN/kiNALig/+T3luc4qHNTyvMCp9L6U5Q==",
"cpu": [
"arm64"
],
@@ -2194,9 +2797,9 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.0.tgz",
- "integrity": "sha512-4aB7K9mcVK1lYEzpOpqWrXHEZympU3oK65fnNcY1Qc4HLJFLJj8AViuqQd4jjjPNuV4sl8jAwTz3gN5VNGWB7w==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.1.tgz",
+ "integrity": "sha512-M+PoH+0+q658wRUbs285RIaSTYnGBSTdweH/0CdzDgA6Q4rBM0sQs4DHmO3BPP0ltCO/vViIoyG7ks66XmCA5g==",
"cpu": [
"ia32"
],
@@ -2209,9 +2812,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.0.tgz",
- "integrity": "sha512-Reer6rkLLcoOvB0dd66+Y7WrWVFH7sEEkF/4bJCIfsSKnTStTYaHtwIJAwbqnt9I392Tqvku0KkoqZOryWV9LQ==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.1.tgz",
+ "integrity": "sha512-Sl1F4Vp5Z1rNXWZYqJwMuWRRol4bqOB6+/d7KqkgQ4AcafKPN1PZmpkCoxv4UFHtFNIB7EotnuIhtXu3zScicQ==",
"cpu": [
"x64"
],
@@ -2274,6 +2877,60 @@
"url": "https://opencollective.com/unts"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
"node_modules/@rushstack/eslint-patch": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
@@ -2533,9 +3190,9 @@
}
},
"node_modules/@swc/helpers": {
- "version": "0.4.14",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
- "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.0.tgz",
+ "integrity": "sha512-SjY/p4MmECVVEWspzSRpQEM3sjR17sP8PbGxELWrT+YZMBfiUyt1MRUNjMV23zohwlG2HYtCQOsCwsTHguXkyg==",
"dependencies": {
"tslib": "^2.4.0"
}
@@ -2554,6 +3211,11 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
},
+ "node_modules/@types/long": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
+ },
"node_modules/@types/node": {
"version": "18.15.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.12.tgz",
@@ -3163,6 +3825,16 @@
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
},
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -4141,6 +4813,17 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -4178,6 +4861,39 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/firebase": {
+ "version": "9.21.0",
+ "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.21.0.tgz",
+ "integrity": "sha512-kQpT+YjusVhqj8feSmb+9Fpmyfy7ayGSd6GVk2k0qJjt+AwYgHZ9tuHuIgFdEHGsvqxYRZJpu067ck9ZQwbqQw==",
+ "dependencies": {
+ "@firebase/analytics": "0.10.0",
+ "@firebase/analytics-compat": "0.2.6",
+ "@firebase/app": "0.9.9",
+ "@firebase/app-check": "0.7.0",
+ "@firebase/app-check-compat": "0.3.6",
+ "@firebase/app-compat": "0.2.9",
+ "@firebase/app-types": "0.9.0",
+ "@firebase/auth": "0.23.1",
+ "@firebase/auth-compat": "0.4.1",
+ "@firebase/database": "0.14.4",
+ "@firebase/database-compat": "0.3.4",
+ "@firebase/firestore": "3.11.0",
+ "@firebase/firestore-compat": "0.3.8",
+ "@firebase/functions": "0.9.4",
+ "@firebase/functions-compat": "0.3.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/installations-compat": "0.2.4",
+ "@firebase/messaging": "0.12.4",
+ "@firebase/messaging-compat": "0.2.4",
+ "@firebase/performance": "0.6.4",
+ "@firebase/performance-compat": "0.2.4",
+ "@firebase/remote-config": "0.4.4",
+ "@firebase/remote-config-compat": "0.2.4",
+ "@firebase/storage": "0.11.2",
+ "@firebase/storage-compat": "0.3.2",
+ "@firebase/util": "1.9.3"
+ }
+ },
"node_modules/flat-cache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
@@ -4272,6 +4988,14 @@
"node": ">=6.9.0"
}
},
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
@@ -4490,6 +5214,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/http-parser-js": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
+ "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="
+ },
+ "node_modules/idb": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="
+ },
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -4677,6 +5411,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -5005,6 +5747,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -5016,6 +5763,11 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
+ "node_modules/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -5121,12 +5873,12 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
"node_modules/next": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/next/-/next-13.3.0.tgz",
- "integrity": "sha512-OVTw8MpIPa12+DCUkPqRGPS3thlJPcwae2ZL4xti3iBff27goH024xy4q2lhlsdoYiKOi8Kz6uJoLW/GXwgfOA==",
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/next/-/next-13.3.1.tgz",
+ "integrity": "sha512-eByWRxPzKHs2oQz1yE41LX35umhz86ZSZ+mYyXBqn2IBi2hyUqxBA88avywdr4uyH+hCJczegGsDGWbzQA5Rqw==",
"dependencies": {
- "@next/env": "13.3.0",
- "@swc/helpers": "0.4.14",
+ "@next/env": "13.3.1",
+ "@swc/helpers": "0.5.0",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001406",
"postcss": "8.4.14",
@@ -5136,18 +5888,18 @@
"next": "dist/bin/next"
},
"engines": {
- "node": ">=14.6.0"
+ "node": ">=14.18.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "13.3.0",
- "@next/swc-darwin-x64": "13.3.0",
- "@next/swc-linux-arm64-gnu": "13.3.0",
- "@next/swc-linux-arm64-musl": "13.3.0",
- "@next/swc-linux-x64-gnu": "13.3.0",
- "@next/swc-linux-x64-musl": "13.3.0",
- "@next/swc-win32-arm64-msvc": "13.3.0",
- "@next/swc-win32-ia32-msvc": "13.3.0",
- "@next/swc-win32-x64-msvc": "13.3.0"
+ "@next/swc-darwin-arm64": "13.3.1",
+ "@next/swc-darwin-x64": "13.3.1",
+ "@next/swc-linux-arm64-gnu": "13.3.1",
+ "@next/swc-linux-arm64-musl": "13.3.1",
+ "@next/swc-linux-x64-gnu": "13.3.1",
+ "@next/swc-linux-x64-musl": "13.3.1",
+ "@next/swc-win32-arm64-msvc": "13.3.1",
+ "@next/swc-win32-ia32-msvc": "13.3.1",
+ "@next/swc-win32-x64-msvc": "13.3.1"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -5195,6 +5947,25 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
@@ -5629,6 +6400,31 @@
"react-is": "^16.13.1"
}
},
+ "node_modules/protobufjs": {
+ "version": "6.11.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+ "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.1",
+ "@types/node": ">=13.7.0",
+ "long": "^4.0.0"
+ },
+ "bin": {
+ "pbjs": "bin/pbjs",
+ "pbts": "bin/pbts"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -5800,6 +6596,14 @@
"jsesc": "bin/jsesc"
}
},
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/resolve": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
@@ -5869,6 +6673,25 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@@ -5971,6 +6794,24 @@
"node": ">=10.0.0"
}
},
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
"node_modules/string.prototype.matchall": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
@@ -6329,6 +7170,11 @@
"node": ">=8.0"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -6512,6 +7358,41 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -6582,11 +7463,35 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -6600,6 +7505,31 @@
"node": ">= 6"
}
},
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index b64670d..0c89190 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
"autoprefixer": "10.4.14",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
- "next": "13.3.0",
+ "firebase": "^9.21.0",
+ "next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
diff --git a/services/firebase.tsx b/services/firebase.tsx
new file mode 100644
index 0000000..39e72eb
--- /dev/null
+++ b/services/firebase.tsx
@@ -0,0 +1,25 @@
+// Import the functions you need from the SDKs you need
+import { initializeApp, getApps } from "firebase/app";
+import { getAnalytics } from "firebase/analytics";
+import { getAuth } from 'firebase/auth'
+// TODO: Add SDKs for Firebase products that you want to use
+// https://firebase.google.com/docs/web/setup#available-libraries
+
+// Your web app's Firebase configuration
+// For Firebase JS SDK v7.20.0 and later, measurementId is optional
+const firebaseConfig = {
+ apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
+ authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
+ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
+ storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
+ messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGIN_SENDER_ID,
+ appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
+ measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
+};
+
+// Initialize Firebase
+const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
+export const auth = getAuth(app) ;
+if (typeof window != 'undefined'){
+ const analytics = getAnalytics(app)
+}
diff --git a/services/requests.tsx b/services/requests.tsx
index f77581d..b11982d 100644
--- a/services/requests.tsx
+++ b/services/requests.tsx
@@ -1,8 +1,9 @@
-const API_KEY = '8216fbb9997cd81a67471e6cb5a6f2df'
-
-const requests = {
- fetchTopRated: `/movie/top_rated?api_key=${API_KEY}`,
- fetchTrending: `/trending/movie/day?api_key=${API_KEY}`,
-}
-
+const API_KEY = '8216fbb9997cd81a67471e6cb5a6f2df'
+
+const requests = {
+ fetchTopRated: `/movie/top_rated?api_key=${API_KEY}`,
+ fetchTrendingMovies: `/trending/movie/day?api_key=${API_KEY}`,
+ fetchTrendingTv: `/trending/tv/day?api_key=${API_KEY}`,
+}
+
export default requests \ No newline at end of file
diff --git a/src/components/Genre.tsx b/src/components/Genre.tsx
deleted file mode 100644
index e63a26a..0000000
--- a/src/components/Genre.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { useEffect, useState } from "react"
-
-const Genres = ({id}) => {
-
- const baseURL = 'https://api.themoviedb.org/3'
- const API_KEY = '8216fbb9997cd81a67471e6cb5a6f2df'
- const [genres, setGenres] = useState()
-
- useEffect(() => {
- fetch(`${baseURL}/movie/${id}?api_key=${API_KEY}`).then((res) => res.json()).then((data) => {
- console.log('MOVIE', data.genres)
- setGenres(data.genres)
- })
- }, [])
-
- return (
- <div className="text-white/60 gap-x-3 text-xs flex flex-row flex-wrap relative">
- {genres?.map((genre) => {
- return (
- <div>{genre.name}</div>
- )
- })}
- </div>
- )
-}
-
-export default Genres \ No newline at end of file
diff --git a/src/components/PreviewCard.tsx b/src/components/PreviewCard.tsx
deleted file mode 100644
index 5c4129f..0000000
--- a/src/components/PreviewCard.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-const imageURL = 'https://image.tmdb.org/t/p/original';
-import Genre from "./Genre";
-const baseURL ='https://api.themoviedb.org/3/'
-
-const PreviewCard = ({ movie }) => {
- return (
- <div className="hover:z-10">
- <div className="rounded ring-white hover:ring-4 flex-col p-1 relative bg-cover h-32 w-60 shrink-0 flex justify-end cursor-pointer hover:scale-125 transition ease-in-out" style={{backgroundImage: `url(${imageURL}${movie?.backdrop_path})`}}>
- <div className="absolute h-full w-full inset-0 bg-gradient-to-t from-black/70"></div>
- <h3 className={"text-white text-sm relative"}>
- {movie.original_title}
- </h3>
- <Genre id={movie.id}/>
- </div>
- </div>
- )}
-
-
-export default PreviewCard \ No newline at end of file
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index e57ed44..c055f25 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,4 +1,4 @@
-import '@prueba/styles/globals.css'
+import '../styles/globals.css'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 9fbd6c7..ccea7d8 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -22,4 +22,5 @@ body {
::-webkit-scrollbar {
width: 0px;
+ display: none;
} \ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
index fba2ad6..00649fb 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -4,6 +4,7 @@ module.exports = {
'./src/pages/**/*.{js,ts,jsx,tsx}',
'./src/components/**/*.{js,ts,jsx,tsx}',
'./src/app/**/*.{js,ts,jsx,tsx}',
+ './app/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
diff --git a/tsconfig.json b/tsconfig.json
index c068872..0f5c44e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "es5",
- "lib": ["dom", "dom.iterable", "esnext"],
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -15,9 +19,23 @@
"jsx": "preserve",
"incremental": true,
"paths": {
- "@prueba/*": ["./src/*"]
- }
+ "@prueba/*": [
+ "./src/*"
+ ]
+ },
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
- "exclude": ["node_modules"]
-}
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}