@@ -33,6 +33,7 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="db">The data context to use for this request</param>
|
||||
/// <param name="clock">The clock instance to use for this request</param>
|
||||
public ProfileController(JobsDbContext db, IClock clock)
|
||||
{
|
||||
_db = db;
|
||||
@@ -114,5 +115,20 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
||||
[HttpGet("search")]
|
||||
public async Task<IActionResult> Search([FromQuery] ProfileSearch search) =>
|
||||
Ok(await _db.SearchProfiles(search));
|
||||
|
||||
[HttpPatch("employment-found")]
|
||||
public async Task<IActionResult> EmploymentFound()
|
||||
{
|
||||
var profile = await _db.FindProfileByCitizen(CurrentCitizenId);
|
||||
if (profile == null) return NotFound();
|
||||
|
||||
var updated = profile with { SeekingEmployment = false };
|
||||
_db.Update(updated);
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using JobsJobsJobs.Server.Data;
|
||||
using JobsJobsJobs.Shared;
|
||||
using JobsJobsJobs.Shared.Api;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NodaTime;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// API controller for success stories
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class SuccessController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// The data context
|
||||
/// </summary>
|
||||
private readonly JobsDbContext _db;
|
||||
|
||||
/// <summary>
|
||||
/// The NodaTime clock instance
|
||||
/// </summary>
|
||||
private readonly IClock _clock;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="db">The data context to use for this request</param>
|
||||
/// <param name="clock">The clock instance to use for this request</param>
|
||||
public SuccessController(JobsDbContext db, IClock clock)
|
||||
{
|
||||
_db = db;
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current citizen ID
|
||||
/// </summary>
|
||||
private CitizenId CurrentCitizenId => CitizenId.Parse(User.FindFirst(ClaimTypes.NameIdentifier)!.Value);
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> Retrieve(string id) =>
|
||||
Ok(await _db.FindSuccessById(SuccessId.Parse(id)));
|
||||
|
||||
[HttpPost("save")]
|
||||
public async Task<IActionResult> Save([FromBody] StoryForm form)
|
||||
{
|
||||
if (form.Id == "new")
|
||||
{
|
||||
var story = new Success(await SuccessId.Create(), CurrentCitizenId, _clock.GetCurrentInstant(),
|
||||
form.FromHere, string.IsNullOrWhiteSpace(form.Story) ? null : new MarkdownString(form.Story));
|
||||
await _db.AddAsync(story);
|
||||
}
|
||||
else
|
||||
{
|
||||
var story = await _db.FindSuccessById(SuccessId.Parse(form.Id));
|
||||
if (story == null) return NotFound();
|
||||
var updated = story with
|
||||
{
|
||||
FromHere = form.FromHere,
|
||||
Story = string.IsNullOrWhiteSpace(form.Story) ? null : new MarkdownString(form.Story)
|
||||
};
|
||||
_db.Update(updated);
|
||||
}
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet("list")]
|
||||
public async Task<IActionResult> List() =>
|
||||
Ok(await _db.AllStories());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
using JobsJobsJobs.Shared;
|
||||
using JobsJobsJobs.Shared.Api;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Server.Data
|
||||
|
||||
34
src/JobsJobsJobs/Server/Data/SuccessExtensions.cs
Normal file
34
src/JobsJobsJobs/Server/Data/SuccessExtensions.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using JobsJobsJobs.Shared;
|
||||
using JobsJobsJobs.Shared.Api;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Server.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions to JobsDbContext to support manipulation of success stories
|
||||
/// </summary>
|
||||
public static class SuccessExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a success story by its ID
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the story to retrieve</param>
|
||||
/// <returns>The success story, if found</returns>
|
||||
public static async Task<Success?> FindSuccessById(this JobsDbContext db, SuccessId id) =>
|
||||
await db.Successes.AsNoTracking().SingleOrDefaultAsync(s => s.Id == id).ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of success stories, with the information needed for the list page
|
||||
/// </summary>
|
||||
/// <returns>A list of success stories, citizen names, and dates</returns>
|
||||
public static async Task<IEnumerable<StoryEntry>> AllStories(this JobsDbContext db) =>
|
||||
await db.Successes
|
||||
.Join(db.Citizens, s => s.CitizenId, c => c.Id, (s, c) => new { Success = s, Citizen = c })
|
||||
.OrderByDescending(it => it.Success.RecordedOn)
|
||||
.Select(it => new StoryEntry(it.Success.Id, it.Citizen.Id, it.Citizen.DisplayName, it.Success.RecordedOn))
|
||||
.ToListAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user