From 266e265b7fcfed2ccab27fa5d60307b1e25211bb Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 16 Jan 2023 21:26:49 -0500 Subject: [PATCH] Add contact info to profiles and listings --- src/JobsJobsJobs/Data/Data.fs | 2 +- src/JobsJobsJobs/Domain/SharedTypes.fs | 4 ++-- src/JobsJobsJobs/Server/Handlers.fs | 4 +--- src/JobsJobsJobs/Server/Views/Citizen.fs | 9 ++++++--- src/JobsJobsJobs/Server/Views/Common.fs | 22 ++++++++++++++++++++++ src/JobsJobsJobs/Server/Views/Listing.fs | 3 ++- src/JobsJobsJobs/Server/Views/Profile.fs | 10 +++++----- src/JobsJobsJobs/Server/wwwroot/style.css | 4 ++++ 8 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/JobsJobsJobs/Data/Data.fs b/src/JobsJobsJobs/Data/Data.fs index 3d4dbd2..8529b5a 100644 --- a/src/JobsJobsJobs/Data/Data.fs +++ b/src/JobsJobsJobs/Data/Data.fs @@ -340,7 +340,7 @@ module Listings = let private toListingForView row = { Listing = toDocument row ContinentName = row.string "continent_name" - ListedBy = Citizen.name (toDocumentFrom "cit_data" row) + Citizen = toDocumentFrom "cit_data" row } /// Find all job listings posted by the given citizen diff --git a/src/JobsJobsJobs/Domain/SharedTypes.fs b/src/JobsJobsJobs/Domain/SharedTypes.fs index befd0f3..fe052a5 100644 --- a/src/JobsJobsJobs/Domain/SharedTypes.fs +++ b/src/JobsJobsJobs/Domain/SharedTypes.fs @@ -13,8 +13,8 @@ type ListingForView = /// The name of the continent for the listing ContinentName : string - /// The display name of the citizen who owns the listing - ListedBy : string + /// The citizen who owns the listing + Citizen : Citizen } diff --git a/src/JobsJobsJobs/Server/Handlers.fs b/src/JobsJobsJobs/Server/Handlers.fs index 7c85f82..13d9ee2 100644 --- a/src/JobsJobsJobs/Server/Handlers.fs +++ b/src/JobsJobsJobs/Server/Handlers.fs @@ -716,9 +716,7 @@ module Profile = let! continent = Continents.findById profile.ContinentId let continentName = match continent with Some c -> c.Name | None -> "not found" let title = $"Employment Profile for {Citizen.name citizen}" - return! - Profile.view citizen profile continentName title currentCitizen - |> render title next ctx + return! Profile.view citizen profile continentName currentCitizen |> render title next ctx | None -> return! Error.notFound next ctx | None -> return! Error.notFound next ctx } diff --git a/src/JobsJobsJobs/Server/Views/Citizen.fs b/src/JobsJobsJobs/Server/Views/Citizen.fs index 19cfa0a..0beba62 100644 --- a/src/JobsJobsJobs/Server/Views/Citizen.fs +++ b/src/JobsJobsJobs/Server/Views/Citizen.fs @@ -21,9 +21,12 @@ let contactEdit (contacts : OtherContactForm array) = div [ _class "form-floating" ] [ select [ _id $"contactType{idx}"; _name $"Contacts[{idx}].ContactType"; _class "form-control" _value contact.ContactType; _placeholder "Type"; _required ] [ - option [ _value "Website" ] [ rawText "Website" ] - option [ _value "Email" ] [ rawText "E-mail Address" ] - option [ _value "Phone" ] [ rawText "Phone Number" ] + let optionFor value label = + let typ = ContactType.toString value + option [ _value typ; if contact.ContactType = typ then _selected ] [ rawText label ] + optionFor Website "Website" + optionFor Email "E-mail Address" + optionFor Phone "Phone Number" ] label [ _class "jjj-required"; _for $"contactType{idx}" ] [ rawText "Type" ] ] diff --git a/src/JobsJobsJobs/Server/Views/Common.fs b/src/JobsJobsJobs/Server/Views/Common.fs index 58454eb..c2637f9 100644 --- a/src/JobsJobsJobs/Server/Views/Common.fs +++ b/src/JobsJobsJobs/Server/Views/Common.fs @@ -101,6 +101,28 @@ let yesOrNo value = let md2html value = rawText (MarkdownString.toHtml value) +/// Display a citizen's contact information +let contactInfo citizen isPublic = + citizen.OtherContacts + |> List.filter (fun it -> (isPublic && it.IsPublic) || not isPublic) + |> List.collect (fun contact -> + match contact.ContactType with + | Website -> + [ i [ _class "mdi mdi-sm mdi-web" ] []; rawText " " + a [ _href contact.Value; _target "_blank"; _rel "noopener"; _class "me-4" ] [ + str (defaultArg contact.Name "Website") + ] + ] + | Email -> + [ i [ _class "mdi mdi-sm mdi-email-outline" ] []; rawText " " + a [ _href $"mailto:{contact.Value}"; _class "me-4" ] [ str (defaultArg contact.Name "E-mail") ] + ] + | Phone -> + [ span [ _class "me-4" ] [ + i [ _class "mdi mdi-sm mdi-phone" ] []; rawText " "; str contact.Value + match contact.Name with Some name -> str $" ({name})" | None -> () + ] + ]) open NodaTime open NodaTime.Text diff --git a/src/JobsJobsJobs/Server/Views/Listing.fs b/src/JobsJobsJobs/Server/Views/Listing.fs index 1d7ddd3..70156d2 100644 --- a/src/JobsJobsJobs/Server/Views/Listing.fs +++ b/src/JobsJobsJobs/Server/Views/Listing.fs @@ -234,7 +234,8 @@ let view (it : ListingForView) = strong [] [ em [] [ rawText "NEEDED BY "; str ((neededBy needed).ToUpperInvariant ()) ] ] rawText " • " | None -> () - rawText "Listed by "; str it.ListedBy //{{citizenName(citizen)}} + rawText "Listed by "; strong [ _class "me-4" ] [ str (Citizen.name it.Citizen) ]; br [] + span [ _class "ms-3" ] []; yield! contactInfo it.Citizen false ] hr [] div [] [ md2html it.Listing.Text ] diff --git a/src/JobsJobsJobs/Server/Views/Profile.fs b/src/JobsJobsJobs/Server/Views/Profile.fs index a5cf1fa..1a47abc 100644 --- a/src/JobsJobsJobs/Server/Views/Profile.fs +++ b/src/JobsJobsJobs/Server/Views/Profile.fs @@ -290,18 +290,18 @@ let search (m : ProfileSearchForm) continents tz (results : ProfileSearchResult /// Profile view template -let view (citizen : Citizen) (profile : Profile) (continentName : string) pageTitle currentId = +let view (citizen : Citizen) (profile : Profile) (continentName : string) currentId = article [] [ - h3 [ _class "pb-3" ] [ str pageTitle ] h2 [] [ - // TODO: link to preferred profile - a [ _href "#"; _target "_blank"; _rel "noopener" ] [ str (Citizen.name citizen) ] + str (Citizen.name citizen) if profile.IsSeekingEmployment then span [ _class "jjj-heading-label" ] [ rawText "   "; span [ _class "badge bg-dark" ] [ rawText "Currently Seeking Employment" ] ] ] - h4 [ _class "pb-3" ] [ str $"{continentName}, {profile.Region}" ] + h4 [] [ str $"{continentName}, {profile.Region}" ] + contactInfo citizen (Option.isNone currentId) + |> div [ _class "pb-3" ] p [] [ rawText (if profile.IsFullTime then "I" else "Not i"); rawText "nterested in full-time employment" rawText " • " diff --git a/src/JobsJobsJobs/Server/wwwroot/style.css b/src/JobsJobsJobs/Server/wwwroot/style.css index 8fcb873..63ce4f9 100644 --- a/src/JobsJobsJobs/Server/wwwroot/style.css +++ b/src/JobsJobsJobs/Server/wwwroot/style.css @@ -84,6 +84,10 @@ label.jjj-required::after { top: 3px; left: -3px } +.mdi-sm::before { + font-size: 1rem; + line-height: unset; +} /* Layout styling */ .jjj-app { display: flex;