diff --git a/client/src/api/history.api.js b/client/src/api/history.api.js index 3ee23da..c1c34c2 100644 --- a/client/src/api/history.api.js +++ b/client/src/api/history.api.js @@ -7,6 +7,11 @@ export const getHistory = async (userId) => { return res.data; } +export const getMovieHistory = async (movieId) => { + const res = await axiosInstance.get(`/history/movie/${movieId}`); + return res.data; +} + export const getHistoryBanner = async () => { const res = await axiosInstance.get('/history'); return res.data; diff --git a/client/src/api/watchList.api.js b/client/src/api/watchList.api.js new file mode 100644 index 0000000..eb17523 --- /dev/null +++ b/client/src/api/watchList.api.js @@ -0,0 +1,6 @@ +import axiosInstance from "./axiosInstance" + +export const getIsMovieWatchListed = async (movieId) => { + const res = await axiosInstance.get(`/watchlist/movie/${movieId}`); + return res.data; +} \ No newline at end of file diff --git a/client/src/components/Navbar.jsx b/client/src/components/Navbar.jsx index 6bb7349..a5d30ee 100644 --- a/client/src/components/Navbar.jsx +++ b/client/src/components/Navbar.jsx @@ -1,5 +1,5 @@ import { Link, useLocation, useNavigate } from "react-router-dom"; -import { useState } from "react"; +import { useState, useRef, useEffect } from "react"; import useUserStore from "../store/userStore"; import Modal from "./ui/Modal"; import { @@ -9,11 +9,27 @@ import { TicketIcon } from "@heroicons/react/24/outline"; import SearchBar from "./ui/SearchBar"; +import Dropdown from "./ui/Dropdown"; +import { ClockIcon } from "lucide-react"; export default function Navbar() { - const [open, setOpen] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); const { user, logout } = useUserStore(); const location = useLocation(); + const navigate = useNavigate(); + + const searchWrapperRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event) => { + if (searchWrapperRef.current && !searchWrapperRef.current.contains(event.target)) { + setIsDropdownOpen(false); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); const getUserInitials = () => { const userData = user?.user || user; @@ -21,20 +37,41 @@ export default function Navbar() { return (userData.firstName[0] + (userData.lastName?.[0] || "")).toUpperCase(); }; - const navigate = useNavigate(); + // Save search query to localStorage + const saveSearchQuery = (query) => { + if (!query.trim()) return; + const key = "searchHistory"; + let history = JSON.parse(localStorage.getItem(key)) || []; + + // Remove duplicate if exists + history = history.filter(item => item.query !== query); + + history.unshift({ query, timeStamp: Date.now() }); + + if (history.length > 5) history.pop(); + localStorage.setItem(key, JSON.stringify(history)); + }; + + // Handle search const handleSearch = (query) => { + if (!query.trim()) return; + + saveSearchQuery(query); + navigate(`/search?q=${query}`); + setIsDropdownOpen(false); }; const isActive = (path) => location.pathname === path; + // Get search history + const searchHistory = JSON.parse(localStorage.getItem("searchHistory")) || []; + return (