diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor
index bfa6ba2..74111df 100644
--- a/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor
+++ b/src/JobsJobsJobs/Client/Pages/Citizen/Dashboard.razor
@@ -25,7 +25,7 @@ else
@code {
bool retrievingProfile = true;
- Profile? profile = null;
+ JobsJobsJobs.Shared.Profile? profile = null;
string? errorMessage = null;
protected override async Task OnInitializedAsync()
diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor b/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor
new file mode 100644
index 0000000..1cabc54
--- /dev/null
+++ b/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor
@@ -0,0 +1,81 @@
+@page "/citizen/profile"
+@using JobsJobsJobs.Client.ViewModels
+@inject HttpClient http
+@inject AppState state
+
+
Employment Profile
+
+@if (errorMessage != "")
+{
+ @errorMessage
+}
+else if (profileForm != null)
+{
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+@code {
+
+ public JobsJobsJobs.Shared.Profile? profile = null;
+
+ public ProfileForm? profileForm = null;
+
+ public string errorMessage = "";
+
+ protected override async Task OnInitializedAsync()
+ {
+ var result = await ServerApi.RetrieveProfile(http, state);
+ if (result.IsOk)
+ {
+ profile = result.Ok;
+ profileForm = (profile == null) ? new ProfileForm() : ProfileForm.FromProfile(profile);
+ }
+ else
+ {
+ errorMessage = result.Error;
+ }
+ }
+
+ public void SaveProfile()
+ {
+ // TODO: save profile
+ }
+}
diff --git a/src/JobsJobsJobs/Client/ViewModels/ProfileForm.cs b/src/JobsJobsJobs/Client/ViewModels/ProfileForm.cs
new file mode 100644
index 0000000..fa6c19c
--- /dev/null
+++ b/src/JobsJobsJobs/Client/ViewModels/ProfileForm.cs
@@ -0,0 +1,70 @@
+using JobsJobsJobs.Shared;
+using System.ComponentModel.DataAnnotations;
+
+namespace JobsJobsJobs.Client.ViewModels
+{
+ ///
+ /// The data required to update a profile
+ ///
+ public class ProfileForm
+ {
+ ///
+ /// Whether the citizen to whom this profile belongs is actively seeking employment
+ ///
+ public bool IsSeekingEmployment { get; set; }
+
+ ///
+ /// Whether this profile should appear in the public search
+ ///
+ public bool IsPublic { get; set; }
+
+ ///
+ /// The ID of the continent on which the citizen is located
+ ///
+ [Required]
+ [StringLength(12, MinimumLength = 1)]
+ [Display(Name = "Continent")]
+ public string ContinentId { get; set; } = "";
+
+ ///
+ /// The area within that continent where the citizen is located
+ ///
+ [Required]
+ [StringLength(255)]
+ public string Region { get; set; } = "";
+
+ ///
+ /// If the citizen is available for remote work
+ ///
+ public bool RemoteWork { get; set; }
+
+ ///
+ /// If the citizen is seeking full-time employment
+ ///
+ public bool FullTime { get; set; }
+
+ ///
+ /// The user's professional biography
+ ///
+ [Required]
+ public string Biography { get; set; } = "";
+
+ ///
+ /// The user's past experience
+ ///
+ public string Experience { get; set; } = "";
+
+ public static ProfileForm FromProfile(Profile profile) =>
+ new ProfileForm
+ {
+ IsSeekingEmployment = profile.SeekingEmployment,
+ IsPublic = profile.IsPublic,
+ ContinentId = profile.ContinentId.ToString(),
+ Region = profile.Region,
+ RemoteWork = profile.RemoteWork,
+ FullTime = profile.FullTime,
+ Biography = profile.Biography.Text,
+ Experience = profile.Experience?.Text ?? ""
+ };
+ }
+}
diff --git a/src/JobsJobsJobs/Shared/Domain/ContinentId.cs b/src/JobsJobsJobs/Shared/Domain/ContinentId.cs
index c43c00c..59ea252 100644
--- a/src/JobsJobsJobs/Shared/Domain/ContinentId.cs
+++ b/src/JobsJobsJobs/Shared/Domain/ContinentId.cs
@@ -20,5 +20,7 @@ namespace JobsJobsJobs.Shared
/// The continent ID
/// If the string is not a valid continent ID
public static ContinentId Parse(string id) => new ContinentId(ShortId.Parse(id));
+
+ public override string ToString() => Id.ToString();
}
}