(use joy)


(route :get "/{{plural}}" :{{plural}}/index)
(route :get "/{{plural}}/new" :{{plural}}/new)
(route :get "/{{plural}}/:id" :{{plural}}/show)
(route :post "/{{plural}}" :{{plural}}/create)
(route :get "/{{plural}}/:id/edit" :{{plural}}/edit)
(route :patch "/{{plural}}/:id" :{{plural}}/patch)
(route :delete "/{{plural}}/:id" :{{plural}}/delete)


(defn {{singular}} [req]
  (let [id (get-in req [:params :id])]
    (db/find :{{table}} id)))


(def params
  (params :{{table}}
    (validates [{{#app-columns}} :{{name}}{{/app-columns}}] :required true)
    (permit [{{#app-columns}} :{{name}}{{/app-columns}}])))


(defn {{plural}}/index [req]
  (let [{{plural}} (db/from :{{table}})]
   [:div
    [:a {:href (url-for :{{plural}}/new)} "New {{singular}}"]

    [:table
     [:thead
      [:tr
       {{#columns}}
       [:th "{{name}}"]
       {{/columns}}
       [:th]
       [:th]
       [:th]]]
     [:tbody
      (foreach [{{singular}} {{plural}}]
        [:tr
          {{#columns}}
          [:td ({{singular}} :{{name}})]
          {{/columns}}
          [:td
           [:a {:href (url-for :{{plural}}/show {{singular}})} "Show"]]
          [:td
           [:a {:href (url-for :{{plural}}/edit {{singular}})} "Edit"]]
          [:td
           (form-for [req :{{plural}}/delete {{singular}}]
            [:input {:type "submit" :value "Delete"}])]])]]]))


(defn {{plural}}/show [req]
  (def {{singular}} ({{singular}} req))

  [:div
   {{#columns}}
   [:strong "{{name}}"]
   [:div ({{singular}} :{{name}})]

   {{/columns}}

   [:a {:href (url-for :{{plural}}/index)} "All {{plural}}"]])


(defn {{plural}}/new [req]
  (def errors (get req :errors {}))
  (def body (get req :body {}))

  (form-for [req :{{plural}}/create]
    {{#app-columns}}
    [:div
     [:label {:for "{{name}}"} "{{name}}"]
     [:input {:type "text" :name "{{name}}" :value (body :{{name}})}]
     [:small (errors :{{name}})]]

    {{/app-columns}}
    [:input {:type "submit" :value "Save"}]))


(defn {{plural}}/create [req]
  (let [result (->> (params req)
                    (db/insert)
                    (rescue))
        [errors {{singular}}] result]
    (if errors
      ({{plural}}/new (put req :errors errors))
      (redirect-to :{{plural}}/index))))


(defn {{plural}}/edit [req]
  (def {{singular}} ({{singular}} req))
  (def errors (get req :errors {}))
  (def body (get req :body {}))

  (form-for [req :{{plural}}/patch {{singular}}]
    {{#app-columns}}
    [:div
     [:label {:for "{{name}}"} "{{name}}"]
     [:input {:type "text" :name "{{name}}" :value (or (body :{{name}})
                                                       ({{singular}} :{{name}}))}]
     [:small (errors :{{name}})]]

    {{/app-columns}}
    [:input {:type "submit" :value "Save"}]))


(defn {{plural}}/patch [req]
  (let [{{singular}} ({{singular}} req)
        result (->> (params req)
                    (merge {{singular}})
                    (db/update)
                    (rescue))
        [errors {{singular}}] result]
    (if errors
      ({{plural}}/edit (put req :errors errors))
      (redirect-to :{{plural}}/index))))


(defn {{plural}}/delete [req]
  (def {{singular}} ({{singular}} req))

  (db/delete {{singular}})

  (redirect-to :{{plural}}/index))
