Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.env
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you prefer visual learning, this is the perfect resource for you. Follow our

Built with React.js for the user interface, Appwrite for the Trending Movies Algorithm, and styled with TailwindCSS, Moodflix is a website project designed to help beginners get started with learning React.js. The platform offers a sleek and modern experience for browsing and discovering movies.

If you're getting started and need assistance or face any bugs, join our active Discord community with over **50k+** members. It's a place where people help each other out.
If you"re getting started and need assistance or face any bugs, join our active Discord community with over **50k+** members. It"s a place where people help each other out.

<a href="https://discord.com/invite/n6EdbFJ" target="_blank"><img src="https://github.com/sujatagunale/EasyRead/assets/151519281/618f4872-1e10-42da-8213-1d69e486d02e" /></a>

Expand Down Expand Up @@ -293,7 +293,7 @@ Public assets used in the project can be found [here](https://drive.google.com/f

**Advance your skills with Next.js Pro Course**

Enjoyed creating this project? Dive deeper into our PRO courses for a richer learning adventure. They're packed with
Enjoyed creating this project? Dive deeper into our PRO courses for a richer learning adventure. They"re packed with
detailed explanations, cool features, and exercises to boost your skills. Give it a go!

<a href="https://jsmastery.pro/next15" target="_blank">
Expand Down
32 changes: 16 additions & 16 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import js from "@eslint/js"
import globals from "globals"
import react from "eslint-plugin-react"
import reactHooks from "eslint-plugin-react-hooks"
import reactRefresh from "eslint-plugin-react-refresh"

export default [
{ ignores: ['dist'] },
{ ignores: ["dist"] },
{
files: ['**/*.{js,jsx}'],
files: ["**/*.{js,jsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaVersion: "latest",
ecmaFeatures: { jsx: true },
sourceType: 'module',
sourceType: "module",
},
},
settings: { react: { version: '18.3' } },
settings: { react: { version: "18.3" } },
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...react.configs["jsx-runtime"].rules,
...reactHooks.configs.recommended.rules,
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
"react/jsx-no-target-blank": "off",
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
Expand Down
38 changes: 19 additions & 19 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { useEffect, useState } from 'react'
import Search from './components/Search.jsx'
import Spinner from './components/Spinner.jsx'
import MovieCard from './components/MovieCard.jsx'
import { useDebounce } from 'react-use'
import { getTrendingMovies, updateSearchCount } from './appwrite.js'
import { useEffect, useState } from "react"
import Search from "./components/Search.jsx"
import Spinner from "./components/Spinner.jsx"
import MovieCard from "./components/MovieCard.jsx"
import { useDebounce } from "react-use"
import { getTrendingMovies, updateSearchCount } from "./appwrite.js"

const API_BASE_URL = 'https://api.themoviedb.org/3';
const API_BASE_URL = "https://api.themoviedb.org/3";

const API_KEY = import.meta.env.VITE_TMDB_API_KEY;

const API_OPTIONS = {
method: 'GET',
method: "GET",
headers: {
accept: 'application/json',
accept: "application/json",
Authorization: `Bearer ${API_KEY}`
}
}

const App = () => {
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('')
const [searchTerm, setSearchTerm] = useState('');
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("")
const [searchTerm, setSearchTerm] = useState("");

const [movieList, setMovieList] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [errorMessage, setErrorMessage] = useState("");
const [isLoading, setIsLoading] = useState(false);

const [trendingMovies, setTrendingMovies] = useState([]);
Expand All @@ -31,9 +31,9 @@ const App = () => {
// by waiting for the user to stop typing for 500ms
useDebounce(() => setDebouncedSearchTerm(searchTerm), 500, [searchTerm])

const fetchMovies = async (query = '') => {
const fetchMovies = async (query = "") => {
setIsLoading(true);
setErrorMessage('');
setErrorMessage("");

try {
const endpoint = query
Expand All @@ -43,13 +43,13 @@ const App = () => {
const response = await fetch(endpoint, API_OPTIONS);

if(!response.ok) {
throw new Error('Failed to fetch movies');
throw new Error("Failed to fetch movies");
}

const data = await response.json();

if(data.Response === 'False') {
setErrorMessage(data.Error || 'Failed to fetch movies');
if(data.Response === "False") {
setErrorMessage(data.Error || "Failed to fetch movies");
setMovieList([]);
return;
}
Expand All @@ -61,7 +61,7 @@ const App = () => {
}
} catch (error) {
console.error(`Error fetching movies: ${error}`);
setErrorMessage('Error fetching movies. Please try again later.');
setErrorMessage("Error fetching movies. Please try again later.");
} finally {
setIsLoading(false);
}
Expand Down Expand Up @@ -92,7 +92,7 @@ const App = () => {
<div className="wrapper">
<header>
<img src="./hero.png" alt="Hero Banner" />
<h1>Find <span className="text-gradient">Movies</span> You'll Enjoy Without the Hassle</h1>
<h1>Find <span className="text-gradient">Movies</span> You&apos;ll Enjoy Without the Hassle</h1>

<Search searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
</header>
Expand Down
10 changes: 5 additions & 5 deletions src/appwrite.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Client, Databases, ID, Query } from 'appwrite'
import { Client, Databases, ID, Query } from "appwrite"

const PROJECT_ID = import.meta.env.VITE_APPWRITE_PROJECT_ID;
const DATABASE_ID = import.meta.env.VITE_APPWRITE_DATABASE_ID;
const COLLECTION_ID = import.meta.env.VITE_APPWRITE_COLLECTION_ID;

const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(PROJECT_ID)

const database = new Databases(client);
Expand All @@ -14,7 +14,7 @@ export const updateSearchCount = async (searchTerm, movie) => {
// 1. Use Appwrite SDK to check if the search term exists in the database
try {
const result = await database.listDocuments(DATABASE_ID, COLLECTION_ID, [
Query.equal('searchTerm', searchTerm),
Query.equal("searchTerm", searchTerm),
])

// 2. If it does, update the count
Expand All @@ -24,7 +24,7 @@ export const updateSearchCount = async (searchTerm, movie) => {
await database.updateDocument(DATABASE_ID, COLLECTION_ID, doc.$id, {
count: doc.count + 1,
})
// 3. If it doesn't, create a new document with the search term and count as 1
// 3. If it doesn"t, create a new document with the search term and count as 1
} else {
await database.createDocument(DATABASE_ID, COLLECTION_ID, ID.unique(), {
searchTerm,
Expand All @@ -41,8 +41,8 @@ export const updateSearchCount = async (searchTerm, movie) => {
export const getTrendingMovies = async () => {
try {
const result = await database.listDocuments(DATABASE_ID, COLLECTION_ID, [
Query.orderDesc("count"),
Query.limit(5),
Query.orderDesc("count")
])

return result.documents;
Expand Down
8 changes: 4 additions & 4 deletions src/components/MovieCard.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React from "react"

const MovieCard = ({ movie:
{ title, vote_average, poster_path, release_date, original_language }
Expand All @@ -7,7 +7,7 @@ const MovieCard = ({ movie:
<div className="movie-card">
<img
src={poster_path ?
`https://image.tmdb.org/t/p/w500/${poster_path}` : '/no-movie.png'}
`https://image.tmdb.org/t/p/w500/${poster_path}` : "/no-movie.png"}
alt={title}
/>

Expand All @@ -17,15 +17,15 @@ const MovieCard = ({ movie:
<div className="content">
<div className="rating">
<img src="star.svg" alt="Star Icon" />
<p>{vote_average ? vote_average.toFixed(1) : 'N/A'}</p>
<p>{vote_average ? vote_average.toFixed(1) : "N/A"}</p>
</div>

<span>•</span>
<p className="lang">{original_language}</p>

<span>•</span>
<p className="year">
{release_date ? release_date.split('-')[0] : 'N/A'}
{release_date ? release_date.split("-")[0] : "N/A"}
</p>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Search.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React from "react"

const Search = ({ searchTerm, setSearchTerm }) => {
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Spinner.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React from "react"

const Spinner = () => {
return (
Expand Down
10 changes: 5 additions & 5 deletions src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import "./index.css"
import App from "./App.jsx"

createRoot(document.getElementById('root')).render(
createRoot(document.getElementById("root")).render(
<App />
)
6 changes: 3 additions & 3 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import tailwindcss from "@tailwindcss/vite"

// https://vite.dev/config/
export default defineConfig({
Expand Down