290 lines
9.5 KiB
C#
290 lines
9.5 KiB
C#
using LEA.Data;
|
|
using LEA.Extensions;
|
|
using LEA.Models;
|
|
using LEA.ViewModels;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace LEA.Controllers;
|
|
|
|
[Authorize]
|
|
public class ApplicationsController : Controller
|
|
{
|
|
private readonly AppDbContext _context;
|
|
private readonly UserManager<ApplicationUser> _userManager;
|
|
|
|
public ApplicationsController(AppDbContext context, UserManager<ApplicationUser> userManager)
|
|
{
|
|
_context = context;
|
|
_userManager = userManager;
|
|
}
|
|
|
|
public async Task<IActionResult> Index(string? searchTerm, ApplicationStatus? status)
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
var query = _context.Applications
|
|
.Include(a => a.Contact)
|
|
.Where(a => a.UserId == userId);
|
|
|
|
if (!string.IsNullOrWhiteSpace(searchTerm))
|
|
{
|
|
var term = $"%{searchTerm.Trim()}%";
|
|
query = query.Where(a =>
|
|
EF.Functions.Like(a.Company, term) ||
|
|
EF.Functions.Like(a.Role, term) ||
|
|
EF.Functions.Like(a.Source ?? string.Empty, term) ||
|
|
EF.Functions.Like(a.Notes ?? string.Empty, term) ||
|
|
(a.Contact != null && (
|
|
EF.Functions.Like(a.Contact.FullName ?? string.Empty, term) ||
|
|
EF.Functions.Like(a.Contact.Email ?? string.Empty, term))));
|
|
}
|
|
|
|
if (status.HasValue)
|
|
{
|
|
query = query.Where(a => a.Status == status.Value);
|
|
}
|
|
|
|
var applications = await query
|
|
.OrderByDescending(a => a.UpdatedAt)
|
|
.ThenByDescending(a => a.AppliedOn)
|
|
.ToListAsync();
|
|
|
|
var statsQuery = _context.Applications.Where(a => a.UserId == userId);
|
|
var statusCounts = await statsQuery
|
|
.GroupBy(a => a.Status)
|
|
.Select(g => new { g.Key, Count = g.Count() })
|
|
.ToListAsync();
|
|
|
|
var statusDictionary = Enum.GetValues<ApplicationStatus>()
|
|
.ToDictionary(s => s, s => statusCounts.FirstOrDefault(sc => sc.Key == s)?.Count ?? 0);
|
|
|
|
var model = new ApplicationListViewModel
|
|
{
|
|
Applications = applications,
|
|
SearchTerm = searchTerm,
|
|
StatusFilter = status,
|
|
StatusOptions = GetStatusSelectList(status, includeAllOption: true),
|
|
StatusCounts = statusDictionary,
|
|
TotalApplications = await statsQuery.CountAsync()
|
|
};
|
|
|
|
return View(model);
|
|
}
|
|
|
|
[HttpGet]
|
|
public IActionResult Create()
|
|
{
|
|
var model = new ApplicationFormViewModel
|
|
{
|
|
AppliedOn = DateTime.Today,
|
|
Status = ApplicationStatus.Applied,
|
|
StatusOptions = GetStatusSelectList(ApplicationStatus.Applied),
|
|
Heading = "Bewerbung hinzufügen",
|
|
SubmitText = "Speichern"
|
|
};
|
|
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Create(ApplicationFormViewModel model)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
model.StatusOptions = GetStatusSelectList(model.Status);
|
|
model.Heading = "Bewerbung hinzufügen";
|
|
model.SubmitText = "Speichern";
|
|
return View(model);
|
|
}
|
|
|
|
var application = new Application
|
|
{
|
|
Role = model.Role.Trim(),
|
|
Company = model.Company.Trim(),
|
|
Source = string.IsNullOrWhiteSpace(model.Source) ? null : model.Source.Trim(),
|
|
Status = model.Status,
|
|
AppliedOn = model.AppliedOn,
|
|
Notes = string.IsNullOrWhiteSpace(model.Notes) ? null : model.Notes.Trim(),
|
|
UserId = GetCurrentUserId(),
|
|
UpdatedAt = DateTime.UtcNow
|
|
};
|
|
|
|
if (HasContactInformation(model))
|
|
{
|
|
application.Contact = new Contact
|
|
{
|
|
FullName = string.IsNullOrWhiteSpace(model.ContactName) ? null : model.ContactName.Trim(),
|
|
Email = string.IsNullOrWhiteSpace(model.ContactEmail) ? null : model.ContactEmail.Trim(),
|
|
Phone = string.IsNullOrWhiteSpace(model.ContactPhone) ? null : model.ContactPhone.Trim()
|
|
};
|
|
}
|
|
|
|
_context.Applications.Add(application);
|
|
await _context.SaveChangesAsync();
|
|
|
|
TempData["Success"] = "Die Bewerbung wurde gespeichert.";
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<IActionResult> Edit(int id)
|
|
{
|
|
var application = await FindApplicationForCurrentUserAsync(id);
|
|
if (application == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
var model = new ApplicationFormViewModel
|
|
{
|
|
Id = application.Id,
|
|
Role = application.Role,
|
|
Company = application.Company,
|
|
Source = application.Source,
|
|
Status = application.Status,
|
|
AppliedOn = application.AppliedOn,
|
|
Notes = application.Notes,
|
|
ContactName = application.Contact?.FullName,
|
|
ContactEmail = application.Contact?.Email,
|
|
ContactPhone = application.Contact?.Phone,
|
|
StatusOptions = GetStatusSelectList(application.Status),
|
|
Heading = "Bewerbung bearbeiten",
|
|
SubmitText = "Änderungen speichern"
|
|
};
|
|
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Edit(int id, ApplicationFormViewModel model)
|
|
{
|
|
if (id != model.Id)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
model.StatusOptions = GetStatusSelectList(model.Status);
|
|
model.Heading = "Bewerbung bearbeiten";
|
|
model.SubmitText = "Änderungen speichern";
|
|
return View(model);
|
|
}
|
|
|
|
var application = await FindApplicationForCurrentUserAsync(id);
|
|
if (application == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
application.Role = model.Role.Trim();
|
|
application.Company = model.Company.Trim();
|
|
application.Source = string.IsNullOrWhiteSpace(model.Source) ? null : model.Source.Trim();
|
|
application.Status = model.Status;
|
|
application.AppliedOn = model.AppliedOn;
|
|
application.Notes = string.IsNullOrWhiteSpace(model.Notes) ? null : model.Notes.Trim();
|
|
application.UpdatedAt = DateTime.UtcNow;
|
|
|
|
if (HasContactInformation(model))
|
|
{
|
|
if (application.Contact == null)
|
|
{
|
|
application.Contact = new Contact();
|
|
}
|
|
|
|
application.Contact.FullName = string.IsNullOrWhiteSpace(model.ContactName) ? null : model.ContactName.Trim();
|
|
application.Contact.Email = string.IsNullOrWhiteSpace(model.ContactEmail) ? null : model.ContactEmail.Trim();
|
|
application.Contact.Phone = string.IsNullOrWhiteSpace(model.ContactPhone) ? null : model.ContactPhone.Trim();
|
|
}
|
|
else if (application.Contact != null)
|
|
{
|
|
_context.Contacts.Remove(application.Contact);
|
|
}
|
|
|
|
await _context.SaveChangesAsync();
|
|
|
|
TempData["Success"] = "Die Bewerbung wurde aktualisiert.";
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<IActionResult> Details(int id)
|
|
{
|
|
var application = await FindApplicationForCurrentUserAsync(id);
|
|
if (application == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
return View(application);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Delete(int id)
|
|
{
|
|
var application = await FindApplicationForCurrentUserAsync(id);
|
|
if (application == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
_context.Applications.Remove(application);
|
|
await _context.SaveChangesAsync();
|
|
|
|
TempData["Success"] = "Die Bewerbung wurde gelöscht.";
|
|
return RedirectToAction(nameof(Index));
|
|
}
|
|
|
|
private async Task<Application?> FindApplicationForCurrentUserAsync(int id)
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
return await _context.Applications
|
|
.Include(a => a.Contact)
|
|
.Where(a => a.UserId == userId)
|
|
.FirstOrDefaultAsync(a => a.Id == id);
|
|
}
|
|
|
|
private IEnumerable<SelectListItem> GetStatusSelectList(ApplicationStatus? selectedStatus, bool includeAllOption = false)
|
|
{
|
|
var options = Enum.GetValues<ApplicationStatus>()
|
|
.Select(status => new SelectListItem
|
|
{
|
|
Text = status.GetDisplayName(),
|
|
Value = status.ToString(),
|
|
Selected = selectedStatus.HasValue && selectedStatus.Value == status
|
|
})
|
|
.ToList();
|
|
|
|
if (includeAllOption)
|
|
{
|
|
options.Insert(0, new SelectListItem
|
|
{
|
|
Text = "Alle Status",
|
|
Value = string.Empty,
|
|
Selected = !selectedStatus.HasValue
|
|
});
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
private bool HasContactInformation(ApplicationFormViewModel model)
|
|
{
|
|
return !string.IsNullOrWhiteSpace(model.ContactName)
|
|
|| !string.IsNullOrWhiteSpace(model.ContactEmail)
|
|
|| !string.IsNullOrWhiteSpace(model.ContactPhone);
|
|
}
|
|
|
|
private string GetCurrentUserId()
|
|
{
|
|
return _userManager.GetUserId(User)
|
|
?? throw new InvalidOperationException("Benutzer ist nicht angemeldet.");
|
|
}
|
|
}
|