Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

LyuboslavL avatar LyuboslavL 3 Точки

Задача 01. Forum от SPA упражненията

Здравейте, колеги,

Бих се радвал на малко насоки, защото определено не намирам как да започна въпросната задача. Цялостно решение също би ми било полезно, за да видя подхода, понеже си признавам, че съм зациклил и не се сещам откъде да го подхвана дори.

Ето и условието:

https://www.photobox.co.uk/my/photo/full?photo_id=504743566071

https://www.photobox.co.uk/my/photo/full?photo_id=504743565950

Благодаря предварително!

0
JavaScript Applications
Axiomatik avatar Axiomatik 2422 Точки

app.js =>

import { showComments, getDate } from './appFunctions.js';

const mainSection = document.getElementById('main-section');
const commentSection = document.getElementById('comment-section');
const topicContainer = document.querySelector('div[class="main-topic-container"]');
const topicFormSection = document.getElementById('topic-form');
const homeBtn = document.querySelector('header nav a');
const postBtn = document.querySelector('button[class="public"]');
const cancelBtn = document.querySelector('button[class="cancel"]');
const url = `http://localhost:3030/jsonstore/collections/myboard/posts`;

commentSection.style.display = 'none';

addEvents();

fetchAllTopics();

function addEvents() {
    homeBtn.addEventListener('click', () => {
        mainSection.style.display = '';
        commentSection.style.display = 'none';
        fetchAllTopics();
    });

    topicContainer.addEventListener('click', (ev) => {
        ev.preventDefault();

        if (ev.target.tagName == 'H2') {
            const id = ev.target.dataset.id;
            showComments(id);
        }
    });

    topicFormSection.addEventListener('submit', (ev) => {
        ev.preventDefault();
    });

    cancelBtn.addEventListener('click', ev => {
        const form = ev.target.parentElement.parentElement;
        form.reset();
    });

    postBtn.addEventListener('click', async (ev) => {
        const form = ev.target.parentElement.parentElement;
        const topic = formTopicData(form);

        if (topic === undefined) {
            alert('All fields must be completed!');
            form.reset();
            return;
        }

        const result = postNewTopic(topic);
        fetchAllTopics();
        form.reset();
    });
}

async function fetchAllTopics() {
    const data = await fetch(url);

    if (data.ok === false) {
        const error = await data.json();
        throw new Error(error.message);
    }

    const topics = Object.values(await data.json());

    if (topics.length !== 0) {
        topicContainer.innerHTML = '';
        topics.forEach(m => topicContainer.appendChild(topicCard(m)));
    }

    topicContainer.style.display = '';
}

function formTopicData(ev) {
    const form = new FormData(ev);
    const title = form.get('topicName');
    const creator = form.get('username');
    const commentContent = form.get('postText');
    const date = getDate();

    // console.log(title, creator, commentContent, date);
    if (title === '' || creator === '' || commentContent === '') {
        return undefined;
    }

    return { title, creator, commentContent, date };
}

async function postNewTopic(topic) {
    const response = await fetch(url, {
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(topic)
    });

    if (response.ok !== true) {
        const error = await error.json();
        throw new Error(error.message);
    }

    return await response.json();
}

function topicCard(topic) {
    const element = document.createElement('div');
    element.classList.add('topic-container');
    element.innerHTML = `
    <div class="topic-name-wrapper"">
        <div class="topic-name">
            <a href="#" class="normal">
                <h2  data-id="${topic._id}">${topic.title}</h2>
            </a>
            <div class="columns">
                <div>
                    <p>Date: <time>${topic.date}</time></p>
                    <div class="nick-name">
                        <p>Username: <span>${topic.creator}</span></p>
                    </div>
                </div>
            </div>
        </div>
    </div>
    `;

    return element;
}


appFunctions.js =>

