Skip to content

Instantly share code, notes, and snippets.



Last active Oct 23, 2019
What would you like to do?
(ns wh.components.job
#?(:cljs [wh.components.ellipsis.views :refer [ellipsis]])
[reagent.core :as r] ;; added purely for our like-job-post component, delete this if you don't want to the use below
[wh.common.job :as jobc]
[ :refer [match-circle]]
[wh.components.common :refer [wrap-img link img]]
[wh.components.icons :refer [icon]]
[wh.interop :as interop]
[ :refer [dispatch]]
[wh.routes :as routes]
[wh.slug :as slug]
[wh.util :as util]))
(defn state->candidate-status
(cond (s #{:pending :approved}) "Pending"
(s #{:get_in_touch}) "Interviewing"
(s #{:pass :rejected}) "Rejected"
(s #{:hired}) "Hired"))
(defn like-job-post
"when we click the heart icon it should increment the like count atom, and as it dereferences,
we see how popular the job is getting. But as it is , this is all local state . And the only
people liking it is us..."
(let [likes (r/atom 0)]
(fn []
[:h2 @likes (if (= 1 @likes) [:h4 " person likes this..."] [:h4 " people like this..."])]
[icon "like"
:id (str "job-card__like-button_job-" 3)
:class "job__icon like job__icon__private job__icon--pointer"
:on-click #(swap! likes inc)]]])))
(defn company-perks
"takes all the potential perks a job can be registered to have.
The base case would be remote and sponsorship are false ,
but role-type would be a value , set to full-time. "
[remote role-type sponsorship-offered]
;; for each truthy value, evaluate the expression associated.
;; [icon ...] is a helper component , and you can find it in
;; client/common/src/wh/components/icons.cljc
(cond-> [:div.card__perks]
remote (conj [icon "job-remote" :class "job__icon--small"] "Remote")
(not= role-type "Full time") (conj [icon "profile" :class "job__icon--small"] role-type)
sponsorship-offered (conj [icon "job-sponsorship" :class "job__icon--small"] "Sponsorship")))
(defn company-info
[{:keys [remote title display-location role-type sponsorship-offered salary]} company-name]
[:div.job-title title]
[ company-name]
[:div.location display-location]
[company-perks remote role-type sponsorship-offered]
[:div.salary salary]])
(when (and logged-in? (not skeleton?))
[icon "like"
:id (str "job-card__like-button_job-" id)
:class (util/merge-classes "job__icon" "like" (when liked? "selected"))
:on-click #(dispatch [ job])])
(defn job-card--header
[{:keys [remote id slug logo title display-location role-type sponsorship-offered salary published] :as job}
{logo :logo company-name :name}
{:keys [logged-in? skeleton? liked? on-close]}]
;; replace the below if you want, for the comment above
(when (and logged-in? (not skeleton?) on-close)
[icon "close"
:id (str "job-card__blacklist-button_job-" id)
:class "job__icon blacklist"
:on-click #(dispatch [ job on-close])])
[:a {:href (when published (routes/path :job :params {:slug slug}))}
(if (or skeleton? (not logo))
(wrap-img img logo {:alt (str company-name " logo") :w 48 :h 48}))]
[company-info job company-name]]]])
(defn job-card--tags
(into [:ul.tags.tags__job]
(map (fn [tag] [:li [:a {:href (routes/path :pre-set-search :params {:tag (slug/slug tag)})} tag]])
(defn user-button
"depending on if the user is viewing the post as a candidate,
or the user is in fact the admin, then the post will come with
functionality to edit the post, or if it is a candidate viewing
the card then there will only be the options of more-info and applying."
[{:keys [slug published applied id is-company? is-admin?] :as job}
{:keys [user-has-applied? user-is-owner? user-is-company? applied? logged-in?] :as user}]
(let [apply-id (str "job-card__apply-button_job-" id)
button-opts (merge {:id apply-id}
(when (or applied?
(and user-is-company?
(not user-is-owner?)))
{:disabled true}))]
(if (not user-is-owner?)
(when published
(let [job-page-path [:job :params {:slug slug} :query-params {:apply true}]]
[:a (if logged-in?
{:href (apply routes/path job-page-path)}
;; show-auth-popup is needed here to wrap our event dispatch for applying,
;; as the person may not be logged in at the time they click apply.
(interop/show-auth-popup :jobcard-apply job-page-path)))
[:button.button button-opts
;; the difference between applied? is that they applied for THIS application,
;; whereas user-has-applied? is seeing if the candidate has applied for OTHER applications,
;; therefore making the application process much quicker.
(cond applied?
"1-Click Apply"
"Easy Apply")]]))
[:a {:href (routes/path :edit-job :params {:id id})}
[:button.button "Edit"]])))
(defn job-card--buttons
"out of the job data, the id , state , slug and published are pulled.
the slug is the url fragment used in the wh frontend routing system,
as the unique identifier. Published is to check that the job is available for view,
and on the market"
[{:keys [id state slug published] :as job}
{:keys [user-has-applied? user-is-owner? user-is-company? applied? logged-in?] :as user}]
(when state
[:span.applied-state "Status: " (state->candidate-status state)]])
[:a.button.button--inverted {:href (routes/path :job :params {:slug slug})}
(if user-is-owner? "View" "More Info")]
;; determine the type of user, and show the ability to edit or the ability to apply.
[user-button job user]]])
(defn job-card
[{:keys [company tagline tags published score user-score applied liked display-salary remuneration]
:or {published true}
:as job}
{:keys [liked? applied? user-is-owner?]
:or {liked? (or liked false)
applied? (or applied false)
user-is-owner? false}
:as opts}]
(let [skeleton? (and job (empty? (dissoc job :id :slug)))
salary (or display-salary (jobc/format-job-remuneration remuneration))
job-tags (if skeleton?
(map (fn [_i] (apply str (repeat (+ 8 (rand-int 30)) ""))) (range 6))
score (or (:user-score job) score)
opts (assoc opts
:liked? liked?
:applied? applied?)]
[:div {:class (util/merge-classes "card"
(str "card-border-color-" (rand-int 8))
(str "i-cur-" (rand-int 9))
(when skeleton? "job-card--skeleton"))}
[job-card--header (assoc job :salary salary) company opts]
[job-card--tags job-tags]
[:div.tagline #?(:cljs [ellipsis tagline]
:clj tagline)]
(when score
[match-circle score true])
[job-card--buttons job opts]
(when (and (not published) user-is-owner?)
;; included for the reference that others files have to this highlight feature, allowing the code above to compile...
(defn highlight
[title icon-name body]
[:h2 title]
(when title [icon icon-name])]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment