Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
main.js 21.7 KiB
Newer Older
peter_rabbit's avatar
peter_rabbit committed
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
const ENV = "dev";
peter_rabbit's avatar
peter_rabbit committed

let server_url;

switch (ENV) {
    case "dev":
peter_rabbit's avatar
peter_rabbit committed
        server_url = "http://localhost";
peter_rabbit's avatar
peter_rabbit committed
        break;
    case "prod":
peter_rabbit's avatar
peter_rabbit committed
        server_url = "http://kuadrado-software.fr";
peter_rabbit's avatar
peter_rabbit committed
}

module.exports = { server_url };

},{}],2:[function(require,module,exports){
const { server_url } = require("./config");

module.exports = {
    images_url: `${server_url}/assets/images`,
peter_rabbit's avatar
peter_rabbit committed
    articles_url: `${server_url}/articles`,
peter_rabbit's avatar
peter_rabbit committed
};

},{"./config":1}],3:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
"use strict";

peter_rabbit's avatar
peter_rabbit committed
const { articles_url } = require("../../constants");
const { fetchjson, fetchtext } = require("../lib/fetch");
const objectHtmlRenderer = require("../lib/object-html-renderer");
const ImageCarousel = require("./image-carousel");

class Articles {
    constructor() {
        this.id = performance.now().toString();
        this.state = {
            loading: true,
            articles: [],
            showArticleIndex: -1,
        };
        this.loadArticles();
    }

    loadArticles() {
        fetchjson(`${articles_url}/index.json`)
            .then(json => {
                Promise.all(
                    json.map(async articlePath => {
                        const art = await fetchjson(`${articles_url}/${articlePath}`);
                        const tmpSplit = articlePath.split("/");
                        tmpSplit.pop();
                        const absArtPath = `${articles_url}/${tmpSplit.join("/")}`;
                        return Object.assign(art, { path: absArtPath });
                    })
                )
                    .then(articles => this.setArticles(articles))
                    .catch(e => console.log(e));
            })
            .catch(e => console.log(e));
    }

    async setArticles(articles) {
        for (const article of articles) {
            if (article.content_text.indexOf("<file>") !== -1) {
                const txtPath = article.content_text.replace("<file>", "");
                const txtValue = await fetchtext(`${article.path}/${txtPath}`);
                article.content_text = txtValue;
            }
            article.date = new Date(article.date);
        }
        this.state.articles = articles.sort((a, b) => a.date - b.date);
        this.state.showArticleIndex = this.state.articles.length - 1;
        this.refresh();
    }

    refresh() {
        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
            mode: "replace",
        });
    }

    getArticleDate(date) {
        return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
    }

    getArticleBody(text) {
        return text
            .split(" ")
            .map(word => {
                if (word.includes("http://") || word.includes("https://")) {
                    const splitword = word.split("||");
                    const href = splitword[0];
                    const text = splitword.length > 1 ? splitword[1] : href;
                    return `<a href=${href} target="_blank">${text}</a>`;
                } else return word;
            })
            .join(" ")
            .replaceAll("\n", "<br/>");
    }

    renderArticle(articleData) {
        return {
            tag: "article",
            contents: [
                {
                    tag: "div",
                    class: "date",
                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
                },
                {
                    tag: "div",
                    class: "title",
                    contents: [
                        {
                            tag: "h3",
                            contents: articleData.title,
                        },
                    ],
                },
                {
                    tag: "div",
                    class: "subtitle",
                    contents: [
                        {
                            tag: "strong",
                            contents: articleData.subtitle,
                        },
                    ],
                },
                {
                    tag: "div",
                    class: "body",
                    contents: [
                        {
                            tag: "p",
                            contents: this.getArticleBody(articleData.content_text),
                        },
                    ],
                },
                new ImageCarousel({
                    images: articleData.images.map(img => `${articleData.path}/images/${img}`),
                }).render(),
            ],
        };
    }

    renderArticlePlaceholder() {
        return {
            tag: "article",
            class: "article-placeholder page-contents-center",
            contents: [
                { tag: "div", class: "date" },
                { tag: "div", class: "title" },
                { tag: "div", class: "subtitle" },
                { tag: "div", class: "body" },
                { tag: "div", class: "image" },
            ],
        };
    }

    handleChangeArticle(dir) {
        let { showArticleIndex, articles } = this.state;
        showArticleIndex =
            dir === "prev"
                ? showArticleIndex - 1 >= 0
                    ? showArticleIndex - 1
                    : 0
                : showArticleIndex + 1 <= articles.length - 1
                ? showArticleIndex + 1
                : articles.length - 1;
        this.state.showArticleIndex = showArticleIndex;
        this.refresh();
    }

    render() {
        const { articles, showArticleIndex } = this.state,
            showNext = showArticleIndex < articles.length - 1,
            showPrev = showArticleIndex > 0;
        return {
            tag: "div",
            id: this.id,
            class: "articles-displayer page-contents-center",
            contents:
                articles.length > 0
                    ? [
                          {
                              tag: "button",
                              class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
                              onclick: this.handleChangeArticle.bind(this, "prev"),
                          },
                          this.renderArticle(articles[showArticleIndex]),
                          {
                              tag: "button",
                              class: `next-btn ${!showNext ? "disabled" : "active"}`,
                              onclick: this.handleChangeArticle.bind(this, "next"),
                          },
                      ]
                    : [this.renderArticlePlaceholder()],
        };
    }
}

