src/views/components/root.lisp
(defpackage murja.views.components.root
(:use :cl :murja.newui :binding-arrows)
(:import-from :murja.middleware.auth :*user*)
(:import-from :murja.posts.post-db :get-titles-by-year)
(:import-from :murja.middleware.db :*settings*)
(:import-from :murja.models.user :user-nickname)
(:export :*inject-to-head* :root-component))
(in-package :murja.views.components.root)
(defun sidebar-tree ()
(let* ((sidebar-titles (->>
(get-titles-by-year)
(lisp-fixup:group-by "Year"))))
(component :ul (:id "grouper")
(loop for year being the hash-keys of sidebar-titles
collecting (c :li ()
(c :details ()
(c :summary () (format nil "~a (~d)" year (length (gethash year sidebar-titles))))
(component :ul ()
(let ((by-month (lisp-fixup:group-by "Month" (gethash year sidebar-titles))))
(loop for month being the hash-keys of by-month
collecting (c :li ()
(c :details ()
(c :summary () (format nil "~a (~d)" month (length (gethash month by-month))))
(component :ul ()
(map 'list
(lambda (title)
(cl-hash-util:with-keys ("Id" "Title") title
(c :li () (c :a (:href (format nil "/blog/post/~d" Id)) Title))))
(gethash month by-month))))))))))))))
(defun loginform/user-widget ()
(if *user*
(c :p (:data-testid "welcome-user-label")
"Welcome, " (c :a (:href "/blog/usersettings") (user-nickname *user*)))
(c :form (:method "post" :action "/api/login")
(c :label () "Username " (c :input (:id "username" :name "username" :data-testid "username-input-field")))
(c :label () "Password " (c :input (:id "password" :name "password" :type "password" :data-testid "password-input-field")))
(c :input (:type :submit :value "Log in")))))
(defvar *inject-to-head* nil)
(defun root-component (inner-component)
"Returns the root html element of murja with `inner-component` embedded inside it"
(let ((head-element (list (c :link (:href "/resources/murja.css" :rel "stylesheet" :type "text/css"))
(c :script (:src "/resources/newui.js"))
(c :meta (:charset "UTF-8")))))
(dolist (to-head *inject-to-head*)
(push to-head head-element))
(c :html ()
(component
:head ()
head-element)
(c :body ()
(c :header ()
(c :a (:href "/") (gethash "blog-title" *settings* )))
(c :div (:class "sidebar-flex")
inner-component
(c :div (:id "sidebar")
(loginform/user-widget)
(sidebar-tree)))))))