Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ENV=DEV
PORT=5001
6 changes: 4 additions & 2 deletions backend/src/controllers/like.controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const seriesCurtidas = async (req, res) => {
};

export const curtir = async(req, res) => {
console.log(req.body)
try {

const { userid } = req.params;
Expand Down Expand Up @@ -71,6 +72,7 @@ export const descurtir = async(req,res) => {
const filePath = path.resolve('./src/database/users.json');
const { userid } = req.params;
const { serie } = req.body;

// Ler o arquivo JSON
let data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));

Expand All @@ -97,8 +99,8 @@ export const descurtir = async(req,res) => {
console.log(`Série "${serie}" não encontrada para o usuário "${userid}"`);
return res.status(400).json({ error: "Série não encontrada na lista do usuário" });
}

// Remover a série do array
// // Remover a série do array
user["Séries Curtidas"] = user["Séries Curtidas"].filter(s => s !== serie);

// Escrever de volta no arquivo JSON
Expand Down
29 changes: 16 additions & 13 deletions backend/src/database/users.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
{
"user": "Sistema",
"top10": [
"The Boys",
"Breaking Bad",
"The Last of Us",
"Marley e Eu",
"Vingadores: Guerra Infinita",
"The Walking Dead",
"The Batman",
"Ainda estou aqui",
"La La Land",
"Valente"
"howls-moving-castle",
"the-hangover",
"superbad",
"la-la-land",
"the-notebook",
"a-quiet-place",
"it",
"jumanji",
"mad-max",
"alien"
],
"terror": [
"A Freira",
Expand All @@ -22,15 +22,18 @@
"The Batman"
],
"geral": [
"Moana 2",
"Zootopia"
"black-panther",
"alien",
"mad-max",
"jumanji"
],
"id": 1
},
{
"user": "Ykaro",
"Séries Curtidas": [
"Breaking Bad"
"mad-max",
"black-panther"
],
"historicoDeVisualizacao": [
"O Incrível Hulk",
Expand Down
4 changes: 3 additions & 1 deletion backend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const app = express()
dotenv.config()
app.use(express.json())
app.use(cookieParser())
app.use(cors());
app.use(cors({
origin: "http://localhost:3000"
}))

// Route imports
import userRoutes from './routes/users.routes.js'
Expand Down
68 changes: 48 additions & 20 deletions frontend/cinevideo/app/filme/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,68 @@ import { useState, useEffect } from "react"
import { Heart, ArrowLeft, Play } from "lucide-react"

export default function MoviePage({ params }: { params: { id: string } }) {
const userId = "Ykaro"
const movieId = params.id
const movie = getMovieById(movieId)
const [likedMovies, setLikedMovies] = useState<string[]>([]) // IDs dos filmes curtidos
const [liked, setLiked] = useState(false) // Estado do botão curtir

// Estado para controlar se o filme foi curtido
const [liked, setLiked] = useState(false)
// Buscar os filmes curtidos ao carregar a página
useEffect(() => {
const fetchLikedMovies = async () => {
try {
const response = await fetch(`http://localhost:4000/user/seriesCurtidas/${userId}`)
if (!response.ok) {
throw new Error("Erro ao buscar filmes curtidos")
}
const data = await response.json()
setLikedMovies(data) // Atualiza a lista de IDs dos filmes curtidos
} catch (error) {
console.error("Erro ao buscar filmes curtidos:", error)
}
}

fetchLikedMovies()
}, [userId])

// Ao carregar a página, verificar no localStorage se o filme foi curtido antes
// Verificar se o filme atual está curtido após o estado `likedMovies` ser atualizado
useEffect(() => {
const likedMovies = JSON.parse(localStorage.getItem("likedMovies") || "[]")
setLiked(likedMovies.includes(movieId))
}, [movieId])
setLiked(likedMovies.includes(movieId)) // Se o ID do filme estiver na lista, define `liked` como true
}, [likedMovies, movieId])

// Função para curtir/descurtir um filme e salvar no localStorage
const toggleLike = () => {
const likedMovies = JSON.parse(localStorage.getItem("likedMovies") || "[]")
// Função para curtir/descurtir um filme
const toggleLike = async () => {
try {
const url = liked
? `http://localhost:4000/user/descurtir/${userId}`
: `http://localhost:4000/user/curtir/${userId}`

const response = await fetch(url, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ serie: movieId })
})

if (liked) {
// Se já estava curtido, remover do array
const updatedLikes = likedMovies.filter((id: string) => id !== movieId)
localStorage.setItem("likedMovies", JSON.stringify(updatedLikes))
} else {
// Se não estava curtido, adicionar ao array
likedMovies.push(movieId)
localStorage.setItem("likedMovies", JSON.stringify(likedMovies))
}
if (!response.ok) {
throw new Error("Erro ao atualizar curtida")
}

setLiked(!liked)
setLiked(!liked) // Atualiza o estado local se a requisição for bem-sucedida
setLikedMovies((prev) =>
liked ? prev.filter((id) => id !== movieId) : [...prev, movieId]
)
} catch (error) {
console.error("Erro ao curtir/descurtir o filme:", error)
}
}