module.exports = Articles;

},{"../../constants":2,"../lib/fetch":7,"../lib/object-html-renderer":8,"./image-carousel":4}],4:[function(require,module,exports){
"use strict";

const objectHtmlRenderer = require("../lib/object-html-renderer");

class ImageCarousel {
    constructor(props) {
        this.props = props;
        this.id = performance.now();
        this.state = {
            showImageIndex: 0,
        };
        this.RUN_INTERVAL = 5000;
        this.run();
    }

    run() {
        this.runningInterval = setInterval(() => {
            let { showImageIndex } = this.state;
            const { images } = this.props;
            this.state.showImageIndex = showImageIndex < images.length - 1 ? ++showImageIndex : 0;
            this.refreshImage();
        }, this.RUN_INTERVAL);
    }

    setImageIndex(i) {
        clearInterval(this.runningInterval);
        this.state.showImageIndex = i;
        this.refreshImage();
    }

    refreshImage() {
        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
            mode: "replace",
        });
    }

    render() {
        const { showImageIndex } = this.state;
        const { images } = this.props;
        return {
            tag: "div",
            id: this.id,
            class: "image-carousel",
            contents: [
                { tag: "img", src: images[showImageIndex] },
                {
                    tag: "div",
                    class: "carousel-bullets",
                    contents: images.map((_, i) => {
                        const active = showImageIndex === i;
                        return {
                            tag: "span",
                            class: `bullet ${active ? "active" : ""}`,
                            onclick: this.setImageIndex.bind(this, i),
                        };
                    }),
                },
            ],
        };
    }
}

module.exports = ImageCarousel;

},{"../lib/object-html-renderer":8}],5:[function(require,module,exports){
"use strict";

const { images_url } = require("../../constants");

class ThemeCard {
    constructor(props) {
        this.props = props;
    }

    render() {
        return {
            tag: "a",
            class: "theme-card",
            href: this.props.href,
            contents: [
                {
                    tag: "div",
                    class: "card-img",
                    contents: [{ tag: "img", src: `${images_url}/${this.props.img}` }],
                },
                {
                    tag: "div",
                    class: "card-title",
                    contents: [{ tag: "h2", class: "section-title", contents: this.props.title }],
                },
                {
                    tag: "div",
                    class: "card-description",
                    contents: [{ tag: "p", contents: this.props.description }],
                },
            ],
        };
    }
}

module.exports = ThemeCard;

},{"../../constants":2}],6:[function(require,module,exports){
"use strict";

const Articles = require("./home-page-components/articles");
const ThemeCard = require("./home-page-components/theme-card");

peter_rabbit's avatar
peter_rabbit committed
class HomePage {
    constructor(args) {
        Object.assign(this, args);
    }

    render() {
        return {
peter_rabbit's avatar
peter_rabbit committed
            tag: "div",
peter_rabbit's avatar
peter_rabbit committed
            id: "home-page",
peter_rabbit's avatar
peter_rabbit committed
            contents: [
                {
peter_rabbit's avatar
peter_rabbit committed
                    tag: "div",
                    class: "page-header",
                    contents: [
                        { tag: "h1", contents: "Kuadrado Software", class: "page-contents-center" },
                        {
                            tag: "p",
                            class: "page-contents-center",
                            contents: `<b>Kvadrata rado</b> veut dire "roue carrée" en Esperanto, c'est le symbole que nous avons choisi pour Kuadrado 
                            pour dire qu'on aime bien fabriquer les trucs nous même, avec des briques aussi élémentaires que possible, 
                            pour le plaisir de les maîtriser et de les comprendre. Quitte parfois à réinventer un peu la roue.
                            `,
                        },
                    ],
                },
                {
                    tag: "section",
                    class: "page-contents-center",
                    contents: [
                        { tag: "h2", contents: "Actu", class: "section-title bg-blue" },
                        new Articles().render(),
                    ],
                },
                {
                    tag: "section",
                    class: "page-contents-center grid-3",
                    contents: [
                        {
                            title: "Jeux",
                            img: "screen_fantom_quest.jpg",
                            href: "/games/",
                            description:
                                "Toutes nos créations vidéoludiques, jeux web et jeux PC, projets en cours, c'est par ici que ça se passe.",
                        },
                        {
                            title: "Software",
                            img: "learning_theme_coding.png",
                            href: "/software-development/",
                            description:
                                "Des fois quand on a besoin d'un outil, on le fabrique nous même (si ça nous amuse) ! Retrouvez les projets en détail.",
                        },
                        {
                            title: "Pédagogie",
                            img: "popularization_banner.png",
                            href: "/education/",
                            description:
                                "La pédagogie est une arme puissante pour faire tomber les barrières entre les gens et la technologie, et nous sommes bien décidés à en faire usage !",
                        },
                    ].map(cardProps => new ThemeCard(cardProps).render()),
peter_rabbit's avatar
peter_rabbit committed
                },
            ],
        };
    }
}

module.exports = HomePage;

peter_rabbit's avatar
peter_rabbit committed
},{"./home-page-components/articles":3,"./home-page-components/theme-card":5}],7:[function(require,module,exports){
"use strict";

function fetchjson(url) {
    return new Promise((resolve, reject) => {
        fetch(url)
            .then(r => r.json())
            .then(r => resolve(r))
            .catch(e => reject(e));
    });
};

function fetchtext(url) {
    return new Promise((resolve, reject) => {
        fetch(url)
            .then(r => r.text())
            .then(r => resolve(r))
            .catch(e => reject(e));
    });
};

module.exports = {
    fetchjson, fetchtext
}

},{}],8:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
"use strict";

