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
  • Learn to ignore specific revisions
  • 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]);