"use strict"; const Article = require("../article"); const { images_url } = require("../constants"); const { fetch_post_article, fetch_article, fetch_update_article } = require("../xhr"); class CreateArticleForm { constructor(params) { this.params = params || {}; this.state = { output: new Article(this.params.data), article_sent: {}, } } reset() { this.state.output = new Article(); this.state.article_sent = {}; this.refresh(); } handle_text_input(field, e) { this.state.output[field] = e.target.value; } handle_del_detail(index) { this.state.output.details.splice(index, 1); this.refresh_details(); } handle_add_detail() { this.state.output.details.push({ label: "", value: "" }); this.refresh_details(); } handle_del_image(index) { this.state.output.images.splice(index, 1); this.refresh_images(); } handle_add_image() { this.state.output.images.push("") this.refresh_images(); } refresh_details() { obj2htm.subRender( this.render_details_inputs(), document.getElementById("create-article-form-details"), { mode: "replace" } ); } render_details_inputs() { return { tag: "ul", style_rules: { gridColumn: "1 / span 2", display: "flex", flexDirection: "column", gap: "10px", listStyleType: "none", padding: 0, }, id: "create-article-form-details", contents: this.state.output.details.map((detail, i) => { return { tag: "li", style_rules: { display: "grid", gridTemplateColumns: "200px auto 60px", gap: "10px", }, contents: [ { tag: "input", type: "text", placeholder: "Label", value: detail.label, oninput: e => { this.state.output.details[i].label = e.target.value; } }, { tag: "input", type: "text", placeholder: "Value", value: detail.value, oninput: e => { this.state.output.details[i].value = e.target.value; } }, { tag: "button", contents: "DEL", onclick: this.handle_del_detail.bind(this, i) } ] } }).concat([ { tag: "li", contents: [{ tag: "button", contents: "ADD DETAIL", onclick: this.handle_add_detail.bind(this) }] } ]) } } refresh_images() { obj2htm.subRender( this.render_images_inputs(), document.getElementById("create-article-form-images"), { mode: "replace" } ); } render_images_inputs() { return { tag: "ul", style_rules: { gridColumn: "1 / span 2", display: "flex", flexDirection: "column", gap: "10px", listStyleType: "none", padding: 0, }, id: "create-article-form-images", contents: this.state.output.images.map((img, i) => { return { tag: "li", style_rules: { display: "flex", alignItems: "center", gap: "10px", }, contents: [ { tag: "div", style_rules: { display: "flex", flexDirection: "center", alignItems: "center", justifyContent: "center", width: "150px", height: "150px", overflow: "hidden", }, contents: [ { tag: "img", style_rules: { minWidth: "100%", minHeight: "100%" }, src: img ? `${images_url}/${img}` : "", } ], }, { tag: "input", type: "text", placeholder: "image file name", value: img, oninput: e => { this.state.output.images[i] = e.target.value; } }, { tag: "button", contents: "OK", onclick: this.refresh_images.bind(this) }, { tag: "button", contents: "DEL", onclick: this.handle_del_image.bind(this, i) } ] } }).concat([ { tag: "li", contents: [{ tag: "button", contents: "ADD IMAGE", onclick: this.handle_add_image.bind(this) }] } ]) } } render_article_sent() { const article = this.state.article_sent; return { tag: "div", style_rules: { maxWidth: "800px", }, contents: [ { tag: "button", contents: "RESET", onclick: this.reset.bind(this) }, { tag: "h2", contents: article.title }, { tag: "h4", contents: article.subtitle }, { tag: "p", contents: article.body.replace(/\n/g, "<br>") }, { tag: "ul", contents: article.details.map(det => { return { tag: "li", style_rules: { display: "flex", gap: "20px", justifyContent: "space-between", }, contents: [ { tag: "span", contents: det.label }, { tag: "span", contents: det.value } ] }; }) }, { tag: "div", style_rules: { display: "flex", gap: "10px" }, contents: article.images.map(img => { return { tag: "img", style_rules: { height: "100px", width: "auto" }, src: `${images_url}/${img}` } }) } ] } } refresh() { obj2htm.subRender( this.render(), document.getElementById("create-article-form"), { mode: "replace" } ); } render() { return { tag: "form", id: "create-article-form", style_rules: { display: "grid", maxWidth: "800px", gridTemplateColumns: "1fr 1fr", gap: "20px", }, onsubmit: e => { e.preventDefault(); const __fetch = this.params.data ? fetch_update_article : fetch_post_article; __fetch(this.state.output) .then(res => { const id = res.insertedId ? res.insertedId.$oid : res._id ? res._id.$oid : undefined; if (!id) { alert("error") } else { fetch_article(id) .then(article => { this.state.article_sent = article; this.params.on_article_sent && this.params.on_article_sent(); this.refresh(); }) .catch(er => console.log(er)); } }) .catch(err => console.log(err)) }, contents: this.state.article_sent._id ? [this.render_article_sent()] : [ { tag: "input", type: "text", placeholder: "category", value: this.state.output.category, oninput: this.handle_text_input.bind(this, "category") }, { tag: "select", value: this.state.output.locale, onchange: e => this.state.output.locale = e.target.value, contents: [{ tag: "option", value: "", contents: "-- LOCALE --" }].concat(["fr", "en", "es"].map(loc => { return { tag: "option", value: loc, contents: loc, selected: this.state.output.locale === loc } })) }, { tag: "input", type: "text", placeholder: "Article title", value: this.state.output.title, oninput: this.handle_text_input.bind(this, "title") }, { tag: "input", type: "text", style_rules: { gridColumn: "1 / span 2" }, placeholder: "Article subtitle", value: this.state.output.subtitle, oninput: this.handle_text_input.bind(this, "subtitle") }, { tag: "textarea", style_rules: { gridColumn: "1 / span 2", height: "300px", }, value: this.state.output.body, placeholder: "Article body", oninput: this.handle_text_input.bind(this, "body") }, this.render_details_inputs(), this.render_images_inputs(), { tag: "input", type: "submit" } ] } } } module.exports = CreateArticleForm;