From 9564c37899a335dd8a51d6d933037cb40ea50974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Wo=C5=BAniak?= Date: Wed, 13 Jul 2022 17:25:51 +0200 Subject: [PATCH] Display news, improve news form --- assets/templates/admin_panel.html | 3 +- assets/templates/news.html | 16 +++++ client/src/admin.js | 4 +- client/src/admin/article-form.js | 1 - client/src/admin/ow-admin.js | 1 - client/src/app.js | 3 + client/src/{admin => news}/news-article.js | 24 +++++-- client/src/{admin => news}/ow-articles.js | 1 - client/src/ow-news.js | 16 ----- client/src/ow-news/news-article.js | 37 ----------- client/src/shared/date-time.js | 76 ++++++++++++++++++++++ client/src/shared/rich-text-editor.js | 1 + src/routes/unrestricted.rs | 38 ++++++++++- 13 files changed, 153 insertions(+), 68 deletions(-) create mode 100644 assets/templates/news.html rename client/src/{admin => news}/news-article.js (75%) rename client/src/{admin => news}/ow-articles.js (91%) delete mode 100644 client/src/ow-news.js delete mode 100644 client/src/ow-news/news-article.js create mode 100644 client/src/shared/date-time.js diff --git a/assets/templates/admin_panel.html b/assets/templates/admin_panel.html index 0660df6..f1b47e3 100644 --- a/assets/templates/admin_panel.html +++ b/assets/templates/admin_panel.html @@ -4,12 +4,13 @@ {% for article in news %} - {{article.body}} + {{article.body|safe}} {% endfor %} diff --git a/assets/templates/news.html b/assets/templates/news.html new file mode 100644 index 0000000..b2c7ffc --- /dev/null +++ b/assets/templates/news.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} +{% block content %} + + {% for article in news %} + + {{article.body|safe}} + + {% endfor %} + +{% endblock %} diff --git a/client/src/admin.js b/client/src/admin.js index 58ca0af..1978f6e 100644 --- a/client/src/admin.js +++ b/client/src/admin.js @@ -1,3 +1,3 @@ import "./admin/ow-admin"; -import "./admin/ow-articles"; -import "./admin/news-article"; + +import "./admin/article-form"; diff --git a/client/src/admin/article-form.js b/client/src/admin/article-form.js index 012818a..f28186d 100644 --- a/client/src/admin/article-form.js +++ b/client/src/admin/article-form.js @@ -1,5 +1,4 @@ import { Component, FORM_STYLE } from "../shared"; -import "../shared/rich-text-editor"; customElements.define('article-form', class extends Component { constructor() { diff --git a/client/src/admin/ow-admin.js b/client/src/admin/ow-admin.js index 446c9ff..00eff2f 100644 --- a/client/src/admin/ow-admin.js +++ b/client/src/admin/ow-admin.js @@ -1,5 +1,4 @@ import { Component } from "../shared"; -import "./ow-articles"; customElements.define('ow-admin', class extends Component { constructor() { diff --git a/client/src/app.js b/client/src/app.js index 5e792cc..7198c96 100644 --- a/client/src/app.js +++ b/client/src/app.js @@ -8,6 +8,9 @@ import "./price/price-view"; import "./price/price-input"; import "./register-form.js"; import "./business-items"; +import "./news/ow-articles"; +import "./news/news-article"; +import "./shared/rich-text-editor"; import { fireFbReady } from "./shared.js"; diff --git a/client/src/admin/news-article.js b/client/src/news/news-article.js similarity index 75% rename from client/src/admin/news-article.js rename to client/src/news/news-article.js index 4828476..b6ca343 100644 --- a/client/src/admin/news-article.js +++ b/client/src/news/news-article.js @@ -1,8 +1,9 @@ import { Component } from "../shared"; +import "../shared/date-time"; customElements.define('news-article', class extends Component { static get observedAttributes() { - return ["article-title", "status", "body", "created-at", "published-at"] + return ["article-id", "article-title", "status", "body", "created-at", "published-at"] } constructor() { @@ -42,11 +43,13 @@ customElements.define('news-article', class extends Component {
Created at: - + +
Published at: - + +
@@ -56,6 +59,15 @@ customElements.define('news-article', class extends Component { `); } + get article_id() { + const id = parseInt(this.getAttribute('article-id')); + return isNaN(id) ? null : id; + } + + set article_id(v) { + this.setAttribute('article-id', v); + } + get article_title() { return this.getAttribute('article-title'); } @@ -79,8 +91,7 @@ customElements.define('news-article', class extends Component { } set created_at(v) { - this.setAttribute('created-at', v); - this.shadowRoot.querySelector('#created_at').textContent = v; + this.shadowRoot.querySelector('#created_at').datetime = v; } get published_at() { @@ -88,7 +99,6 @@ customElements.define('news-article', class extends Component { } set published_at(v) { - this.setAttribute('published-at', v); - this.shadowRoot.querySelector('#published_at').textContent = v; + this.shadowRoot.querySelector('#published_at').datetime = v; } }); diff --git a/client/src/admin/ow-articles.js b/client/src/news/ow-articles.js similarity index 91% rename from client/src/admin/ow-articles.js rename to client/src/news/ow-articles.js index 56ca84e..80ecd37 100644 --- a/client/src/admin/ow-articles.js +++ b/client/src/news/ow-articles.js @@ -1,5 +1,4 @@ import { Component } from "../shared" -import "./article-form"; customElements.define('ow-articles', class extends Component { constructor() { diff --git a/client/src/ow-news.js b/client/src/ow-news.js deleted file mode 100644 index 70a68e0..0000000 --- a/client/src/ow-news.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from "./shared"; - -import "./ow-news/news-article"; - -customElements.define("ow-news", class extends Component { - constructor() { - super(` - -
- -
- `); - } -}); diff --git a/client/src/ow-news/news-article.js b/client/src/ow-news/news-article.js deleted file mode 100644 index 97cb04a..0000000 --- a/client/src/ow-news/news-article.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Component } from "../shared"; - -customElements.define('news-article', class extends Component { - static get observedAttributes() { - return ["title", "body", "published-at"] - } - - constructor() { - super(` - -
-

-
-
- `); - } - - get title() { - return this.getAttribute('title'); - } - - set title(v) { - this.setAttribute('title', v); - this.shadowRoot.querySelector('#title').textContent = v; - } - - get body() { - return this.getAttribute('body'); - } - - set body(v) { - this.setAttribute('body', v); - this.shadowRoot.querySelector('#body').textContent = v; - } -}); diff --git a/client/src/shared/date-time.js b/client/src/shared/date-time.js new file mode 100644 index 0000000..36662e2 --- /dev/null +++ b/client/src/shared/date-time.js @@ -0,0 +1,76 @@ +import { Component } from "../shared"; + +customElements.define('date-time', class extends Component { + static get observedAttributes() { + return ['datetime', "hide-date", "hide-time"] + } + + constructor() { + super(` + +
+
+
+
+ `); + } + + get datetime() { + return Date.parse(this.getAttribute('datetime')); + } + + set datetime(v) { + this.setAttribute('datetime', v); + this.#format(); + } + + get hide_date() { + return this.getAttribute('hide-date') === 'true'; + } + + set hide_date(v) { + this.setAttribute('hide-date', v === true || v === 'true' ? 'true' : 'false'); + this.#format(); + } + + get hide_time() { + return this.getAttribute('hide-time') === 'true'; + } + + set hide_time(v) { + this.setAttribute('hide-time', v === true || v === 'true' ? 'true' : 'false'); + this.#format(); + } + + #format() { + { + const el = this.shadowRoot.querySelector('#date'); + if (!this.hide_date) + el.textContent = new Date().toLocaleDateString(navigator.language || navigator.userLanguage, { + weekday: "long", + year: "numeric", + month: "short", + day: "numeric" + }); + else + el.textContent = ''; + } + { + const el = this.shadowRoot.querySelector('#time'); + if (!this.hide_date) + el.textContent = new Date().toLocaleDateString(navigator.language || navigator.userLanguage, { + hour: "numeric", + minute: "numeric", + date: "short" + }).split(' ')[1]; + else + el.textContent = ''; + } + } +}); diff --git a/client/src/shared/rich-text-editor.js b/client/src/shared/rich-text-editor.js index 57b894f..65a0ecb 100644 --- a/client/src/shared/rich-text-editor.js +++ b/client/src/shared/rich-text-editor.js @@ -216,6 +216,7 @@ customElements.define('rich-text-editor', class extends Component { const img = new Image(); img.src = reader.result || ''; el.appendChild(img); + this.#emitChange(); }; reader.readAsDataURL(file); }); diff --git a/src/routes/unrestricted.rs b/src/routes/unrestricted.rs index eb66896..00ffe01 100644 --- a/src/routes/unrestricted.rs +++ b/src/routes/unrestricted.rs @@ -126,7 +126,7 @@ struct AccountTemplate { async fn account_page(id: Identity, db: Data) -> Result { let pool = db.into_inner(); let mut t = crate::ok_or_internal!(pool.begin().await); - let record = match id.identity() { + let account = match id.identity() { Some(id) => queries::account_by_id(&mut t, id).await, _ => { id.forget(); @@ -136,7 +136,7 @@ async fn account_page(id: Identity, db: Data) -> Result, + error: Option, + page: Page, + news: Vec, +} + +#[get("/news")] +async fn news(id: Identity, db: Data) -> Result { + let pool = db.into_inner(); + let mut t = crate::ok_or_internal!(pool.begin().await); + let account = match id.identity() { + Some(id) => queries::account_by_id(&mut t, id).await, + _ => { + id.forget(); + None + } + }; + let news = queries::published_news(&mut t).await.unwrap_or_default(); + Ok(HttpResponse::Ok().content_type("text/html").body( + NewsTemplate { + account, + error: None, + page: Page::News, + news, + } + .render() + .unwrap(), + )) +} + pub fn configure(config: &mut ServiceConfig) { std::fs::create_dir_all("./uploads").expect("Failed to create ./uploads directory"); @@ -562,6 +595,7 @@ pub fn configure(config: &mut ServiceConfig) { ) .service(index) .service(account_page) + .service(news) .service(register) .service(logout) .service(login)