Files
LeaJobTrackerWebApp/Desktop/hallo/LEA/Controllers/ApplicationsController.cs
younes elhaddoury bb13759af4 hallo
2025-09-17 10:28:02 +02:00

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.");
}
}