Загрузка данных


/**
 * Получить карточку персонажа
 *
 * @param character
 * @returns {string}
 */
function getCharacterCard(character) {
    return `
        <div class="card mb-3 col-sm-12 col-md-6 col-lg-4">
            <div class="row g-0">
                <div class="col-4">
                    <img src="${character.thumbnail}"
                         style="max-width: 100%;"
                         alt="${character.name}"
                    >
                </div>
                <div class="col-8">
                    <div class="card-body">
                        <h5 class="card-title">${character.name}</h5>
                        <button type="button"
                                data-bs-toggle="modal"
                                data-bs-target="#exampleModal-${character.id}"
                                class="btn btn-secondary btn-sm"
                        >Подробнее</button>
                    </div>
                </div>
            </div>
        </div>
        `;
}

/**
 * Получить модальное окно персонажа
 *
 * @param character
 * @returns {string}
 */
function getCharacterModal(character) {
    return `
        <div id="exampleModal-${character.id}"
             tabindex="-1"
             aria-labelledby="exampleModalLabel-${character.id}"
             class="modal fade"
             style="display: none;" 
             aria-hidden="true"
        >
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">${character.name}</h5>
                        <button type="button"
                                data-bs-dismiss="modal"
                                aria-label="Close"
                                class="btn-close"
                        ></button>
                    </div>
                    <div class="modal-body">
                        <img src="${character.thumbnail}"
                             style="max-width: 100%;"
                             alt="${character.name}"
                        >
                        <div>
                            <p class="text-muted">${character.modified}</p>
                            <h5>Описание:</h5>
                            <p>${character.description || 'Описание отсутствует'}</p>
                        </div>

                        <div class="modal-footer">
                            <button type="button"
                                    data-bs-dismiss="modal"
                                    class="btn btn-secondary btn-sm"
                            >Закрыть</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        `;
}

/**
 * получим информацию о персонажах с API
 */
function fetchCharacters() {

    return fetch('https://cdn.jsdelivr.net/gh/akabab/superhero-api@0.3.0/api/all.json')
        .then(response => {
            if (!response.ok) {
                throw new Error('Ошибка загрузки данных');
            }
            return response.json();
        })
        .then(data => {
            const characters = data.map((hero, index) => ({
                id: index,
                name: hero.name,
                thumbnail: hero.images.xs,
                description: hero.biography.fullName || 'Нет описания',
                modified: hero.appearance.race || 'Неизвестно'
            }));
            return characters;
        })
        .catch(error => {
            console.error('Ошибка при загрузке персонажей:', error);
            return [];
        });
}

/**
 * Получить массив карточек персонажей
 *
 * @param characters
 * @returns {Array}
 */
function getCharacterCards(characters) {
    const cards = [];

    if (!characters || !Array.isArray(characters)) {
        return cards;
    }

    for (let i = 0; i < characters.length; i++) {
        const cardHtml = getCharacterCard(characters[i]);
        cards.push(cardHtml);
    }

    return cards;
}

/**
 * Получить массив модальных окон персонажей
 *
 * @param characters
 * @returns {Array}
 */
function getCharacterModals(characters) {
    const modals = [];

    if (!characters || !Array.isArray(characters)) {
        return modals;
    }

    for (let i = 0; i < characters.length; i++) {
        const modalHtml = getCharacterModal(characters[i]);
        modals.push(modalHtml);
    }

    return modals;
}

async function displayCharacters() {
    const container = document.getElementById('characters-container');
    if (container) {
        container.innerHTML = '<div class="text-center"><div class="spinner-border" role="status"><span class="visually-hidden">Загрузка...</span></div></div>';
    }

    const characters = await fetchCharacters();

    const cards = getCharacterCards(characters);
    const modals = getCharacterModals(characters);

    if (container) {
        container.innerHTML = cards.join('');
    }

    const modalsContainer = document.getElementById('modals-container');
    if (modalsContainer) {
        modalsContainer.innerHTML = modals.join('');
    } else {
        const modalWrapper = document.createElement('div');
        modalWrapper.id = 'modals-container';
        modalWrapper.innerHTML = modals.join('');
        document.body.appendChild(modalWrapper);
    }
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', displayCharacters);
} else {
    displayCharacters();
}