module.exports = {
    setRenderCycleRoot(renderCycleRoot) {
        this.renderCycleRoot = renderCycleRoot;
    },
    objectToHtml: function objectToHtml(obj) {
        const { tag } = obj;

        const node = document.createElement(tag);
        const excludeKeys = ["tag", "contents", "style_rules", "state"];

        Object.keys(obj)
            .filter(attr => !excludeKeys.includes(attr))
            .forEach(attr => {
                if (attr === "class") {
                    node.classList.add(...obj[attr].split(" ").filter(s => s !== ""));
                } else {
                    node[attr] = obj[attr];
                }
            });
        if (obj.contents && typeof obj.contents === "string") {
            node.innerHTML = obj.contents;
        } else {
            obj.contents &&
                obj.contents.length > 0 &&
                obj.contents.forEach(el => {
                    switch (typeof el) {
                        case "string":
                            node.innerHTML = el;
                            break;
                        case "object":
                            node.appendChild(objectToHtml(el));
                            break;
                    }
                });
        }

        if (obj.style_rules) {
            Object.keys(obj.style_rules).forEach(rule => {
                node.style[rule] = obj.style_rules[rule];
            });
        }

        return node;
    },
    renderCycle: function () {
        this.subRender(this.renderCycleRoot.render(), document.getElementsByTagName("main")[0], {
            mode: "replace",
        });
    },
    subRender(object, htmlNode, options = { mode: "append" }) {
        const insert = this.objectToHtml(object);
        switch (options.mode) {
            case "append":
                htmlNode.appendChild(insert);
                break;
            case "override":
                htmlNode.innerHTML = "";
                htmlNode.appendChild(insert);
                break;
            case "insert-before":
                htmlNode.insertBefore(insert, htmlNode.childNodes[options.insertIndex]);
                break;
            case "adjacent":
                /**
                 * options.insertLocation must be one of:
                 *
                 * afterbegin
                 * afterend
                 * beforebegin
                 * beforeend
                 */
                htmlNode.insertAdjacentHTML(options.insertLocation, insert);
                break;
            case "replace":
                htmlNode.parentNode.replaceChild(insert, htmlNode);
                break;
            case "remove":
                htmlNode.remove();
                break;
        }
    },
};

peter_rabbit's avatar
peter_rabbit committed
},{}],9:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
"use strict";

const HomePage = require("./homepage");
const runPage = require("./run-page");

runPage(HomePage);

peter_rabbit's avatar
peter_rabbit committed
},{"./homepage":6,"./run-page":10}],10:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
"use strict";

const objectHtmlRenderer = require("./lib/object-html-renderer");
peter_rabbit's avatar
peter_rabbit committed
const Template = require("./template/template");
peter_rabbit's avatar
peter_rabbit committed

module.exports = function runPage(PageComponent) {
peter_rabbit's avatar
peter_rabbit committed
    const template = new Template({ page: new PageComponent() });
    objectHtmlRenderer.setRenderCycleRoot(template);
peter_rabbit's avatar
peter_rabbit committed
    objectHtmlRenderer.renderCycle();
};