if (!movie) {
return (
<div className="min-h-screen bg-white p-4 flex flex-col items-center justify-center">
<h1 className="text-2xl font-bold mb-4">Filme não encontrado</h1>
<Link href="/" className="text-[#e31010] hover:underline">Voltar para a página inicial</Link>
<Link href="/" className="text-[#e31010] hover:underline">
Voltar para a página inicial
</Link>
</div>
)
}
Expand Down
72 changes: 51 additions & 21 deletions frontend/cinevideo/app/likedSeries/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,70 @@ import Image from "next/image"
import { ArrowLeft } from "lucide-react"

export default function LikedMoviesPage() {
const [likedMovies, setLikedMovies] = useState<any[]>([])
const [likedMovies, setLikedMovies] = useState<any[]>([]) // IDs dos filmes curtidos
const [movieDetails, setMovieDetails] = useState<any[]>([]) // Detalhes dos filmes
const userId = "Ykaro"

useEffect(() => {
// Pega os IDs dos filmes curtidos do localStorage
const likedMoviesIds = JSON.parse(localStorage.getItem("likedMovies") || "[]")
const fetchLikedMovies = async () => {
try {
const response = await fetch(`http://localhost:4000/user/seriesCurtidas/${userId}`);
if (!response.ok) {
throw new Error("Erro ao buscar filmes curtidos");
}
const data = await response.json();
setLikedMovies(data); // Armazenar os IDs dos filmes curtidos
} catch (error) {
console.error("Erro ao buscar filmes curtidos:", error);
}
};

// Busca os detalhes de cada filme
const movies = likedMoviesIds.map((id: string) => getMovieById(id)).filter(Boolean)
fetchLikedMovies();
}, [userId])

setLikedMovies(movies)
}, [])
useEffect(() => {
const fetchMovieDetails = async () => {
const movies = await Promise.all(
likedMovies.map(async (movieId) => {
const movie = await getMovieById(movieId);
return movie;
})
);
setMovieDetails(movies);
};

if (likedMovies.length > 0) {
fetchMovieDetails();
}
}, [likedMovies]);

