using JobsJobsJobs.Server.Data; using JobsJobsJobs.Shared; using JobsJobsJobs.Shared.Api; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using NodaTime; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; namespace JobsJobsJobs.Server.Areas.Api.Controllers { /// /// API controller for employment profile information /// [Route("api/[controller]")] [Authorize] [ApiController] public class ProfileController : ControllerBase { /// /// The data context /// private readonly JobsDbContext _db; /// /// The NodaTime clock instance /// private readonly IClock _clock; /// /// Constructor /// /// The data context to use for this request public ProfileController(JobsDbContext db, IClock clock) { _db = db; _clock = clock; } /// /// The current citizen ID /// private CitizenId CurrentCitizenId => CitizenId.Parse(User.FindFirst(ClaimTypes.NameIdentifier)!.Value); // This returns 204 to indicate that there is no profile data for the current citizen (if, of course, that is // the case. The version where an ID is specified returns 404, which is an error condition, as it should not // occur unless someone is messing with a URL. [HttpGet("")] public async Task Get() { var profile = await _db.FindProfileByCitizen(CurrentCitizenId); return profile == null ? NoContent() : Ok(profile); } [HttpPost("save")] public async Task Save(ProfileForm form) { // Profile var existing = await _db.FindProfileByCitizen(CurrentCitizenId); var profile = existing == null ? new Profile(CurrentCitizenId, form.IsSeekingEmployment, form.IsPublic, ContinentId.Parse(form.ContinentId), form.Region, form.RemoteWork, form.FullTime, new MarkdownString(form.Biography), _clock.GetCurrentInstant(), string.IsNullOrEmpty(form.Experience) ? null : new MarkdownString(form.Experience)) : existing with { SeekingEmployment = form.IsSeekingEmployment, IsPublic = form.IsPublic, ContinentId = ContinentId.Parse(form.ContinentId), Region = form.Region, RemoteWork = form.RemoteWork, FullTime = form.FullTime, Biography = new MarkdownString(form.Biography), LastUpdatedOn = _clock.GetCurrentInstant(), Experience = string.IsNullOrEmpty(form.Experience) ? null : new MarkdownString(form.Experience) }; await _db.SaveProfile(profile); // Skills var skills = new List(); foreach (var skill in form.Skills) { skills.Add(new Skill(skill.Id.StartsWith("new") ? await SkillId.Create() : SkillId.Parse(skill.Id), CurrentCitizenId, skill.Description, string.IsNullOrEmpty(skill.Notes) ? null : skill.Notes)); } foreach (var skill in skills) await _db.SaveSkill(skill); await _db.DeleteMissingSkills(CurrentCitizenId, skills.Select(s => s.Id)); await _db.SaveChangesAsync(); return Ok(); } [HttpGet("skills")] public async Task GetSkills() => Ok(await _db.FindSkillsByCitizen(CurrentCitizenId)); [HttpGet("count")] public async Task GetProfileCount() => Ok(new Count(await _db.CountProfiles())); [HttpGet("skill-count")] public async Task GetSkillCount() => Ok(new Count(await _db.CountSkillsByCitizen(CurrentCitizenId))); [HttpGet("get/{id}")] public async Task GetProfileForCitizen([FromRoute] string id) { var profile = await _db.FindProfileByCitizen(CitizenId.Parse(id)); return profile == null ? NotFound() : Ok(profile); } [HttpGet("search")] public async Task Search() { return Ok(await _db.SearchProfiles()); } } }