diff --git a/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor b/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor
index b45220f..d5e5cbd 100644
--- a/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor
+++ b/src/JobsJobsJobs/Client/Pages/Citizen/Profile.razor
@@ -69,7 +69,7 @@ else if (profileForm != null)
-
+
@@ -77,12 +77,13 @@ else if (profileForm != null)
diff --git a/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor
new file mode 100644
index 0000000..8c23edb
--- /dev/null
+++ b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor
@@ -0,0 +1,15 @@
+
+@if (_showPreview)
+{
+
+}
+else
+{
+
+}
diff --git a/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.cs b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.cs
new file mode 100644
index 0000000..0b57c80
--- /dev/null
+++ b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.cs
@@ -0,0 +1,88 @@
+using Markdig;
+using Microsoft.AspNetCore.Components;
+
+namespace JobsJobsJobs.Client.Shared
+{
+ ///
+ /// Code-behind for the Markdown Editor component
+ ///
+ public partial class MarkdownEditor : ComponentBase
+ {
+ ///
+ /// Pipeline with most extensions enabled
+ ///
+ private readonly MarkdownPipeline _pipeline = new MarkdownPipelineBuilder()
+ .UseSmartyPants().UseAdvancedExtensions().Build();
+
+ ///
+ /// Whether the preview should be shown
+ ///
+ private bool _showPreview = false;
+
+ ///
+ /// Backing field for the plain-text representation of this document
+ ///
+ private string _text = "";
+
+ ///
+ /// The plain-text (Markdown source)
+ ///
+ private string PlainText {
+ get => _text;
+ set
+ {
+ _text = value;
+ TextChanged.InvokeAsync(_text).ConfigureAwait(false).GetAwaiter().GetResult();
+ }
+ }
+
+ ///
+ /// The rendered HTML
+ ///
+ private MarkupString PreviewText => (MarkupString)Markdown.ToHtml(_text, _pipeline);
+
+ ///
+ /// CSS class for the "Markdown" tab (active if preview not shown)
+ ///
+ private string MarkdownClass => _showPreview ? "" : "active";
+
+ ///
+ /// CSS class for the "Preview" tab (active if preview shown)
+ ///
+ private string PreviewClass => _showPreview ? "active" : "";
+
+ ///
+ /// The ID used for the textarea; allows for a label to be assigned
+ ///
+ [Parameter]
+ public string Id { get; set; } = "";
+
+ ///
+ /// The text value of the Markdown
+ ///
+ [Parameter]
+ public string Text { get; set; } = "";
+
+ ///
+ /// Event fired when the text is changed
+ ///
+ [Parameter]
+ public EventCallback TextChanged { get; set; }
+
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ _text = Text;
+ }
+
+ ///
+ /// Show the Markdown editor
+ ///
+ private void ShowMarkdown() => _showPreview = false;
+
+ ///
+ /// Show the Markdown preview
+ ///
+ private void ShowPreview() => _showPreview = true;
+ }
+}
diff --git a/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.css b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.css
new file mode 100644
index 0000000..6ab1dc2
--- /dev/null
+++ b/src/JobsJobsJobs/Client/Shared/MarkdownEditor.razor.css
@@ -0,0 +1,4 @@
+section.preview {
+ border: solid 1px darkgray;
+ border-radius: 2rem;
+}