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;