return (
<div className="min-h-screen bg-white p-4">
<div className="mb-6">
<Link href="/" className="inline-flex items-center text-[#e31010] hover:underline">
<ArrowLeft className="mr-2 h-4 w-4" />
Voltar para a página inicial
</Link>
</div>
<div className="mb-6">
<Link href="/" className="inline-flex items-center text-[#e31010] hover:underline">
<ArrowLeft className="mr-2 h-4 w-4" />
Voltar para a página inicial
</Link>
</div>
<h1 className="text-3xl font-bold text-[#e31010] mb-6">Filmes Curtidos</h1>

{likedMovies.length === 0 ? (
{movieDetails.length === 0 ? (
<p>Nenhum filme curtido ainda.</p>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
{likedMovies.map((movie) => (
{movieDetails.map((movie) => (
<div key={movie.id} className="bg-[#d9d9d9] p-2">
<Link href={`/filme/${movie.id}`} className="text-[#e31010] hover:underline">
<div className="aspect-[2/3] relative">
<Image src={movie.posterUrl || "/placeholder.svg"} alt={movie.title} fill className="object-cover" />
</div>
<h2 className="text-lg font-bold mt-2">{movie.title}</h2>
</Link>
<Link href={`/filme/${movie.id}`} className="text-[#e31010] hover:underline">
<div className="aspect-[2/3] relative">
<Image
src={movie.posterUrl || "/placeholder.svg"}
alt={movie.title}
fill
className="object-cover"
/>
</div>
<h2 className="text-lg font-bold mt-2">{movie.title}</h2>
</Link>
</div>
))}
</div>
Expand Down
77 changes: 74 additions & 3 deletions frontend/cinevideo/components/cinevideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ import Image from "next/image"
import Link from "next/link"
import { useState, useEffect } from "react"
import { movieData } from "@/lib/movie-data"
import { getMovieById } from "@/lib/movie-data"

export default function CineVideo() {
// Estado para controlar a exibição do menu de gêneros
const [showGenres, setShowGenres] = useState(false)
const [topTenMovies, setTopTenMovies] = useState<string[]>([]) // IDs dos filmes do top 10
const [recomendationsMovies, setRecomendationsMovies] = useState<string[]>([]) // IDs dos filmes da lista de recomendações
const [movieDetails, setMovieDetails] = useState<any[]>([]) // Detalhes dos filmes
const [movieDetailsRec, setMovieDetailsRec] = useState<any[]>([]) // Detalhes dos filmes
// Estado para o termo de pesquisa
const [searchTerm, setSearchTerm] = useState("")
// Estado para controlar se a pesquisa foi submetida
const [isSearching, setIsSearching] = useState(false)

// Verificar se há um termo de pesquisa na URL ao carregar a página
useEffect(() => {

// Verificar se há um termo de pesquisa na URL ao carregar a página
if (typeof window !== "undefined") {
const urlParams = new URLSearchParams(window.location.search)
const searchParam = urlParams.get("search")
Expand All @@ -24,8 +30,73 @@ export default function CineVideo() {
setIsSearching(true)
}
}


const fetchTop10 = async () => {
try {
const response = await fetch(`http://localhost:4000/user/top10/Sistema`)
if (!response.ok) {
throw new Error("Erro ao buscar filmes do top 10")
}
const data = await response.json()
setTopTenMovies(data) // Atualiza a lista de IDs dos filmes curtidos
} catch (error) {
console.error("Erro ao buscar filmes do top 10:", error)
}
}

const fetchRecomendations = async () => {
try {
const response = await fetch(`http://localhost:4000/user/Sistema/series`)
if (!response.ok) {
throw new Error("Erro ao buscar filmes recomendados")
}
const NewData = await response.json()
setRecomendationsMovies(NewData) // Atualiza a lista de IDs dos filmes curtidos
} catch (error) {
console.error("Erro ao buscar filmes recomendados:", error)
}
}

fetchTop10()
fetchRecomendations()
}, [])

useEffect(() => {
const fetchMovieDetails = async () => {
const movies = await Promise.all(
topTenMovies.map(async (movieId) => {
const movie = await getMovieById(movieId);
return movie;
})
);
setMovieDetails(movies);
};

const fetchMovieDetailsRec = async () => {
const movies = await Promise.all(
recomendationsMovies.map(async (movieId) => {
const movie = await getMovieById(movieId);
return movie;
})
);
setMovieDetailsRec(movies);
};



if (topTenMovies.length > 0) {
fetchMovieDetails();
}


if (recomendationsMovies.length > 0) {
fetchMovieDetailsRec();
}


}, [topTenMovies, recomendationsMovies]);

// Lista de gêneros disponíveis
const genres = [
{ id: "acao", name: "Ação" },
Expand Down Expand Up @@ -147,7 +218,7 @@ export default function CineVideo() {
{/* Seção Top 10 Filmes */}
<section className="mb-12">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
{top10Movies.map((movie) => (
{movieDetails.map((movie) => (
<MovieCard key={movie.id} movie={movie} />
))}
</div>
Expand All @@ -157,7 +228,7 @@ export default function CineVideo() {
<section>
<h2 className="text-[#e31010] text-3xl font-bold mb-6">Recomendados</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
{recommendedMovies.map((movie) => (
{movieDetailsRec.map((movie) => (
<MovieCard key={movie.id} movie={movie} />
))}
</div>
Expand Down