const mainSection = document.getElementById('main-section');
const commentSection = document.getElementById('comment-section');
const topicContainer = document.querySelector('div[class="main-topic-container"]');
const topicDetailSection = commentSection.querySelector('.theme-content')
const url = `http://localhost:3030/jsonstore/collections/myboard/posts`;
const commentsUrl = `http://localhost:3030/jsonstore/collections/myboard/comments`;

export async function showComments(topicId) {
    mainSection.style.display = 'none';
    topicContainer.style.display = 'none';
    commentSection.style.display = '';

    const topic = await getTopicById(topicId);
    const div = document.createElement('div');
    div.classList.add('comment');
    div.innerHTML = `
  <div class="header">
      <img src="./static/profile.png" alt="avatar">
      <p><span>${topic.creator}</span> posted on <time>${topic.date}</time></p>
      <p class="post-content">${topic.commentContent}</p>
  </div>
`;
    topicDetailSection.replaceChildren(div);

    commentSection.querySelector('form').addEventListener('submit', (ev) => {
        const comment = getCommentData(ev);
        comment.topicId = topicId;
        const newComment = postNewComment(comment);
        loadComments(topicId);
    });

    loadComments(topicId);
}

async function postNewComment(comment) {
    const response = await fetch(commentsUrl, {
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(comment)
    });

    if (response.ok !== true) {
        const error = await response.json();
        throw new Error(error.message);
    }

    return await response.json();
}

async function getComments() {
    const response = await fetch(commentsUrl);

    if (response.ok != true) {
        const error = await response.json();
        throw new Error(error.message);
    }

    return await response.json();
}

function getCommentData(ev) {
    ev.preventDefault();
    const form = document.getElementById('comment-form');
    const data = new FormData(form);
    const text = data.get('postText');
    const username = data.get('username');
    const date = getDate();

    if (text == '' || username == '') {
        alert('All fields must be completed!');
        form.reset();
        return;
    }

    form.reset();

    return { text, username, date };
}

async function loadComments(topicId) {
    const allComments = await getComments();
    const filteredComments = Object.values(allComments).filter(c => c.topicId === topicId);
    const commentSections = document.getElementById('all-comments');
    commentSections.innerHTML = '';

    filteredComments.forEach(e => {
        const div = document.createElement('div');
        div.classList.add('user-comment');
        div.innerHTML = `
    <div class="topic-name-wrapper">
        <div class="topic-name">
            <p><strong>${e.username}</strong> commented on <time>${e.date}</time></p>
            <div class="post-content">
                 <p>${e.text}</p>
            </div>
        </div>
    </div>
`;
        // div.dataset.id = topicId;
        commentSections.appendChild(div);
    });
}

export async function getTopicById(id) {
    const response = await fetch(`${url}/${id}`);

    if (response.ok != true) {
        const error = await response.json();
        throw new Error(error.message);
    }

    const topic = await response.json();
    return topic;
}

export function getDate() {
    const currentDate = new Date();
    const date = currentDate.getDate();
    const month = currentDate.getMonth();
    const year = currentDate.getFullYear();
    const hour = currentDate.getHours();
    const minutes = currentDate.getMinutes();
    const seconds = currentDate.getSeconds();
    const milliSeconds = currentDate.getMilliseconds();

    const fullDate = `${year}-${checkDate(month)}-${checkDate(date)}T${checkDate(hour)}:${checkDate(minutes)}:${checkDate(seconds)}.${checkMilliSeconds(milliSeconds)}Z`;

    return fullDate;

    function checkDate(date) {
        return date < 10 ? `0${date}` : date;
    }

    function checkMilliSeconds(date) {
        return date.toString().padStart(3, 0);
    }
}

;-)

1
LyuboslavL avatar LyuboslavL 3 Точки

Много благодаря! 

2
thomasfrank avatar thomasfrank 3 Точки

I highly appreciate the comprehensive guidance and detailed solution provided, which not only helped me understand the fnf task better but also enabled me to successfully complete it.

-1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.