peter_rabbit's avatar
peter_rabbit committed
},{"./lib/object-html-renderer":8,"./template/template":12}],11:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
"use strict";

const { images_url } = require("../../../constants");
peter_rabbit's avatar
peter_rabbit committed

peter_rabbit's avatar
peter_rabbit committed
const NAV_MENU_ITEMS = [
    ["/games/", "Jeux"],
    ["/software-development/", "Software"],
peter_rabbit's avatar
peter_rabbit committed
    [
        "/education/",
peter_rabbit's avatar
peter_rabbit committed
        "Pédagogie",
        [
            // submenu
            ["/education/#game-studio-club", "Game Studio Club"],
            ["/education/#popularization", "Vulgarisation numérique"],
peter_rabbit's avatar
peter_rabbit committed
        ],
    ],
];

class NavBar {
    constructor() {
        this.initEventHandlers();
    }

    handleBurgerClick() {
        document.getElementById("nav-menu-list").classList.toggle("responsive-show");
    }

    initEventHandlers() {
        window.addEventListener("click", event => {
            if (
                event.target.id !== "nav-menu-list" &&
                !event.target.classList.contains("burger") &&
                !event.target.parentNode.classList.contains("burger")
            ) {
                document.getElementById("nav-menu-list").classList.remove("responsive-show");
            }
        });
    }

    renderHome() {
        return {
            tag: "div",
            class: "home",
            contents: [
                {
                    tag: "a",
peter_rabbit's avatar
peter_rabbit committed
                        { tag: "img", src: `${images_url}/logo_kuadrado.svg` },
                        {
                            tag: "img",
                            class: "logo-text",
                            src: `${images_url}/logo_kuadrado_txt.svg`,
                        },
peter_rabbit's avatar
peter_rabbit committed
    renderMenu(menuItemsArray, isSubmenu = false) {
peter_rabbit's avatar
peter_rabbit committed
            tag: "ul",
            id: "nav-menu-list",
peter_rabbit's avatar
peter_rabbit committed
            class: isSubmenu ? "submenu" : "",
            contents: menuItemsArray.map(link => {
                const [href, text, submenu] = link;
peter_rabbit's avatar
peter_rabbit committed
                return {
                    tag: "li",
                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
peter_rabbit's avatar
peter_rabbit committed
                    contents: [
                        {
                            tag: "a",
                            href,
peter_rabbit's avatar
peter_rabbit committed
                        },
                    ].concat(submenu ? [this.renderMenu(submenu, true)] : []),
peter_rabbit's avatar
peter_rabbit committed
                };
            }),
        };
    }

    renderResponsiveBurger() {
        return {
            tag: "div",
            class: "burger",
            onclick: this.handleBurgerClick.bind(this),
            contents: [{ tag: "span", contents: "···" }],
        };
peter_rabbit's avatar
peter_rabbit committed
    }

    render() {
        return {
            tag: "nav",
            contents: [
                this.renderHome(),
                this.renderResponsiveBurger(),
                this.renderMenu(NAV_MENU_ITEMS),
            ],
        };
    }
}

module.exports = NavBar;

peter_rabbit's avatar
peter_rabbit committed
},{"../../../constants":2}],12:[function(require,module,exports){
peter_rabbit's avatar
peter_rabbit committed
const { images_url } = require("../../constants");
const NavBar = require("./components/navbar");

class Template {
    constructor(props) {
        this.props = props;
    }
peter_rabbit's avatar
peter_rabbit committed
    render() {
        return {
            tag: "main",
            contents: [
                {
                    tag: "header",
                    contents: [new NavBar().render()],
peter_rabbit's avatar
peter_rabbit committed
                },
                {
                    tag: "div",
                    id: "page-container",
                    contents: [this.props.page.render()],
                },
                {
                    tag: "footer",
                    contents: [
peter_rabbit's avatar
peter_rabbit committed
                        {
                            tag: "div",
                            class: "logo",
                            contents: [
                                {
                                    tag: "img",
                                    src: `${images_url}/logo_kuadrado.svg`,
                                },
                                {
                                    tag: "img",
                                    class:"text-logo",
                                    src: `${images_url}/logo_kuadrado_txt.svg`,
                                },
                            ],
                        },
                        {
                            tag:"span",
                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
                        },
peter_rabbit's avatar
peter_rabbit committed
                        {
                            tag: "a",
peter_rabbit's avatar
peter_rabbit committed
                            href: "mailto:contact@kuadrado-software.fr",
                            contents: "contact@kuadrado-software.fr",
peter_rabbit's avatar
peter_rabbit committed
                        },
                    ],
                },
            ],
        };
    }
}

module.exports = Template;

peter_rabbit's avatar
peter_rabbit committed
},{"../../constants":2,"./components/navbar":11}]},{},[9]);