Skip to content

Commit

Permalink
Adding Day #38
Browse files Browse the repository at this point in the history
  • Loading branch information
AsmrProg-YT committed Jun 25, 2023
1 parent 8ef73b4 commit 68350a0
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 1 deletion.
17 changes: 17 additions & 0 deletions Day #38 - Movie App/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Day #38

### Movie App (TheMovieDB)
In this tutorial ([Open in Youtube](https://youtu.be/dButm3gpZDA)), I am gonna showing to you how to code a Movie App using JavaScript. in this video i'm using TheMovieDB api to get movies info. Also this code is fully responsive and when you scroll it will load more results❗️

## Warning
You need to get your own api key (in video we showed how!) and replace it in index.js file on line 1 :

```javascript
const apiKey = "YOUR_API_KEY";
```


# Screenshot
Here we have project screenshot :

![screenshot](screenshot.jpg)
32 changes: 32 additions & 0 deletions Day #38 - Movie App/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Day #38 - Movie App | AsmrProg</title>
</head>

<body>

<div class="container">
<div class="search-box">
<a href="#">
<h1>MovieDB Api</h1>
</a>
<form id="search-form">
<input type="text" id="search-input" placeholder="Search Movies ...">
<button class="search-btn" type="submit">Search</button>
</form>
</div>

<div id="result"></div>

</div>

<script src="index.js"></script>

</body>

</html>
120 changes: 120 additions & 0 deletions Day #38 - Movie App/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const apiKey = "YOUR_API_KEY";
const imgApi = "https://image.tmdb.org/t/p/w1280";
const searchUrl = `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&query=`;
const form = document.getElementById("search-form");
const query = document.getElementById("search-input");
const result = document.getElementById("result");

let page = 1;
let isSearching = false;

// Fetch JSON data from url
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Network response was not ok.");
}
return await response.json();
} catch (error) {
return null;
}
}

// Fetch and show results based on url
async function fetchAndShowResult(url) {
const data = await fetchData(url);
if (data && data.results) {
showResults(data.results);
}
}

// Create movie card html template
function createMovieCard(movie) {
const { poster_path, original_title, release_date, overview } = movie;
const imagePath = poster_path ? imgApi + poster_path : "./img-01.jpeg";
const truncatedTitle = original_title.length > 15 ? original_title.slice(0, 15) + "..." : original_title;
const formattedDate = release_date || "No release date";
const cardTemplate = `
<div class="column">
<div class="card">
<a class="card-media" href="./img-01.jpeg">
<img src="${imagePath}" alt="${original_title}" width="100%" />
</a>
<div class="card-content">
<div class="card-header">
<div class="left-content">
<h3 style="font-weight: 600">${truncatedTitle}</h3>
<span style="color: #12efec">${formattedDate}</span>
</div>
<div class="right-content">
<a href="${imagePath}" target="_blank" class="card-btn">See Cover</a>
</div>
</div>
<div class="info">
${overview || "No overview yet..."}
</div>
</div>
</div>
</div>
`;
return cardTemplate;
}

// Clear result element for search
function clearResults() {
result.innerHTML = "";
}

// Show results in page
function showResults(item) {
const newContent = item.map(createMovieCard).join("");
result.innerHTML += newContent || "<p>No results found.</p>";
}

// Load more results
async function loadMoreResults() {
if (isSearching) {
return;
}
page++;
const searchTerm = query.value;
const url = searchTerm ? `${searchUrl}${searchTerm}&page=${page}` : `https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=${apiKey}&page=${page}`;
await fetchAndShowResult(url);
}

// Detect end of page and load more results
function detectEnd() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 20) {
loadMoreResults();
}
}

// Handle search
async function handleSearch(e) {
e.preventDefault();
const searchTerm = query.value.trim();
if (searchTerm) {
isSearching = true;
clearResults();
const newUrl = `${searchUrl}${searchTerm}&page=${page}`;
await fetchAndShowResult(newUrl);
query.value = "";
}
}

// Event listeners
form.addEventListener('submit', handleSearch);
window.addEventListener('scroll', detectEnd);
window.addEventListener('resize', detectEnd);

// Initialize the page
async function init() {
clearResults();
const url = `https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=${apiKey}&page=${page}`;
isSearching = false;
await fetchAndShowResult(url);
}

init();
Binary file added Day #38 - Movie App/screenshot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
152 changes: 152 additions & 0 deletions Day #38 - Movie App/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');

*{
margin: 0;
outline: none;
font-family: 'Poppins', sans-serif;
box-sizing: border-box;
}

a{
color: #fff;
text-decoration: none;
}

body{
color: #fff;
background-color: #212121;
padding: 1.5rem;
}

.search-box{
width: 100%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
max-width: 1200px;
align-items: center;
margin: 15px 0 30px 0;
}

.search-box form{
display: flex;
max-width: 400px;
}

.search-box input{
width: 100%;
max-width: 400px;
padding: 8px;
border-radius: 0.4rem 0 0 0.4rem;
border: none;
background-color: rgba(255, 255, 255, 0.9);
}

.search-box .search-btn{
width: 120px;
background-color: #01579b;
color: #fff;
cursor: pointer;
padding: 6px 8px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 0 0.4rem 0.4rem 0;
transition: all 0.5s ease;
}

.search-box .search-btn:hover{
background-color: #0091ea;
border: 1px solid #fff;
}

.container{
width: 100%;
max-height: 100vh;
display: flex;
align-items: center;
flex-direction: column;
}

.container .card{
position: relative;
font-size: 14px;
border: 1px solid rgba(255, 255, 255, 0.6);
border-radius: 0.4rem;
line-height: 20px;
width: 285px;
height: 360px;
overflow: hidden;
transition: all 0.5s ease;
}

.container .card .card-content{
width: 100%;
position: absolute;
bottom: 0;
left: 0;
padding: 100px 10px 5px;
background-image: linear-gradient(180deg, rgba(51, 55, 69, 0), rgba(16, 21, 40, 0.95));
transition: all 0.5s ease;
}

.container .card .card-content .card-header{
padding: 8px 0;
display: flex;
align-items: center;
justify-content: space-between;
}

.container .card .card-content .card-btn{
color: #fff;
cursor: pointer;
padding: 6px 8px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 0.4rem;
transition: all 0.5s ease;
}

.container .card .card-content .info{
max-height: 0;
opacity: 0;
border-top: 1px solid rgba(255, 255, 255, 0.3);
overflow: hidden;
transition: all 0.5s ease;
}

.container .card:hover{
cursor: pointer;
}

.container .card:hover .card-content{
background-image: linear-gradient(180deg, rgba(51, 55, 69, 0), #101528 48%);
}

.container .card:hover .card-btn{
background-color: #0091ea;
border-color: #0091ea;
}

.container .card:hover .info{
max-height: 200px;
opacity: 1;
padding: 8px 0;
}

#result{
display: flex;
max-width: 1200px;
gap: 15px;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}

@media screen and (max-width: 550px) {
.search-box{
justify-content: center;
}

.search-box form{
margin-top: 10px;
}

}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ Here we have list of projects:
35. ASCII Donut Animation
36. Stock Tracker App
37. Box Shadow Generator
38. Movie App (TheMovieDB)

## Where is rest 63 Projects
## Where is rest 62 Projects

We create a project each 3 days with voting on our <a href="https://youtube.com/@AsmrProg" target="_blank">Youtube</a> channel.
You can vote for upcoming projects on our channel **community** page :wink:

0 comments on commit 68350a0

Please sign in to comment.