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
amityusa0106 avatar amityusa0106 0 Точки

Thank you for your guidance. I have been able to improve my writing skills and learn new things. drift boss

-1
mira23a avatar mira23a 2 Точки

There have been some very good and lego 2k drive useful tutorials given, you can refer to it

-1
karausa avatar karausa 3 Точки

Решенията, които сте дали, са доста ефективни и помагат на мен и на други, retro bowl които се борят да разрешат проблемите, които срещат в тази област. 

0
stipulaterooster avatar stipulaterooster 3 Точки

Pseudonymisation is the processing the backrooms of personal data in such a way that, without the use of additional information, the personal data can no longer be attributed to a specific data subject. Provided such additional information is kept separately and is subject to technical and organisational measures designed to ensure that the personal data are not attributed to an identified or identifiable natural person.

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