240 lines
7.2 KiB
Forth
240 lines
7.2 KiB
Forth
/// View models for Jobs, Jobs, Jobs
|
|
module JobsJobsJobs.ViewModels
|
|
|
|
open JobsJobsJobs.Domain
|
|
|
|
/// The fields required for a skill
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type SkillForm =
|
|
{ Description : string
|
|
|
|
/// Notes regarding the skill
|
|
Notes : string
|
|
}
|
|
|
|
/// Functions to support skill forms
|
|
module SkillForm =
|
|
|
|
/// Create a skill form from a skill
|
|
let fromSkill (skill : Skill) =
|
|
{ SkillForm.Description = skill.Description; Notes = defaultArg skill.Notes "" }
|
|
|
|
/// Create a skill from a skill form
|
|
let toSkill (form : SkillForm) =
|
|
{ Skill.Description = form.Description; Notes = if form.Notes = "" then None else Some form.Notes }
|
|
|
|
|
|
/// The data required to add or edit a job listing
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type EditListingForm =
|
|
{ /// The ID of the listing
|
|
Id : string
|
|
|
|
/// The listing title
|
|
Title : string
|
|
|
|
/// The ID of the continent on which this opportunity exists
|
|
ContinentId : string
|
|
|
|
/// The region in which this opportunity exists
|
|
Region : string
|
|
|
|
/// Whether this is a remote work opportunity
|
|
RemoteWork : bool
|
|
|
|
/// The text of the job listing
|
|
Text : string
|
|
|
|
/// The date by which this job listing is needed
|
|
NeededBy : string
|
|
}
|
|
|
|
/// Support functions to support listings
|
|
module EditListingForm =
|
|
|
|
open NodaTime.Text
|
|
|
|
/// Create a listing form from an existing listing
|
|
let fromListing (listing : Listing) theId =
|
|
let neededBy =
|
|
match listing.NeededBy with
|
|
| Some dt -> (LocalDatePattern.CreateWithCurrentCulture "yyyy-MM-dd").Format dt
|
|
| None -> ""
|
|
{ Id = theId
|
|
Title = listing.Title
|
|
ContinentId = ContinentId.toString listing.ContinentId
|
|
Region = listing.Region
|
|
RemoteWork = listing.IsRemote
|
|
Text = MarkdownString.toString listing.Text
|
|
NeededBy = neededBy
|
|
}
|
|
|
|
|
|
/// The data required to update a profile
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type EditProfileViewModel =
|
|
{ /// Whether the citizen to whom this profile belongs is actively seeking employment
|
|
IsSeekingEmployment : bool
|
|
|
|
/// The ID of the continent on which the citizen is located
|
|
ContinentId : string
|
|
|
|
/// The area within that continent where the citizen is located
|
|
Region : string
|
|
|
|
/// If the citizen is available for remote work
|
|
RemoteWork : bool
|
|
|
|
/// If the citizen is seeking full-time employment
|
|
FullTime : bool
|
|
|
|
/// The user's professional biography
|
|
Biography : string
|
|
|
|
/// The skills for the user
|
|
Skills : SkillForm array
|
|
|
|
/// The user's past experience
|
|
Experience : string option
|
|
|
|
/// Whether this profile should appear in the public search
|
|
IsPubliclySearchable : bool
|
|
|
|
/// Whether this profile should be shown publicly
|
|
IsPubliclyLinkable : bool
|
|
}
|
|
|
|
/// Support functions for the ProfileForm type
|
|
module EditProfileViewModel =
|
|
|
|
/// An empty view model (used for new profiles)
|
|
let empty =
|
|
{ IsSeekingEmployment = false
|
|
ContinentId = ""
|
|
Region = ""
|
|
RemoteWork = false
|
|
FullTime = false
|
|
Biography = ""
|
|
Skills = [||]
|
|
Experience = None
|
|
IsPubliclySearchable = false
|
|
IsPubliclyLinkable = false
|
|
}
|
|
|
|
/// Create an instance of this form from the given profile
|
|
let fromProfile (profile : Profile) =
|
|
{ IsSeekingEmployment = profile.IsSeekingEmployment
|
|
ContinentId = ContinentId.toString profile.ContinentId
|
|
Region = profile.Region
|
|
RemoteWork = profile.IsRemote
|
|
FullTime = profile.IsFullTime
|
|
Biography = MarkdownString.toString profile.Biography
|
|
Skills = profile.Skills |> List.map SkillForm.fromSkill |> Array.ofList
|
|
Experience = profile.Experience |> Option.map MarkdownString.toString
|
|
IsPubliclySearchable = profile.IsPubliclySearchable
|
|
IsPubliclyLinkable = profile.IsPubliclyLinkable
|
|
}
|
|
|
|
|
|
/// The data required to provide a success story
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type EditSuccessForm =
|
|
{ /// The ID of this success story
|
|
Id : string
|
|
|
|
/// Whether the employment was obtained from Jobs, Jobs, Jobs
|
|
FromHere : bool
|
|
|
|
/// The success story
|
|
Story : string
|
|
}
|
|
|
|
/// Support functions for success edit forms
|
|
module EditSuccessForm =
|
|
|
|
/// Create an edit form from a success story
|
|
let fromSuccess (success : Success) =
|
|
{ Id = SuccessId.toString success.Id
|
|
FromHere = success.IsFromHere
|
|
Story = success.Story |> Option.map MarkdownString.toString |> Option.defaultValue ""
|
|
}
|
|
|
|
|
|
/// The form submitted to expire a listing
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type ExpireListingForm =
|
|
{ /// The ID of the listing to expire
|
|
Id : string
|
|
|
|
/// Whether the job was filled from here
|
|
FromHere : bool
|
|
|
|
/// The success story written by the user
|
|
SuccessStory : string
|
|
}
|
|
|
|
|
|
/// View model for the log on page
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type LogOnViewModel =
|
|
{ /// A message regarding an error encountered during a log on attempt
|
|
ErrorMessage : string option
|
|
|
|
/// The e-mail address for the user attempting to log on
|
|
Email : string
|
|
|
|
/// The password of the user attempting to log on
|
|
Password : string
|
|
|
|
/// The URL where the user should be redirected after logging on
|
|
ReturnTo : string option
|
|
}
|
|
|
|
|
|
/// View model for the registration page
|
|
[<CLIMutable; NoComparison; NoEquality>]
|
|
type RegisterViewModel =
|
|
{ /// The user's first name
|
|
FirstName : string
|
|
|
|
/// The user's last name
|
|
LastName : string
|
|
|
|
/// The user's display name
|
|
DisplayName : string option
|
|
|
|
/// The user's e-mail address
|
|
Email : string
|
|
|
|
/// The user's desired password
|
|
Password : string
|
|
|
|
/// The index of the first question asked
|
|
Question1Index : int
|
|
|
|
/// The answer for the first question asked
|
|
Question1Answer : string
|
|
|
|
/// The index of the second question asked
|
|
Question2Index : int
|
|
|
|
/// The answer for the second question asked
|
|
Question2Answer : string
|
|
}
|
|
|
|
/// Support for the registration page view model
|
|
module RegisterViewModel =
|
|
|
|
/// An empty view model
|
|
let empty =
|
|
{ FirstName = ""
|
|
LastName = ""
|
|
DisplayName = None
|
|
Email = ""
|
|
Password = ""
|
|
Question1Index = 0
|
|
Question1Answer = ""
|
|
Question2Index = 0
|
|
Question2Answer = ""
|
|
}
|