diff --git a/TourismApp/Controllers/AccountController.cs b/TourismApp/Controllers/AccountController.cs index 400088a..6461b8e 100644 --- a/TourismApp/Controllers/AccountController.cs +++ b/TourismApp/Controllers/AccountController.cs @@ -32,7 +32,7 @@ public AccountController( // ========================== [HttpGet] - public IActionResult Login(string returnUrl = null) + public IActionResult Login(string? returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); @@ -40,7 +40,7 @@ public IActionResult Login(string returnUrl = null) [HttpPost] [ValidateAntiForgeryToken] - public async Task Login(LoginViewModel model, string returnUrl = null) + public async Task Login(LoginViewModel model, string? returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; if (!ModelState.IsValid) return View(model); @@ -53,7 +53,7 @@ public async Task Login(LoginViewModel model, string returnUrl = } var result = await _signInManager.PasswordSignInAsync( - user.UserName, model.Password, model.RememberMe, lockoutOnFailure: false); + user.UserName!, model.Password, model.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { @@ -63,7 +63,6 @@ public async Task Login(LoginViewModel model, string returnUrl = if (!hasPreferences) { - return RedirectToAction("Index", "Preferences"); } @@ -106,7 +105,8 @@ public async Task Register(RegisterViewModel model) var pending = await _dbContext.PendingUsers.FirstOrDefaultAsync(u => u.Email == model.Email); var passwordHasher = new PasswordHasher(); - var passwordHash = passwordHasher.HashPassword(null, model.Password); + + var passwordHash = passwordHasher.HashPassword(null!, model.Password); var token = Guid.NewGuid().ToString(); if (pending != null) @@ -174,7 +174,7 @@ public async Task ConfirmPendingUser(string token, string email) Email = pendingUser.Email, UserName = pendingUser.Email, EmailConfirmed = true, - PasswordHash = pendingUser.PasswordHash + PasswordHash = pendingUser.PasswordHash }; var result = await _userManager.CreateAsync(user); @@ -212,7 +212,7 @@ public async Task VerifyEmail(VerifyEmailViewModel model) var resetLink = Url.Action("ChangePassword", "Account", new { email = user.Email, token = token }, Request.Scheme); string message = $"

Click here to reset your password: Reset Password

"; - await _emailService.SendEmailAsync(user.Email, "Password Reset Request", message); + await _emailService.SendEmailAsync(user.Email!, "Password Reset Request", message); return RedirectToAction("VerifyEmailSent"); } @@ -230,7 +230,11 @@ public IActionResult ChangePassword(string token, string email) { ModelState.AddModelError("", "Invalid password reset token."); } - return View(new ChangePasswordViewModel { Token = token, Email = email }); + return View(new ChangePasswordViewModel + { + Token = token ?? string.Empty, + Email = email ?? string.Empty + }); } [HttpPost] diff --git a/TourismApp/Controllers/ExploreController.cs b/TourismApp/Controllers/ExploreController.cs index a7f7426..2ec0f67 100644 --- a/TourismApp/Controllers/ExploreController.cs +++ b/TourismApp/Controllers/ExploreController.cs @@ -24,20 +24,20 @@ public ExploreController(RankingService rankingService, _exploreService = exploreService; } - public async Task Index(string section = "poi", string category = null, string q = null, string eventCategory = null, string date = null, string sort = null) + public async Task Index(string section = "poi", string? category = null, string? q = null, string? eventCategory = null, string? date = null, string? sort = null) { var userId = _userManager.GetUserId(User); var viewModel = new ExploreViewModel { Section = section, - Category = category, - Query = q + Category = category ?? string.Empty, + Query = q ?? string.Empty }; if (section == "poi") { - var pois = await _rankingService.GetPersonalizedFeedAsync(userId); + var pois = await _rankingService.GetPersonalizedFeedAsync(userId ?? string.Empty); if (!string.IsNullOrEmpty(category)) { @@ -46,10 +46,9 @@ public async Task Index(string section = "poi", string category = if (!string.IsNullOrEmpty(q)) { - pois = pois.Where(p => p.Name.Contains(q, System.StringComparison.OrdinalIgnoreCase)).ToList(); + pois = pois.Where(p => p.Name != null && p.Name.Contains(q, System.StringComparison.OrdinalIgnoreCase)).ToList(); } - if (!string.IsNullOrWhiteSpace(sort)) { switch (sort) @@ -67,22 +66,21 @@ public async Task Index(string section = "poi", string category = viewModel.PointsOfInterest = pois; } - else { if (section == "news") { - viewModel.News = await _exploreService.GetNewsAsync(q); + viewModel.News = await _exploreService.GetNewsAsync(q ?? string.Empty); } if (section == "events") { - viewModel.Events = await _exploreService.GetEventsAsync(q, eventCategory, date); + viewModel.Events = await _exploreService.GetEventsAsync(q ?? string.Empty, eventCategory ?? string.Empty, date ?? string.Empty); } if (section == "municipalities") { - viewModel.MunicipalitiesList = await _exploreService.GetMunicipalitiesAsync(q); + viewModel.MunicipalitiesList = await _exploreService.GetMunicipalitiesAsync(q ?? string.Empty); } } diff --git a/TourismApp/Models/Municipality.cs b/TourismApp/Models/Municipality.cs index c64da4d..33029fb 100644 --- a/TourismApp/Models/Municipality.cs +++ b/TourismApp/Models/Municipality.cs @@ -1,8 +1,6 @@ using Microsoft.Extensions.Logging; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations; - namespace TourismApp.Models { public class Municipality @@ -11,7 +9,8 @@ public class Municipality public int Id { get; set; } [Required] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; + public string? ImageUrl { get; set; } public ICollection PointsOfInterest { get; set; } = new List(); diff --git a/TourismApp/Program.cs b/TourismApp/Program.cs index 49690a8..c26cd44 100644 --- a/TourismApp/Program.cs +++ b/TourismApp/Program.cs @@ -14,7 +14,7 @@ builder.Services.AddControllersWithViews(); // Add Razor Pages support (ESSENZIALE per Login/Logout/Identity) -builder.Services.AddRazorPages(); // <--- MANCAVA QUESTO! +builder.Services.AddRazorPages(); // Register HTTP Client for external API calls (e.g., Open Data) builder.Services.AddHttpClient(); @@ -124,6 +124,6 @@ pattern: "{controller=Home}/{action=Index}/{id?}"); // Rotta per le Razor Pages (Login, Register, Logout) -app.MapRazorPages(); // <--- MANCAVA QUESTO! +app.MapRazorPages(); app.Run(); \ No newline at end of file diff --git a/TourismApp/TourismApp.csproj b/TourismApp/TourismApp.csproj index 2343a56..225b628 100644 --- a/TourismApp/TourismApp.csproj +++ b/TourismApp/TourismApp.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + aa10327e-0ddb-4f9f-8ef3-af1cb0c3afc5 diff --git a/TourismApp/ViewModels/RegisterViewModel.cs b/TourismApp/ViewModels/RegisterViewModel.cs index 0eaf138..b25be94 100644 --- a/TourismApp/ViewModels/RegisterViewModel.cs +++ b/TourismApp/ViewModels/RegisterViewModel.cs @@ -2,40 +2,39 @@ namespace TourismApp.ViewModels { - public class RegisterViewModel { [Required(ErrorMessage = "Name is required")] - [StringLength(50, ErrorMessage = "Name cannot exceed 50 characters.")] + [StringLength(50, ErrorMessage = "Name cannot exceed 50 characters.")] [Display(Name = "Name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [Required(ErrorMessage = "Surname is required")] [StringLength(50, ErrorMessage = "Surname cannot exceed 50 characters.")] [Display(Name = "Surname")] - public string Surname { get; set; } + public string Surname { get; set; } = string.Empty; [Required(ErrorMessage = "Date of birth is required")] [DataType(DataType.Date)] - [Display(Name = "Date of Birth")] - public DateTime DateOfBirth { get; set; } + [Display(Name = "Date of Birth")] + public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Email is required")] [EmailAddress(ErrorMessage = "Please enter a valid email address")] [StringLength(100)] [Display(Name = "Email")] - public string Email { get; set; } + public string Email { get; set; } = string.Empty; [Required(ErrorMessage = "Password is required")] [DataType(DataType.Password)] [Display(Name = "Set Password")] [RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$", ErrorMessage = "Your password must contain at least 1 lowercase letter, 1 uppercase letter, 1 number, and be at least 8 characters long.")] - public string Password { get; set; } + public string Password { get; set; } = string.Empty; [DataType(DataType.Password)] [Display(Name = "Confirm Password")] [Compare("Password", ErrorMessage = "The password and password confirmation do not match.")] - public string ConfirmPassword { get; set; } + public string ConfirmPassword { get; set; } = string.Empty; } } \ No newline at end of file diff --git a/TourismApp/ViewModels/VerifyEmailViewModel.cs b/TourismApp/ViewModels/VerifyEmailViewModel.cs index ae904e5..edab574 100644 --- a/TourismApp/ViewModels/VerifyEmailViewModel.cs +++ b/TourismApp/ViewModels/VerifyEmailViewModel.cs @@ -6,6 +6,6 @@ public class VerifyEmailViewModel { [Required(ErrorMessage = "Email is required.")] [EmailAddress] - public string Email { get; set; } + public string Email { get; set; } = string.Empty; } -} +} \ No newline at end of file diff --git a/TourismApp/appsettings.json b/TourismApp/appsettings.json index 55d6665..726b3d7 100644 --- a/TourismApp/appsettings.json +++ b/TourismApp/appsettings.json @@ -17,8 +17,8 @@ "EmailSettings": { "SmtpServer": "smtp.gmail.com", "Port": "587", - "SenderEmail": "dfrgroup3@gmail.com", - "SenderPassword": "ifiq lkiv wdak tmlm" + "SenderEmail": "", + "SenderPassword": "" } } diff --git a/storico_commit.txt b/storico_commit.txt new file mode 100644 index 0000000..293eead Binary files /dev/null and b/storico_commit.txt differ