57
src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor
Normal file
57
src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor
Normal file
@@ -0,0 +1,57 @@
|
||||
@page "/success-story/add"
|
||||
@page "/success-story/edit/{Id}"
|
||||
@inject HttpClient http
|
||||
@inject AppState state
|
||||
@inject NavigationManager nav
|
||||
@inject IToastService toast
|
||||
|
||||
<PageTitle Title=@Title />
|
||||
|
||||
<h3>@Title</h3>
|
||||
|
||||
<ErrorList Errors=@ErrorMessages>
|
||||
@if (Loading)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (IsNew)
|
||||
{
|
||||
<p>
|
||||
Congratulations on your employment! Your fellow citizens would enjoy hearing how it all came about; tell us
|
||||
about it below! <em>(These will be visible to other users, but not to the general public.)</em>
|
||||
</p>
|
||||
}
|
||||
<EditForm Model=@Form OnValidSubmit=@SaveStory>
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<div class="form-check">
|
||||
<InputCheckbox id="fromHere" class="form-check-input" @bind-Value=@Form.FromHere />
|
||||
<label for="fromHere" class="form-check-label">I found my employment here</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label for="story" class="jjj-label">The Success Story</label>
|
||||
<MarkdownEditor Id="story" @bind-Text=@Form.Story />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<br>
|
||||
<button type="submit" class="btn btn-outline-primary">Save</button>
|
||||
@if (IsNew)
|
||||
{
|
||||
<p>
|
||||
<em>(Saving this will set “Seeking Employment” to “No” on your profile.)</em>
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
}
|
||||
</ErrorList>
|
||||
124
src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs
Normal file
124
src/JobsJobsJobs/Client/Pages/SuccessStory/EditStory.razor.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using JobsJobsJobs.Shared;
|
||||
using JobsJobsJobs.Shared.Api;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Client.Pages.SuccessStory
|
||||
{
|
||||
public partial class EditStory : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the success story being edited
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether we are loading information
|
||||
/// </summary>
|
||||
private bool Loading { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// The page title / header
|
||||
/// </summary>
|
||||
public string Title => IsNew ? "Tell Your Success Story" : "Edit Success Story";
|
||||
|
||||
/// <summary>
|
||||
/// The form with information for the success story
|
||||
/// </summary>
|
||||
private StoryForm Form { get; set; } = new StoryForm();
|
||||
|
||||
/// <summary>
|
||||
/// Convenience property for showing new
|
||||
/// </summary>
|
||||
private bool IsNew => Form.Id == "new";
|
||||
|
||||
/// <summary>
|
||||
/// Error messages from API access
|
||||
/// </summary>
|
||||
private IList<string> ErrorMessages { get; } = new List<string>();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (Id != null)
|
||||
{
|
||||
ServerApi.SetJwt(http, state);
|
||||
var story = await ServerApi.RetrieveOne<Success>(http, $"success/{Id}");
|
||||
if (story.IsOk && story.Ok != null)
|
||||
{
|
||||
Form = new StoryForm
|
||||
{
|
||||
Id = story.Ok.Id.ToString(),
|
||||
FromHere = story.Ok.FromHere,
|
||||
Story = story.Ok.Story?.Text ?? ""
|
||||
};
|
||||
}
|
||||
else if (story.IsOk)
|
||||
{
|
||||
ErrorMessages.Add($"The success story {Id} does not exist");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorMessages.Add(story.Error);
|
||||
}
|
||||
}
|
||||
Loading = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the success story
|
||||
/// </summary>
|
||||
private async Task SaveStory()
|
||||
{
|
||||
ServerApi.SetJwt(http, state);
|
||||
var res = await http.PostAsJsonAsync("/api/success/save", Form);
|
||||
|
||||
if (res.IsSuccessStatusCode)
|
||||
{
|
||||
if (IsNew)
|
||||
{
|
||||
res = await http.PatchAsync("/api/profile/employment-found", new StringContent(""));
|
||||
if (res.IsSuccessStatusCode)
|
||||
{
|
||||
SaveSuccessful();
|
||||
}
|
||||
else
|
||||
{
|
||||
await SaveFailed(res);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveSuccessful();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await SaveFailed(res);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle success notifications if saving succeeded
|
||||
/// </summary>
|
||||
private void SaveSuccessful()
|
||||
{
|
||||
toast.ShowSuccess("Story Saved Successfully");
|
||||
nav.NavigateTo("/success-story/list");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle failure notifications is saving was not successful
|
||||
/// </summary>
|
||||
/// <param name="res">The HTTP response</param>
|
||||
private async Task SaveFailed(HttpResponseMessage res)
|
||||
{
|
||||
var error = await res.Content.ReadAsStringAsync();
|
||||
if (!string.IsNullOrEmpty(error)) error = $"- {error}";
|
||||
toast.ShowError($"{(int)res.StatusCode} {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor
Normal file
46
src/JobsJobsJobs/Client/Pages/SuccessStory/ListStories.razor
Normal file
@@ -0,0 +1,46 @@
|
||||
@page "/success-story/list"
|
||||
@inject HttpClient http
|
||||
@inject AppState state
|
||||
|
||||
<PageTitle Title="Success Stories" />
|
||||
|
||||
<h3>Success Stories</h3>
|
||||
|
||||
<ErrorList Errors=@ErrorMessages>
|
||||
@if (Loading)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else if (Stories.Any())
|
||||
{
|
||||
<table class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Story</th>
|
||||
<th scope="col">From</th>
|
||||
<th scope="col">Recorded On</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var story in Stories)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/success-story/view/@story.Id">View</a>
|
||||
@if (story.CitizenId == state.User!.Id)
|
||||
{
|
||||
<text> ~ <a href="/success-story/edit/@story.Id">Edit</a></text>
|
||||
}
|
||||
</td>
|
||||
<td>@story.CitizenName</td>
|
||||
<td><FullDate TheDate=@story.RecordedOn /></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>There are no success stories recorded <em>(yet)</em></p>
|
||||
}
|
||||
</ErrorList>
|
||||
@@ -0,0 +1,44 @@
|
||||
using JobsJobsJobs.Shared.Api;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Client.Pages.SuccessStory
|
||||
{
|
||||
public partial class ListStories : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether we are still loading data
|
||||
/// </summary>
|
||||
private bool Loading { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// The story entries
|
||||
/// </summary>
|
||||
private IEnumerable<StoryEntry> Stories { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Error messages encountered
|
||||
/// </summary>
|
||||
private IList<string> ErrorMessages { get; set; } = new List<string>();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ServerApi.SetJwt(http, state);
|
||||
var stories = await ServerApi.RetrieveMany<StoryEntry>(http, "success/list");
|
||||
|
||||
if (stories.IsOk)
|
||||
{
|
||||
Stories = stories.Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorMessages.Add(stories.Error);
|
||||
}
|
||||
|
||||
Loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user