summaryrefslogtreecommitdiff
path: root/lisp/webapps
diff options
context:
space:
mode:
authorckonstanski <kostcarl@isu.edu>2026-07-19 22:05:02 -0600
committerckonstanski <kostcarl@isu.edu>2026-07-19 22:05:02 -0600
commite7301bcd63c0cbfc4d55f21d0d7c33c7557d6444 (patch)
tree2fc51725eb8931c09df6d9360bb358e7645a5244 /lisp/webapps
parent08e435104c42751689553537b1f20ffb14b8dfcc (diff)
starting resume logic
Diffstat (limited to 'lisp/webapps')
-rw-r--r--lisp/webapps/resume/clojurescript/resume/src/core.cljs268
-rw-r--r--lisp/webapps/resume/site.lisp93
-rw-r--r--lisp/webapps/resume/static/css/stylesheet.css45
3 files changed, 276 insertions, 130 deletions
diff --git a/lisp/webapps/resume/clojurescript/resume/src/core.cljs b/lisp/webapps/resume/clojurescript/resume/src/core.cljs
index 7010a88..a84c806 100644
--- a/lisp/webapps/resume/clojurescript/resume/src/core.cljs
+++ b/lisp/webapps/resume/clojurescript/resume/src/core.cljs
@@ -29,8 +29,6 @@
(declare handler-menu)
(declare handler-menu-user)
(declare render-menu)
-(declare comp-home)
-(declare handler-home)
(declare render-home)
(declare template-login)
(declare handler-login)
@@ -128,6 +126,29 @@
(declare on-users-delete-clicked)
(declare handler-users-delete)
(declare render-users-delete)
+(declare template-resumes)
+(declare handler-resumes)
+(declare render-resumes)
+(declare template-resumes-view)
+(declare handler-resumes-view)
+(declare render-resumes-view)
+(declare on-resumes-add-clicked)
+(declare template-resumes-add)
+(declare handler-resumes-add)
+(declare render-resumes-add)
+(declare on-resumes-add-submit-clicked)
+(declare handler-resumes-add-submit)
+(declare render-resumes-add-submit)
+(declare on-resumes-modify-clicked)
+(declare template-resumes-modify)
+(declare handler-resumes-modify)
+(declare render-resumes-modify)
+(declare on-resumes-modify-submit-clicked)
+(declare handler-resumes-modify-submit)
+(declare render-resumes-modify-submit)
+(declare on-resumes-delete-clicked)
+(declare handler-resumes-delete)
+(declare render-resumes-delete)
(declare on-menu-clicked)
(declare handler-location)
(declare goto-location)
@@ -137,14 +158,14 @@
(enable-console-print!)
-(defonce jquery (js* "$"))
-(defonce sql-formatter (time-format/formatter "yyyy-MM-dd HH:mm:ss"))
-(defonce pretty-formatter (time-format/formatters :rfc822))
-(defonce location-state (r/atom "/home"))
-(defonce about-us-category-state (r/atom nil))
-(defonce menu-main-state (r/atom []))
-(defonce menu-user-state (r/atom []))
-(defonce menu-user-label (r/atom nil))
+(def jquery (js* "$"))
+(def sql-formatter (time-format/formatter "yyyy-MM-dd HH:mm:ss"))
+(def pretty-formatter (time-format/formatters :rfc822))
+(def location-state (r/atom "/home"))
+(def about-us-category-state (r/atom "home"))
+(def menu-main-state (r/atom []))
+(def menu-user-state (r/atom []))
+(def menu-user-label (r/atom "Guest User"))
;; helper functions
@@ -182,7 +203,7 @@
[:tr
[:td {:class "banner-menu"}
[comp-menu-user]]
- [:td {:class "banner-title"} "Bogen-" [:i "Herr"]]
+ [:td {:class "banner-title"} "Resume Builder"]
[:td {:class "banner-menu"} " "]]]]]
[comp-menu-main]
[ck-notifications/comp-errormsg]
@@ -242,7 +263,7 @@
(defn comp-menu-main []
[:div {:class "well"}
[:ul {:class "nav nav-pills"}
- (for [menuitem @menu-main-state]
+ (for [menuitem (doall @menu-main-state)]
[:li {:key (str "li_" (get menuitem "id"))
:class "nav-item"}
[:a {:class (cond (= (str/upper-case (get menuitem "handler"))
@@ -264,7 +285,7 @@
:aria-expanded "false"}
@menu-user-label]
[:div {:class "dropdown-menu" :aria-labelledby "button-menu-user"}
- (for [menuitem @menu-user-state]
+ (for [menuitem (doall @menu-user-state)]
[:a {:key (get menuitem "id")
:class "dropdown-item"
:on-click #(on-menu-clicked (get menuitem "handler"))}
@@ -283,33 +304,6 @@
(GET "/menu" {:handler handler-menu})
(GET "/menu/user" {:handler handler-menu-user}))
-;; home
-
-(hiccups/defhtml template-home [jsonobj]
- [:div
- [:h2 {:style "text-align: center"} "Welcome To Carlos Konstanski's Music Studio"]
- [:h3 {:style "text-align: center"}
- [:i "a.k.a. der Bogenherr" [:br] "a.k.a. Dr. Divertimento"]]
- [:h2 {:style "text-align: center"} "Study the Violin, Viola and Viola d'Amore With Me!"]
- [:div {:style "text-align: center"}
- [:img {:style "width: 100%"
- :src "/static/images/instrument-cabinet.jpg"}]]])
-
-(defn handler-home [response]
- (let [jsonobj (js->clj (js/JSON.parse response))]
- (notifications jsonobj)
- (dommy/set-html! (dommy/sel1 :#body) (template-home jsonobj))))
-
-(defn render-home
- ([]
- (GET "/home" {:handler handler-home}))
- ([message errormsg]
- (POST "/home"
- {:format :raw
- :params {:message message
- :errormsg errormsg}
- :handler handler-home})))
-
;; login
(hiccups/defhtml template-login [jsonobj]
@@ -506,13 +500,11 @@
:pwd2 (dommy/value (dommy/sel1 :#pwd2))}
:handler handler-password-submit}))
-;; about-us (lessons, gigs, programming)
+;; about-us (home)
(hiccups/defhtml template-about-us [jsonobj]
[:h1 {:style "text-align: center"}
- (cond (= @about-us-category-state "lessons") "About the Studio"
- (= @about-us-category-state "gigs") "Hire Me to Play"
- (= @about-us-category-state "programming") "Hire Me to Write Software")]
+ (cond (= @about-us-category-state "home") "Home")]
[:div {:id "content"}]
[:div {:id "modify"
:class "modal fade"
@@ -543,14 +535,15 @@
(dommy/set-html! (dommy/sel1 :#body) (template-about-us jsonobj))
(render-about-us-view)))
-(defn render-lessons []
- (GET "/lessons" {:handler handler-about-us}))
-
-(defn render-gigs []
- (GET "/gigs" {:handler handler-about-us}))
-
-(defn render-programming []
- (GET "/programming" {:handler handler-about-us}))
+(defn render-home
+ ([]
+ (GET "/home" {:handler handler-about-us}))
+ ([message errormsg]
+ (POST "/home"
+ {:format :raw
+ :params {:message message
+ :errormsg errormsg}
+ :handler handler-about-us})))
;; about-us-view
@@ -583,9 +576,7 @@
(let [jsonobj (js->clj (js/JSON.parse response))]
(auth-notifications jsonobj)
(dommy/set-html! (dommy/sel1 :#modify-title)
- (str (cond (= @about-us-category-state "lessons") "About the Studio"
- (= @about-us-category-state "gigs") "For Hire"
- (= @about-us-category-state "programming") "Software Consulting")
+ (str (cond (= @about-us-category-state "home") "Home")
" - Modify"))
(dommy/set-html! (dommy/sel1 :#modify-body) (template-about-us-modify jsonobj))
(.modal (jquery "#modify"))))
@@ -1036,6 +1027,167 @@
{:format :raw
:handler handler-users-delete}))
+;; resumes
+
+(hiccups/defhtml template-resumes [jsonobj]
+ [:h3 {:style "text-align: center"} (get jsonobj "title")]
+ [:div {:id "content"}]
+ [:div {:id "modify"
+ :class "modal fade"
+ :role "dialog"
+ :tabindex "-1"}
+ [:div {:class "modal-dialog modal-lg"}
+ [:div {:class "modal-content"}
+ [:div {:class "modal-header"}
+ [:h5 [:span {:id "modify-title"}]]
+ [:button {:type "button"
+ :class "close"
+ :data-dismiss "modal"}
+ "&times;"]]
+ [:div {:id "modify-body"
+ :class "modal-body"
+ :style "height: 450px;"}]
+ [:div {:class "modal-footer"}
+ [:button {:type "submit"
+ :class "btn btn-danger btn-default"
+ :data-dismiss "modal"}
+ [:span {:class "glyphicon glyphicon-remove"}]
+ "Cancel"]]]]])
+
+(defn handler-resumes [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#body) (template-resumes jsonobj))
+ (render-resumes-view)))
+
+(defn render-resumes []
+ (GET "/resumes" {:handler handler-resumes}))
+
+;; resumes-view
+
+(hiccups/defhtml template-resumes-view [jsonobj]
+ [:div {:style "text-align: right"}
+ [:img {:src "/static/images/add.png"
+ :style "cursor:pointer; cursor:hand"
+ :onclick (str (namespace ::x) ".on_resumes_add_clicked()")}]]
+ [:table {:class "table table-striped table-hover table-sm"}
+ [:thead
+ [:tr
+ [:th {:scope "col"} "Name"]
+ [:th {:scope "col"} "Del"]]]
+ [:tbody
+ (for [resume (get jsonobj "resumes")]
+ (let [onclick (str (namespace ::x) ".on_resumes_modify_clicked(" (get resume "id") ")")
+ toggle-active (str (namespace ::x) ".on_resumes_toggle_active_clicked(" (get resume "id") ")")]
+ [:tr
+ [:td {:onclick onclick} (get resume "name")]
+ [:td {:width "50"}
+ [:img {:src "/static/images/delete.png"
+ :onclick (str (namespace ::x) ".on_resumes_delete_clicked(" (get resume "id") ", '" (get resume "name") "')")}]]]))]])
+
+(defn handler-resumes-view [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (dommy/set-html! (dommy/sel1 :#content) (template-resumes-view jsonobj))))
+
+(defn render-resumes-view []
+ (GET "/resumes/view" {:handler handler-resumes-view}))
+
+;; resumes-add
+
+(defn on-resumes-add-clicked []
+ (render-resumes-add))
+
+(hiccups/defhtml template-resumes-add [jsonobj]
+ (ck-form/template-generic-form (get jsonobj "form") (namespace ::x)))
+
+(defn handler-resumes-add [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#modify-title) (get jsonobj "title"))
+ (dommy/set-html! (dommy/sel1 :#modify-body) (template-resumes-add jsonobj))
+ (.modal (jquery "#modify"))))
+
+(defn render-resumes-add []
+ (POST "/resumes/add" {:handler handler-resumes-add}))
+
+;; resumes-add-submit
+
+(defn on-resumes-add-submit-clicked []
+ (when (-> (jquery "#resumes-add-form")
+ (.get "0")
+ (.checkValidity))
+ (.modal (jquery "#modify") "hide")
+ (render-resumes-add-submit)))
+
+(defn handler-resumes-add-submit [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (auth-notifications jsonobj)
+ (on-menu-clicked "/resumes")))
+
+(defn render-resumes-add-submit []
+ (POST "/resumes/add/submit"
+ {:format :raw
+ :params {:name (dommy/value (dommy/sel1 :#name))}
+ :handler handler-resumes-add-submit}))
+
+;; resumes-modify
+
+(defn on-resumes-modify-clicked [id]
+ (render-resumes-modify id))
+
+(hiccups/defhtml template-resumes-modify [jsonobj]
+ (ck-form/template-generic-form (get jsonobj "form") (namespace ::x)))
+
+(defn handler-resumes-modify [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (auth-notifications jsonobj)
+ (dommy/set-html! (dommy/sel1 :#modify-title) (get jsonobj "title"))
+ (dommy/set-html! (dommy/sel1 :#modify-body) (template-resumes-modify jsonobj))
+ (.modal (jquery "#modify"))))
+
+(defn render-resumes-modify [id]
+ (POST "/resumes/modify"
+ {:format :raw
+ :params {:id id}
+ :handler handler-resumes-modify}))
+
+;; resumes-modify-submit
+
+(defn on-resumes-modify-submit-clicked []
+ (when (-> (jquery "#resumes-modify-form")
+ (.get "0")
+ (.checkValidity))
+ (.modal (jquery "#modify") "hide")
+ (render-resumes-modify-submit)))
+
+(defn handler-resumes-modify-submit [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (auth-notifications jsonobj)
+ (on-menu-clicked "/resumes")))
+
+(defn render-resumes-modify-submit []
+ (POST "/resumes/modify/submit"
+ {:format :raw
+ :params {:id (dommy/value (dommy/sel1 :#id))
+ :name (dommy/value (dommy/sel1 :#name))}
+ :handler handler-resumes-modify-submit}))
+
+;; resumes-delete
+
+(defn on-resumes-delete-clicked [id name]
+ (when (js/confirm (str "Are you sure you want to delete " name "? This action cannot be undone."))
+ (render-resumes-delete id)))
+
+(defn handler-resumes-delete [response]
+ (let [jsonobj (js->clj (js/JSON.parse response))]
+ (auth-notifications jsonobj)
+ (on-menu-clicked "/resumes")))
+
+(defn render-resumes-delete [id]
+ (DELETE (str "/resumes/delete/" id)
+ {:format :raw
+ :handler handler-resumes-delete}))
+
;; location
(defn on-menu-clicked [handler]
@@ -1046,12 +1198,10 @@
(= handler "/logout") (render-logout)
(= handler "/profile") (render-profile)
(= handler "/password") (render-password)
- (= handler "/lessons") (render-lessons)
- (= handler "/gigs") (render-gigs)
- (= handler "/programming") (render-programming)
(= handler "/contact-us") (render-contact-us)
(= handler "/messages") (render-messages)
- (= handler "/users") (render-users)))
+ (= handler "/users") (render-users)
+ (= handler "/resumes") (render-resumes)))
(defn handler-location [response]
(let [jsonobj (js->clj (js/JSON.parse response))]
diff --git a/lisp/webapps/resume/site.lisp b/lisp/webapps/resume/site.lisp
index 3e31ac1..a7e5916 100644
--- a/lisp/webapps/resume/site.lisp
+++ b/lisp/webapps/resume/site.lisp
@@ -30,10 +30,19 @@
`(location-json location))
(defmacro .home-get ()
- `(home-json))
+ `(about-us-json "home"))
(defmacro .home-post ()
- `(home-json message errormsg))
+ `(about-us-json "home" message errormsg))
+
+(defmacro .home-view ()
+ `(about-us-view-json "home"))
+
+(defmacro .home-modify ()
+ `(about-us-modify-json "home"))
+
+(defmacro .home-modify-submit ()
+ `(about-us-modify-submit-json "home" content))
(defmacro .menu ()
`(menu-json))
@@ -71,42 +80,6 @@
(defmacro .password-submit ()
`(password-submit-json id pwd pwd2))
-(defmacro .lessons ()
- `(about-us-json "lessons"))
-
-(defmacro .lessons-view ()
- `(about-us-view-json "lessons"))
-
-(defmacro .lessons-modify ()
- `(about-us-modify-json "lessons"))
-
-(defmacro .lessons-modify-submit ()
- `(about-us-modify-submit-json "lessons" content))
-
-(defmacro .gigs ()
- `(about-us-json "gigs"))
-
-(defmacro .gigs-view ()
- `(about-us-view-json "gigs"))
-
-(defmacro .gigs-modify ()
- `(about-us-modify-json "gigs"))
-
-(defmacro .gigs-modify-submit ()
- `(about-us-modify-submit-json "gigs" content))
-
-(defmacro .programming ()
- `(about-us-json "programming"))
-
-(defmacro .programming-view ()
- `(about-us-view-json "programming"))
-
-(defmacro .programming-modify ()
- `(about-us-modify-json "programming"))
-
-(defmacro .programming-modify-submit ()
- `(about-us-modify-submit-json "programming" content))
-
(defmacro .contact-us ()
`(contact-us-json))
@@ -158,10 +131,34 @@
(defmacro .users-delete ()
`(users-delete-json id))
+(defmacro .resumes ()
+ `(resumes-json))
+
+(defmacro .resumes-view ()
+ `(resumes-view-json))
+
+(defmacro .resumes-add ()
+ `(resumes-add-json))
+
+(defmacro .resumes-add-submit ()
+ `(resumes-add-submit-json name))
+
+(defmacro .resumes-modify ()
+ `(resumes-modify-json id))
+
+(defmacro .resumes-modify-submit ()
+ `(resumes-modify-submit-json id name))
+
+(defmacro .resumes-delete ()
+ `(users-delete-json id))
+
(define-endpoint ("/" :method :get) () .base)
(define-endpoint ("/location" :method :post) (&post (location :parameter-type 'string)) .location)
(define-endpoint ("/home" :method :get) () .home-get)
(define-endpoint ("/home" :method :post) (&post (message :parameter-type 'string) (errormsg :parameter-type 'string)) .home-post)
+(define-endpoint ("/home/view" :method :get) () .home-view)
+(define-endpoint ("/home/modify" :method :post) () .home-modify)
+(define-endpoint ("/home/modify/submit" :method :post) (&post (content :parameter-type 'string)) .home-modify-submit)
(define-endpoint ("/menu" :method :get) () .menu)
(define-endpoint ("/menu/user" :method :get) () .menu-user)
(define-endpoint ("/login" :method :get) () .login)
@@ -174,18 +171,6 @@
(define-endpoint ("/profile/modify/submit" :method :post) (&post (id :parameter-type 'integer) (username :parameter-type 'string) (first_name :parameter-type 'string) (last_name :parameter-type 'string) (email :parameter-type 'string) (phone :parameter-type 'string)) .profile-modify-submit)
(define-endpoint ("/password" :method :get) () .password)
(define-endpoint ("/password/submit" :method :post) (&post (id :parameter-type 'integer) (pwd :parameter-type 'string) (pwd2 :parameter-type 'string)) .password-submit)
-(define-endpoint ("/lessons" :method :get) () .lessons)
-(define-endpoint ("/lessons/view" :method :get) () .lessons-view)
-(define-endpoint ("/lessons/modify" :method :post) () .lessons-modify)
-(define-endpoint ("/lessons/modify/submit" :method :post) (&post (content :parameter-type 'string)) .lessons-modify-submit)
-(define-endpoint ("/gigs" :method :get) () .gigs)
-(define-endpoint ("/gigs/view" :method :get) () .gigs-view)
-(define-endpoint ("/gigs/modify" :method :post) () .gigs-modify)
-(define-endpoint ("/gigs/modify/submit" :method :post) (&post (content :parameter-type 'string)) .gigs-modify-submit)
-(define-endpoint ("/programming" :method :get) () .programming)
-(define-endpoint ("/programming/view" :method :get) () .programming-view)
-(define-endpoint ("/programming/modify" :method :post) () .programming-modify)
-(define-endpoint ("/programming/modify/submit" :method :post) (&post (content :parameter-type 'string)) .programming-modify-submit)
(define-endpoint ("/contact-us" :method :get) () .contact-us)
(define-endpoint ("/contact-us/view" :method :get) () .contact-us-view)
(define-endpoint ("/contact-us/email" :method :post) (&post (first_name :parameter-type 'string) (last_name :parameter-type 'string) (email :parameter-type 'string) (phone :parameter-type 'string) (comments :parameter-type 'string)) .contact-us-email)
@@ -204,3 +189,11 @@
(define-endpoint ("/users/modify/submit" :method :post) (&post (id :parameter-type 'integer) (role_groups :parameter-type 'string) (username :parameter-type 'string) (first_name :parameter-type 'string) (last_name :parameter-type 'string) (email :parameter-type 'string) (phone :parameter-type 'string)) .users-modify-submit)
(define-endpoint ("/users/toggle-active" :method :post) (&post (id :parameter-type 'integer)) .users-toggle-active)
(define-endpoint ("/users/delete/:id" :method :delete) (&path (id 'integer)) .users-delete)
+
+(define-endpoint ("/resumes" :method :get) () .resumes)
+(define-endpoint ("/resumes/view" :method :get) () .resumes-view)
+(define-endpoint ("/resumes/add" :method :post) () .resumes-add)
+(define-endpoint ("/resumes/add/submit" :method :post) (&post (name :parameter-type 'string)) .resumes-add-submit)
+(define-endpoint ("/resumes/modify" :method :post) (&post (id :parameter-type 'integer)) .resumes-modify)
+(define-endpoint ("/resumes/modify/submit" :method :post) (&post (id :parameter-type 'integer) (name :parameter-type 'string)) .resumes-modify-submit)
+(define-endpoint ("/resumes/delete/:id" :method :delete) (&path (id 'integer)) .resumes-delete)
diff --git a/lisp/webapps/resume/static/css/stylesheet.css b/lisp/webapps/resume/static/css/stylesheet.css
index 659aa54..0589853 100644
--- a/lisp/webapps/resume/static/css/stylesheet.css
+++ b/lisp/webapps/resume/static/css/stylesheet.css
@@ -1,16 +1,20 @@
body {
- background-color: #161012;
+ background-color: black;
color: white;
font-size: 14px;
}
hr {
- border: 1px #ffd081 solid;
+ border: 1px #404040 solid;
width: 200px;
}
a {
- color: #ffd081;
+ color: lightblue;
+}
+
+a:hover {
+ color: lightgreen;
}
.container-fluid {
@@ -31,13 +35,13 @@ a {
.nav-pills {
.nav-link.active,
.show > .nav-link {
- background-color: #59200e;
+ background-color: #404040;
}
}
.well {
- background-color: #2c180d;
- border: 1px black solid;
+ background-color: #202020;
+ border: 1px #404040 solid;
text-align: center;
}
@@ -45,41 +49,39 @@ a {
.btn-primary,
.dropdown-toggle {
color: white;
- background-color: #59200e;
- border-color: #59200e;
+ background-color: #202020;
+ border-color: #404040;
&:hover {
color: white;
- background-color: #59200e;
- border-color: #59200e;
+ background-color: #202020;
+ border-color: #404040;
}
}
.show > .btn-primary.dropdown-toggle {
color: white;
- background-color: #59200e;
- border-color: #59200e;
+ background-color: #202020;
+ border-color: #404040;
}
.dropdown-menu {
color: white;
- background-color: #59200e;
+ background-color: #202020;
}
.dropdown-item {
color: white;
- background-color: #59200e;
+ background-color: #202020;
}
.banner {
height: 90px;
- background-image: url("/static/images/violin-strip.jpg");
- background-repeat: repeat;
- background-position: left;
+ background-color: black;
}
.banner-title {
width: *;
- color: #59200e;
+ color: white;
font-size: 28px;
font-weight: bold;
text-align: center;
@@ -93,18 +95,19 @@ a {
.form-control {
width: 600px;
- background-color: #ffd081;
+ color: #ffffff;
+ background-color: #202020;
}
.contact-info {
- color: #59200e;
+ color: #202020;
font-size: 15px;
font-weight: bold;
line-height: 0.4;
}
.modal-content {
- background-color: #161012;
+ background-color: #202020;
}
#body {