Implement collapse panel

- Change profile search menu item to "Job Seekers"
This commit is contained in:
Daniel J. Summers 2023-01-31 21:26:58 -05:00
parent 61e8909ba9
commit de0883b898
5 changed files with 68 additions and 54 deletions

View File

@ -228,6 +228,13 @@ span.jjj-audio-clip:hover {
border: solid 1px lightgray;
border-radius: .5rem;
}
/* Collapse Panel styling */
a[data-bs-toggle] {
color: var(--bs-body-color);
}
a[data-bs-toggle]:hover {
text-decoration: none;
}
/* Footer styling */
footer {
display: flex;

View File

@ -100,16 +100,16 @@ let markdownEditor attrs name value editorLabel isHtmx =
]
/// Wrap content in a collapsing panel
let collapsePanel header content =
let collapsePanel header isShown content =
let showClass = if isShown then " show" else ""
div [ _class "card" ] [
div [ _class "card-body" ] [
h6 [ _class "card-title" ] [
// TODO: toggle collapse
//a [ _href "#"; _class "{ 'cp-c': collapsed, 'cp-o': !collapsed }"; @click.prevent="toggle">{{headerText}} ]
txt header
div [ _class "card-header" ] [
h6 [ _class "mb-0 card-title" ] [
a [ _href "#jjjCollapse"; _data "bs-toggle" "collapse"; _roleButton; _ariaControls "#jjjCollapse"
_ariaExpanded (isShown.ToString().ToLowerInvariant ()) ] [ txt header ]
]
yield! content
]
div [ _id "jjjCollapse"; _class $"card-body collapse{showClass}" ] content
]
/// "Yes" or "No" based on a boolean value
@ -242,7 +242,7 @@ module Layout =
if ctx.IsLoggedOn then
navLink "/citizen/dashboard" "view-dashboard-variant" "Dashboard"
navLink "/help-wanted" "newspaper-variant-multiple-outline" "Help Wanted!"
navLink "/profile/search" "view-list-outline" "Employment Profiles"
navLink "/profile/search" "view-list-outline" "Job Seekers"
navLink "/success-stories" "thumb-up" "Success Stories"
div [ _class "separator" ] []
navLink "/citizen/account" "account-edit" "My Account"
@ -252,7 +252,7 @@ module Layout =
navLink "/citizen/log-off" "logout-variant" "Log Off"
else
navLink "/" "home" "Home"
navLink "/profile/search" "view-list-outline" "Employment Profiles"
navLink "/profile/search" "view-list-outline" "Job Seekers"
navLink "/citizen/log-on" "login-variant" "Log On"
navLink "/how-it-works" "help-circle-outline" "How It Works"
]

View File

@ -854,14 +854,15 @@ module Help =
h5 [] [ txt "Search Criteria" ]
p [] [
txt "The employment profile search form is the same whether there is a user logged on or not; however, "
txt "the results are different. There are three sections to the search form. "
strong [] [ txt "Continent" ]; txt " will select profiles from the selected continent, while "
strong [] [ txt "Seeking Remote Work?" ]; txt " will select profiles based whether the citizen has "
txt "selected remote work in their profile. "; strong [] [ txt "Text Search" ]; txt " will search "
txt "several aspects of the employment profile for matches; it is case-insensitive and will match "
txt "using English stemming rules (ex. searching for “force” will match words like "
txt "“force”, “forced”, or “forcing”)."
txt "The "; span [ linkedPage ] [ txt "Job Seekers" ]; txt " page and its search form is the same "
txt "whether there is a user logged on or not; however, the results are different. There are three "
txt "sections to the search form. "; strong [] [ txt "Continent" ]; txt " will select profiles from "
txt "the selected continent, while "; strong [] [ txt "Seeking Remote Work?" ]; txt " will select "
txt "profiles based whether the citizen has selected remote work in their profile. "
strong [] [ txt "Text Search" ]; txt " will search several aspects of the employment profile for "
txt "matches; it is case-insensitive and will match using English stemming rules (ex. searching for "
txt "“force” will match words like “force”, “forced”, or "
txt "“forcing”)."
]
p [] [
txt "If more than one field has a value selected, profiles must match all of those selections to be "

View File

@ -9,7 +9,6 @@ open JobsJobsJobs.Listings.Domain
/// Job listing edit page
let edit (m : EditListingForm) continents isNew isHtmx csrf =
pageWithTitle $"""{if isNew then "Add a" else "Edit"} Job Listing""" [
form [ _class "row g-3"; _method "POST"; _action "/listing/save" ] [
antiForgery csrf
input [ _type "hidden"; _name (nameof m.Id); _value m.Id ]
@ -35,15 +34,15 @@ let edit (m : EditListingForm) continents isNew isHtmx csrf =
]
div [ _class "col-12" ] [ submitButton "content-save-outline" "Save" ]
]
]
|> List.singleton
|> pageWithTitle $"""{if isNew then "Add a" else "Edit"} Job Listing"""
open System.Net
/// Page to expire a job listing
let expire (m : ExpireListingForm) (listing : Listing) isHtmx csrf =
pageWithTitle $"Expire Job Listing ({WebUtility.HtmlEncode listing.Title})" [
p [ _class "fst-italic" ] [
[ p [ _class "fst-italic" ] [
txt "Expiring this listing will remove it from search results. You will be able to see it via your "
txt "“My Job Listings” page, but you will not be able to “un-expire” it."
]
@ -65,14 +64,14 @@ let expire (m : ExpireListingForm) (listing : Listing) isHtmx csrf =
]
jsOnLoad "jjj.listing.toggleFromHere()" isHtmx
]
|> pageWithTitle $"Expire Job Listing ({WebUtility.HtmlEncode listing.Title})"
/// "My Listings" page
let mine (listings : ListingForView list) tz =
let active = listings |> List.filter (fun it -> not it.Listing.IsExpired)
let expired = listings |> List.filter (fun it -> it.Listing.IsExpired)
pageWithTitle "My Job Listings" [
p [] [ a [ _href "/listing/new/edit"; _class "btn btn-outline-primary" ] [ txt "Add a New Job Listing" ] ]
[ p [] [ a [ _href "/listing/new/edit"; _class "btn btn-outline-primary" ] [ txt "Add a New Job Listing" ] ]
if not (List.isEmpty expired) then h4 [ _class "pb-2" ] [ txt "Active Job Listings" ]
if List.isEmpty active then p [ _class "pb-3 fst-italic" ] [ txt "You have no active job listings" ]
else
@ -117,6 +116,7 @@ let mine (listings : ListingForView list) tz =
|> tbody []
]
]
|> pageWithTitle "My Job Listings"
open NodaTime.Text
@ -125,13 +125,12 @@ let private neededBy dt =
(LocalDatePattern.CreateWithCurrentCulture "MMMM d, yyyy").Format dt
let search (m : ListingSearchForm) continents (listings : ListingForView list option) =
pageWithTitle "Help Wanted" [
if Option.isNone listings then
[ if Option.isNone listings then
p [] [
txt "Enter relevant criteria to find results, or just click “Search” to see all active job "
txt "listings."
]
collapsePanel "Search Criteria" [
collapsePanel "Search Criteria" (List.isEmpty (defaultArg listings [])) [
form [ _class "container"; _method "GET"; _action "/help-wanted" ] [
input [ _type "hidden"; _name "searched"; _value "true" ]
div [ _class "row" ] [
@ -201,11 +200,12 @@ let search (m : ListingSearchForm) continents (listings : ListingForView list op
]
| None -> ()
]
|> pageWithTitle "Help Wanted"
/// The job listing view page
let view (it : ListingForView) =
article [] [
h3 [] [
h3 [ _class "mb-1" ] [
str it.Listing.Title
if it.Listing.IsExpired then
span [ _class "jjj-heading-label" ] [
@ -214,11 +214,17 @@ let view (it : ListingForView) =
txt "     "; span [ _class "badge bg-success" ] [ txt "Filled via Jobs, Jobs, Jobs" ]
]
]
h4 [ _class "pb-3 text-muted" ] [ str it.ContinentName; rawText " / "; str it.Listing.Region ]
h4 [ _class "mb-3 text-muted" ] [
str $"{it.ContinentName} / {it.Listing.Region}"
if it.Listing.IsRemote then
span [ _class "jjj-heading-label" ] [
txt "     "; span [ _class "badge text-bg-info" ] [ txt "Remote" ]
]
]
p [] [
match it.Listing.NeededBy with
| Some needed ->
strong [] [ em [] [ txt "NEEDED BY "; str ((neededBy needed).ToUpperInvariant ()) ] ]; txt " • "
strong [] [ em [] [ txt "NEEDED BY "; str ((neededBy needed).ToUpperInvariant ()) ] ]; br [] // txt " • "
| None -> ()
txt "Listed by "; strong [ _class "me-4" ] [ str (Citizen.name it.Citizen) ]; br []
span [ _class "ms-3" ] []; yield! contactInfo it.Citizen false

View File

@ -354,8 +354,8 @@ let editHistory (history : EmploymentHistory list) idx csrf =
// ~~~ PROFILE SEARCH ~~~ //
/// The search form
let private searchForm (m : ProfileSearchForm) continents =
collapsePanel "Search Criteria" [
let private searchForm (m : ProfileSearchForm) continents isShown =
collapsePanel "Search Criteria" isShown [
form [ _class "container"; _method "GET"; _action "/profile/search" ] [
input [ _type "hidden"; _name "searched"; _value "true" ]
div [ _class "row" ] [
@ -474,7 +474,7 @@ let search m continents tz (results : ProfileForView list option) isPublic =
if isPublic then txt "publicly searchable or viewable "
txt "profiles."
]
searchForm m continents
searchForm m continents (List.isEmpty (defaultArg results []))
match results with
| Some r when List.isEmpty r -> p [ _class "pt-3" ] [ txt "No results found for the specified criteria" ]
| Some r -> if isPublic then yield! publicResults r else privateResults r tz