From c0246068ba1c3357b4cd09c8eaa7ca9074d4691d Mon Sep 17 00:00:00 2001 From: Hein Tay Zar Date: Wed, 23 Nov 2022 04:07:21 +0630 Subject: [PATCH 1/4] Add Comment Section --- src/modules/api/Comment.js | 42 +++++++++++++++++++++++++++++ src/modules/api/ShowApi.js | 7 ++--- src/modules/router/router.js | 3 ++- src/modules/show.js | 51 ++++++++++++++++++++++++++++++++++-- src/style.css | 30 +++++++++++++++++++++ 5 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 src/modules/api/Comment.js diff --git a/src/modules/api/Comment.js b/src/modules/api/Comment.js new file mode 100644 index 0000000..f361dfc --- /dev/null +++ b/src/modules/api/Comment.js @@ -0,0 +1,42 @@ +import axios from 'axios'; + +export default class Comments { + constructor() { + this.involvementApi = process.env.INVOLVEMENT_API_LINK; + this.involvementApiId = process.env.INVOLVEMENT_ID; + this.commentsEndPoint = `/apps/${this.involvementApiId}/comments`; + this.commentsAllEndPoint = `/apps/${this.involvementApiId}/comments?item_id=`; + } + + getComments = async (id) => { + try { + // eslint-disable-next-line consistent-return + return await axios.get(`${this.involvementApi}${this.commentsAllEndPoint}${id}`).then((res) => { + if (res.status === 200) { + return res; + } + throw new Error('Fail'); + }); + } catch (error) { + return false; + } + } + + addComment = async (itemId, username, comment) => { + try { + // eslint-disable-next-line consistent-return + return await axios.post(`${this.involvementApi}${this.commentsEndPoint}`, { + item_id: itemId, + username, + comment, + }).then((res) => { + if (res.status === 201) { + return true; + } + throw new Error('Fail'); + }); + } catch (error) { + throw new Error('Fail'); + } + } +} \ No newline at end of file diff --git a/src/modules/api/ShowApi.js b/src/modules/api/ShowApi.js index e57589b..fdeb7f2 100644 --- a/src/modules/api/ShowApi.js +++ b/src/modules/api/ShowApi.js @@ -1,13 +1,14 @@ import axios from 'axios'; // eslint-disable-next-line import/no-cycle, import/no-unresolved import { navigator } from '../router/router.js'; +// eslint-disable-next-line import/no-cycle +import Comments from './Comment.js'; -export default class ShowApi { +export default class ShowApi extends Comments { constructor() { + super(); this.movieApi = process.env.MOVIEDB_API_LINK; this.movieApiSecret = process.env.MOVIEDB_API_SECRET; - this.involvementApi = process.env.INVOLVEMENT_API_LINK; - this.involvementApiId = process.env.INVOLVEMENT_ID; this.apiSecretCall = `?api_key=${this.movieApiSecret}&language=en-US`; this.noMovieMsg = 'Request failed with status code 404'; } diff --git a/src/modules/router/router.js b/src/modules/router/router.js index b6a6bf5..1102451 100644 --- a/src/modules/router/router.js +++ b/src/modules/router/router.js @@ -25,12 +25,13 @@ const scrollToTop = () => { set to el.innerHtml */ const newPage = async (Page, el, obj = {}) => { - // intiial image should be null + // initial image should be null const images = document.querySelectorAll('.image'); images.forEach((image) => { image.innerHTML = ''; }); imgHelper(); const page = new Page(); el.innerHTML = await page.html(obj); + await page.js(); links(); scrollToTop(); }; diff --git a/src/modules/show.js b/src/modules/show.js index 2fb08d8..d158506 100644 --- a/src/modules/show.js +++ b/src/modules/show.js @@ -6,6 +6,7 @@ export default class Show extends ShowApi { super(); this.color = ['blue', 'green', 'red', 'aqua', 'lightblue']; this.photo = 'https://image.tmdb.org/t/p/original'; + this.itemNotFound = "item_id' not found."; } toText = (num) => { @@ -49,7 +50,7 @@ export default class Show extends ShowApi { toRecommendations = (data) => { let string = ''; for (let i = 0; i < 5 && i < data.length; i += 1) { - string += `
${this.checkNull(data[i].poster_path, `photo`)}
${data[i].title}
`; + string += `
${this.checkNull(data[i].poster_path, `photo`)}
${(data[i].title.length > 20) ? `${data[i].title.slice(0, 20)}...` : data[i].title}
`; } return string; } @@ -61,6 +62,39 @@ export default class Show extends ShowApi { return text; } + toDate = (str) => { + const date = new Date(str); + return `${date.getDate()}/${date.getMonth()}/${date.getFullYear()}`; + } + + toComments = (data) => { + let string = ''; + data.forEach((comment) => { + string += `
+ ${this.toDate(comment.creation_date)} + ${comment.username} + ${comment.comment} +
`; + }); + return string; + } + + js = () => { + const form = document.querySelector('.form'); + + form.addEventListener('submit', async (e) => { + e.preventDefault(); + const commentsEl = document.querySelector('.comments'); + this.addComment(e.target.id, e.target[0].value, e.target[1].value).then(async (res) => { + if (res === true) { + const comments = await this.getComments(e.target.id); + commentsEl.innerHTML = this.toComments(comments.data); + e.target.reset(); + } + }); + }); + } + html = async ({ hash }) => { const res = await this.show(Number(hash)).then((data) => data); const { @@ -68,10 +102,11 @@ export default class Show extends ShowApi { } = res; const posterPath = res.poster_path; const rating = res.vote_average; - const releaseDate = res.release_date; + const releaseDate = this.toDate(res.release_date); const language = res.original_language; const people = await this.people(id).then((data) => data); const recommendations = await this.recommendations(id).then((data) => data); + const comments = await this.getComments(id); return (`
@@ -105,6 +140,18 @@ export default class Show extends ShowApi {
${this.toRecommendations(recommendations.results)}
+ +

Comments(${(comments === false) ? 0 : comments.data.length})

+
+ ${(comments === false) ? 'No comments yet' : this.toComments(comments.data)} +
+ +

Add a comment

+
+ + + +
` diff --git a/src/style.css b/src/style.css index eb3d031..8114584 100644 --- a/src/style.css +++ b/src/style.css @@ -247,6 +247,36 @@ footer { flex-wrap: wrap; } +.comment-form { + display: grid; + grid-template-columns: 100%; + gap: 20px; +} + +.input-box { + padding: 5px; +} + +.input-name { + width: 375px; +} + +.input-btn { + padding: 10px; + width: 100px; +} + +.comments { + display: grid; + grid-template-columns: 1fr; + gap: 15px; +} + +.comment { + display: flex; + gap: 10px; +} + .spaLink { cursor: pointer; } From 6b833aef9a3b9e398000e288fafd0cb5b3382894 Mon Sep 17 00:00:00 2001 From: Hein Tay Zar Date: Wed, 23 Nov 2022 13:25:09 +0630 Subject: [PATCH 2/4] Fix routers and make comment counter --- src/modules/api/Comment.js | 6 ++++-- src/modules/api/ShowApi.js | 2 -- src/modules/main.js | 3 +++ src/modules/router/router.js | 8 +------- src/modules/show.js | 17 ++++++++++++++--- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/modules/api/Comment.js b/src/modules/api/Comment.js index f361dfc..ac2fc1f 100644 --- a/src/modules/api/Comment.js +++ b/src/modules/api/Comment.js @@ -8,6 +8,7 @@ export default class Comments { this.commentsAllEndPoint = `/apps/${this.involvementApiId}/comments?item_id=`; } + // eslint-disable-next-line consistent-return getComments = async (id) => { try { // eslint-disable-next-line consistent-return @@ -15,10 +16,11 @@ export default class Comments { if (res.status === 200) { return res; } - throw new Error('Fail'); }); } catch (error) { - return false; + if (error.response) { + return false; + } } } diff --git a/src/modules/api/ShowApi.js b/src/modules/api/ShowApi.js index fdeb7f2..e6ce4a6 100644 --- a/src/modules/api/ShowApi.js +++ b/src/modules/api/ShowApi.js @@ -44,8 +44,6 @@ export default class ShowApi extends Comments { }); } catch (error) { if (error.message === this.noMovieMsg) { - // window.history.pushState({ path: '404' }, '404', 'error'); - // navigator('/404'); throw new Error('No such page'); } throw new Error('No such page'); diff --git a/src/modules/main.js b/src/modules/main.js index 75215c3..af225a1 100644 --- a/src/modules/main.js +++ b/src/modules/main.js @@ -12,4 +12,7 @@ export default class Main { links(); }); }; + + js = async () => { + } } \ No newline at end of file diff --git a/src/modules/router/router.js b/src/modules/router/router.js index 1102451..0254f2b 100644 --- a/src/modules/router/router.js +++ b/src/modules/router/router.js @@ -55,8 +55,6 @@ const noPage = (el) => { // for main navigation const navigator = (path) => { - // get main - const main = document.querySelector('.main'); let route = path; let hash; if (route.includes('#')) { @@ -65,19 +63,15 @@ const navigator = (path) => { } const routeInfo = routerInstance.routes.filter((rou) => (rou.path === route || `${rou.path}/` === route))[0]; if (!routeInfo || path === '404') { - noPage(main); // eslint-disable-next-line no-use-before-define router(); } else if (routeInfo.params && hash) { - newPage(routeInfo.page, main, { hash: Number(window.location.hash) }); // eslint-disable-next-line no-use-before-define router(); } else if (!routeInfo.params) { - newPage(routeInfo.page, main, {}); // eslint-disable-next-line no-use-before-define router(); } else { - noPage(main); // eslint-disable-next-line no-use-before-define router(); } @@ -86,7 +80,7 @@ const navigator = (path) => { /** * navigate according to button */ -const navigate = (event) => { +const navigate = async (event) => { event.preventDefault(); let route = event.target.attributes[0].value; let hash; diff --git a/src/modules/show.js b/src/modules/show.js index d158506..0577ab3 100644 --- a/src/modules/show.js +++ b/src/modules/show.js @@ -50,7 +50,7 @@ export default class Show extends ShowApi { toRecommendations = (data) => { let string = ''; for (let i = 0; i < 5 && i < data.length; i += 1) { - string += `
${this.checkNull(data[i].poster_path, `photo`)}
${(data[i].title.length > 20) ? `${data[i].title.slice(0, 20)}...` : data[i].title}
`; + string += `
${this.checkNull(data[i].poster_path, `photo`)}
${(data[i].title.length > 20) ? `${data[i].title.slice(0, 20)}...` : data[i].title}
`; } return string; } @@ -79,6 +79,13 @@ export default class Show extends ShowApi { return string; } + commentsLength = () => { + const commentsLength = document.querySelector('#comments-length'); + const comments = document.querySelectorAll('.comment'); + commentsLength.innerHTML = comments.length; + return comments.length; + } + js = () => { const form = document.querySelector('.form'); @@ -89,10 +96,12 @@ export default class Show extends ShowApi { if (res === true) { const comments = await this.getComments(e.target.id); commentsEl.innerHTML = this.toComments(comments.data); + this.commentsLength(); e.target.reset(); } }); }); + this.commentsLength(); } html = async ({ hash }) => { @@ -112,7 +121,9 @@ export default class Show extends ShowApi {
@@ -141,7 +152,7 @@ export default class Show extends ShowApi { ${this.toRecommendations(recommendations.results)}
-

Comments(${(comments === false) ? 0 : comments.data.length})

+

Comments()

${(comments === false) ? 'No comments yet' : this.toComments(comments.data)}
From 7628bf50d917ccfad5876d4b0149ddfb84d1bf1c Mon Sep 17 00:00:00 2001 From: Hein Tay Zar Date: Wed, 23 Nov 2022 17:24:33 +0630 Subject: [PATCH 3/4] Add COmments --- src/modules/api/Comment.js | 10 ++++++++ src/modules/api/ShowApi.js | 15 ++++++++++++ src/modules/show.js | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/src/modules/api/Comment.js b/src/modules/api/Comment.js index ac2fc1f..d7dd186 100644 --- a/src/modules/api/Comment.js +++ b/src/modules/api/Comment.js @@ -7,6 +7,11 @@ export default class Comments { this.commentsEndPoint = `/apps/${this.involvementApiId}/comments`; this.commentsAllEndPoint = `/apps/${this.involvementApiId}/comments?item_id=`; } + /** + * call to Involvement APi for getting comments + * @param id + * @returns api data + */ // eslint-disable-next-line consistent-return getComments = async (id) => { @@ -24,6 +29,11 @@ export default class Comments { } } + /** + * call to Involvement APi for adding new + * @param itemId, username, comment + * @returns api data + */ addComment = async (itemId, username, comment) => { try { // eslint-disable-next-line consistent-return diff --git a/src/modules/api/ShowApi.js b/src/modules/api/ShowApi.js index e6ce4a6..4564f69 100644 --- a/src/modules/api/ShowApi.js +++ b/src/modules/api/ShowApi.js @@ -13,6 +13,11 @@ export default class ShowApi extends Comments { this.noMovieMsg = 'Request failed with status code 404'; } + /** + * call to movie db for getting people + * @param {id} id + * @returns api data + */ people = async (id) => { try { return await axios.get(`${this.movieApi}/${id}/credits${this.apiSecretCall}`).then((res) => (res.data)); @@ -26,6 +31,11 @@ export default class ShowApi extends Comments { } } + /** + * call to movie db for getting recommended movie + * @param {id} id + * @returns api data + */ recommendations = async (id) => { try { return await axios.get(`${this.movieApi}/${id}/recommendations${this.apiSecretCall}`).then((res) => (res.data)); @@ -34,6 +44,11 @@ export default class ShowApi extends Comments { } } + /** + * call to movie db for getting the movie by id + * @param {id} id + * @returns api data + */ show = async (id) => { try { // eslint-disable-next-line consistent-return diff --git a/src/modules/show.js b/src/modules/show.js index 0577ab3..0ba2126 100644 --- a/src/modules/show.js +++ b/src/modules/show.js @@ -9,6 +9,11 @@ export default class Show extends ShowApi { this.itemNotFound = "item_id' not found."; } + /** + * change to smaller string for the given length text + * @param num + * @returns string + */ toText = (num) => { let string = num; for (let i = 3; i < num.toString().length; i += 4) { @@ -17,6 +22,11 @@ export default class Show extends ShowApi { return string; } + /** + * get in string format for innerHtml adding: get show more show less button + * @param string + * @returns string + */ showMore = (str) => { let string = str; if (str.length > 100) { @@ -32,6 +42,11 @@ export default class Show extends ShowApi { return string; } + /** + * get in string format for innerHtml adding: adding genre + * @param Array + * @returns string + */ toGenre = (genres) => { if (genres.length > 0) { return Array.from(genres, (e) => `${e.name}`).join(''); @@ -39,6 +54,11 @@ export default class Show extends ShowApi { return 'N/A'; } + /** + * get in string format for innerHtml adding: adding people + * @param Array + * @returns string + */ toPeople = (p) => { let string = ''; for (let i = 0; i < 5 && i < p.length; i += 1) { @@ -47,6 +67,11 @@ export default class Show extends ShowApi { return string; } + /** + * get in string format for innerHtml adding: adding recommendations cards + * @param Array + * @returns string + */ toRecommendations = (data) => { let string = ''; for (let i = 0; i < 5 && i < data.length; i += 1) { @@ -55,6 +80,11 @@ export default class Show extends ShowApi { return string; } + /** + * check null or not if null return 'N/A' otherwise text + * @param (data: noyNullStr, text: Str) + * @returns string + */ checkNull = (data, text) => { if (!data) { return 'N/A'; @@ -62,11 +92,21 @@ export default class Show extends ShowApi { return text; } + /** + * change to the data objects + * @param str + * @returns string + */ toDate = (str) => { const date = new Date(str); return `${date.getDate()}/${date.getMonth()}/${date.getFullYear()}`; } + /** + * get in string format for innerHtml adding: adding comments + * @param (obj: comments) + * @returns string + */ toComments = (data) => { let string = ''; data.forEach((comment) => { @@ -79,12 +119,22 @@ export default class Show extends ShowApi { return string; } + /** + * get the comments length that is in dom + * @param + * @returns comments length + */ commentsLength = () => { const commentsLength = document.querySelector('#comments-length'); const comments = document.querySelectorAll('.comment'); commentsLength.innerHTML = comments.length; return comments.length; } + /** + * to run the javascript code after the + * @param Array + * @returns string + */ js = () => { const form = document.querySelector('.form'); From 1484c4141afbc712a1caeb52db80d9deb0c66ab0 Mon Sep 17 00:00:00 2001 From: Hein Tay Zar Date: Wed, 23 Nov 2022 17:41:46 +0630 Subject: [PATCH 4/4] Add comments --- src/modules/show.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/modules/show.js b/src/modules/show.js index 0ba2126..6604d1d 100644 --- a/src/modules/show.js +++ b/src/modules/show.js @@ -131,9 +131,8 @@ export default class Show extends ShowApi { return comments.length; } /** - * to run the javascript code after the - * @param Array - * @returns string + * to run the javascript code after the html from the class is finished + * @param () */ js = () => { @@ -154,6 +153,11 @@ export default class Show extends ShowApi { this.commentsLength(); } + /** + * for main.innerHtml data + * @param () + * @return (main.innerHtml: string) + */ html = async ({ hash }) => { const res = await this.show(Number(hash)).then((data) => data); const {