diff --git a/DataAccess/InstitutionDAO.cs b/DataAccess/InstitutionDAO.cs new file mode 100644 index 0000000..eb3c202 --- /dev/null +++ b/DataAccess/InstitutionDAO.cs @@ -0,0 +1,96 @@ +using Microsoft.EntityFrameworkCore; +using ObjectBusiness; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DataAccess +{ + public class InstitutionDAO + { + #region Variables + private readonly BackToMeDbContext db; + #endregion + + #region Constructor + public InstitutionDAO(BackToMeDbContext db) + { + this.db = db; + } + #endregion + + #region Create Institution + public async Task CreateInstitution(Institution institution) + { + institution.InstitutionId = new Random().Next(); + var isAdded = db.Institutions.Add(institution); + if (isAdded != null) + { + await db.SaveChangesAsync(); + return true; + } + return false; + } + #endregion + + #region All Institutions + public IQueryable AllInstitutions() + { + var listUsers = db.Institutions.AsNoTracking() + .OrderByDescending(u => u.InstitutionName); + + return listUsers; + } + #endregion + + #region Get Institution By Name + public async Task GetInstitutionByNameAndAddress(string institutionName, string institutionAddress) + { + if (string.IsNullOrWhiteSpace(institutionName)) + { + return null; + } + + institutionName = institutionName.Trim(); + institutionAddress = institutionAddress.Trim(); + + var institution = await db.Institutions.AsNoTracking() + .FirstOrDefaultAsync(i => i.InstitutionName.Contains(institutionName) && + i.InstitutionAddress.Contains(institutionAddress)); + return institution; + } + #endregion + + #region Get Institution By ID + public async Task GetInstitutionByID(int institutionId) + { + var institution = await db.Institutions.FirstOrDefaultAsync(u => u.InstitutionId == institutionId); + return institution; + } + #endregion + + #region Update Institution + public async Task UpdateInstitution() + { + try + { + await db.SaveChangesAsync(); + return true; + } + catch (Exception ex) + { + return false; + } + } + #endregion + + #region Delete Institution + public async Task DeleteInstitution(int institutionId) + { + return false; + } + #endregion + } +} diff --git a/LostFound_API/Controllers/InstitutionController.cs b/LostFound_API/Controllers/InstitutionController.cs new file mode 100644 index 0000000..e46b4d7 --- /dev/null +++ b/LostFound_API/Controllers/InstitutionController.cs @@ -0,0 +1,211 @@ +using Azure; +using LostFound_API.DTOs.Institution; +using LostFound_API.DTOs.Users; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using ObjectBusiness; +using Repository; +using System.Text.Json; +using System.Threading.Tasks; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace LostFound_API.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class InstitutionController : ControllerBase + { + #region Variables + private readonly IInstitutionRepository institutionRepository; + private readonly IWebHostEnvironment webHost; + private readonly IConfiguration configuration; + private readonly IHttpClientFactory httpClientFactory; + #endregion + + #region Constructor + public InstitutionController(IInstitutionRepository institutionRepository, + IWebHostEnvironment webHost, + IConfiguration configuration, + IHttpClientFactory httpClientFactory) + { + this.institutionRepository = institutionRepository; + this.webHost = webHost; + this.configuration = configuration; + this.httpClientFactory = httpClientFactory; + } + #endregion + + // GET: api/ + [HttpGet] + public IEnumerable Get() + { + return new string[] { "value1", "value2" }; + } + + // GET api//5 + [HttpGet("search")] + public async Task Search(string query) + { + if (string.IsNullOrWhiteSpace(query)) + { + return BadRequest(new + { + message = "Query is required" + }); + } + + var apiKey = configuration["CollegeScorecard:ApiKey"]; + var client = httpClientFactory.CreateClient(); + + var url = + $"https://api.data.gov/ed/collegescorecard/v1/schools" + + $"?api_key={apiKey}" + + $"&school.name={Uri.EscapeDataString(query)}" + + $"&fields=id,school.name,school.address,school.city,school.state,school.zip,school.school_url,location.lat,location.lon" + + $"&per_page=10"; + + // Send GET request to College Scorecard API + var res = await client.GetAsync(url); + + // If API returns errors + if (!res.IsSuccessStatusCode) + { + return StatusCode( + (int)res.StatusCode, + "Unable to retrieve institutions."); + } + + var json = await res.Content.ReadAsStringAsync(); + + // Parse JSON to JsonDocument in order to read each property + using var document = JsonDocument.Parse(json); + + // Get property "results" + var results = document.RootElement.GetProperty("results"); + + // Create DTO list to return to frontend. + var institutions = new List(); + + foreach (var item in results.EnumerateArray()) + { + institutions.Add(new InstitutionSearchDTO + { + // GET "id" field + // + // JSON: + // + // "id":166027 + // + // => + // int + Id = item.TryGetProperty("id", out var id) + && id.ValueKind == JsonValueKind.Number + ? id.GetInt32() : 0, + + // GET school name. + // + // JSON: + // + // "school.name":"Georgia State University" + // + // if null then return "" + Name = item.GetProperty("school.name").GetString() ?? "", + + // TryGetProperty to skip throw exception + // if property does not exist. + // + // If exist: + // get Address. + // + // If no: + // return null. + Address = item.TryGetProperty("school.address", out var address) + ? address.GetString() : null, + + // City + City = item.TryGetProperty("school.city", out var city) + ? city.GetString() : null, + + // State + State = item.TryGetProperty("school.state", out var state) + ? state.GetString() : null, + + // Zip Code + ZipCode = item.TryGetProperty("school.zip", out var zip) + ? zip.GetString() : null, + + // Website + Website = item.TryGetProperty("school.school_url", out var website) + ? website.GetString() : null, + + // Latitude + Latitude = item.TryGetProperty("location.lat", out var lat) + && lat.ValueKind == JsonValueKind.Number + ? lat.GetDouble() : null, + + // Longitude + Longitude = item.TryGetProperty("location.lon", out var lon) + && lon.ValueKind == JsonValueKind.Number + ? lon.GetDouble() : null, + + }); + } + + // return List to frontend. + // + // Frontend will receive: + // + // [ + // { + // id:166027, + // name:"Georgia State University", + // address:"33 Gilmer St SE", + // city:"Atlanta", + // state:"GA", + // zipCode:"30303", + // website:"www.gsu.edu", + // latitude:33.75, + // longitude:-84.38 + // } + // ] + + return Ok(institutions); + } + + // POST api/ + [Authorize] + [HttpPost] + public async Task CreateInstitution([FromBody] Institution institution) + { + if (institution == null || string.IsNullOrWhiteSpace(institution.InstitutionName) || string.IsNullOrWhiteSpace(institution.InstitutionAddress)) + { + return BadRequest("Invalid institution data"); + } + + var isAddedInstitution = await institutionRepository.CreateInstitution(institution); + + if (isAddedInstitution) + { + return Ok(new + { + Message = "Created institution successfully" + }); + } + + return BadRequest("Create institution failed"); + } + + // PUT api//5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api//5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } + } +} diff --git a/LostFound_API/Controllers/MessageChatController.cs b/LostFound_API/Controllers/MessageChatController.cs index 7e3eb23..7236c7b 100644 --- a/LostFound_API/Controllers/MessageChatController.cs +++ b/LostFound_API/Controllers/MessageChatController.cs @@ -191,7 +191,7 @@ public async Task SendMessage([FromBody] MessageChatDTO messageCha // Send email notification new chat string senderName = "Back2Me"; - string senderEmail = "baoandng07@gmail.com"; + string senderEmail = "mycampuslostfound@gmail.com"; string toName = user.FirstName + " " + user.LastName; string toEmail = userReceive.Email; string subject = "💬 You have a new chat on Back2me"; @@ -366,7 +366,7 @@ .content p {{ // Send email notification new message string senderName = "Back2Me"; - string senderEmail = "baoandng07@gmail.com"; + string senderEmail = "mycampuslostfound@gmail.com"; string toName = user.FirstName + " " + user.LastName; string toEmail = userReceive.Email; string subject = "💬 You have a new message on Back2me"; diff --git a/LostFound_API/Controllers/PickUpRequestController.cs b/LostFound_API/Controllers/PickUpRequestController.cs index 0bbf6ec..316715b 100644 --- a/LostFound_API/Controllers/PickUpRequestController.cs +++ b/LostFound_API/Controllers/PickUpRequestController.cs @@ -257,7 +257,7 @@ public async Task PickLater(int postId) if (post != null && admin != null) { string senderName = "Back2Me"; - string senderEmail = "baoandng07@gmail.com"; + string senderEmail = "mycampuslostfound@gmail.com"; string toName = admin.FirstName + " " + admin.LastName; string toEmail = admin.Email; string subject = "User Chose to Pick Up Later"; diff --git a/LostFound_API/Controllers/UsersController.cs b/LostFound_API/Controllers/UsersController.cs index ed31897..377dad4 100644 --- a/LostFound_API/Controllers/UsersController.cs +++ b/LostFound_API/Controllers/UsersController.cs @@ -27,6 +27,7 @@ public class UsersController : ControllerBase { #region Variables private readonly IUsersRepository usersRepository; + private readonly IInstitutionRepository institutionRepository; private readonly IStudentRepository studentRepository; private readonly IWebHostEnvironment webHost; private readonly IConfiguration configuration; @@ -42,7 +43,8 @@ public UsersController(IUsersRepository usersRepository, IStudentRepository studentRepository, IMemoryCache memoryCache, EmailSender emailSender, - IHubContext hubContext) + IHubContext hubContext, + IInstitutionRepository institutionRepository) { this.usersRepository = usersRepository; this.memoryCache = memoryCache; @@ -51,6 +53,7 @@ public UsersController(IUsersRepository usersRepository, this.configuration = configuration; this.studentRepository = studentRepository; this.emailSender = emailSender; + this.institutionRepository = institutionRepository; } #endregion @@ -168,57 +171,69 @@ public string Get(int id) [HttpPost("sign-up")] public async Task SignUp([FromBody] Users user) { - // Check duplicate student ID - var existingStudentByStudentId = studentRepository.AllStudents() - .Any(s => s.StudentId == user.StudentId); - - if (existingStudentByStudentId) + if (user == null) { - return Conflict(new + return BadRequest(new { - message = "Your student ID is already in use" + message = "Data is not valid" }); } - // Check duplicate email - var existingUserByEmail = usersRepository.AllUsers() - .Any(u => u.Email.Equals(user.Email)); + var institutionIdExist = institutionRepository.GetInstitutionByID(user.InstitutionId); - if (existingUserByEmail) + if (institutionIdExist != null) { - return Conflict(new - { - message = "Your email is already in use" - }); - } + // Check duplicate student ID + var existingStudentByStudentId = studentRepository.AllStudents() + .Any(s => s.StudentId == user.StudentId); - try - { - var isAddedUser = await usersRepository.SignUp(user); - if (isAddedUser) + if (existingStudentByStudentId) { - var student = new Student + return Conflict(new { - StudentId = user.StudentId, - UserId = user.UserId, - }; + message = "Your student ID is already in use" + }); + } - var isAddedStudent = await studentRepository.SignUpStudent(student); + // Check duplicate email + var existingUserByEmail = usersRepository.AllUsers() + .Any(u => u.Email.Equals(user.Email)); - if (isAddedStudent) + if (existingUserByEmail) + { + return Conflict(new { - // Send verification code via email - var token = Guid.NewGuid().ToString(); - memoryCache.Set($"EMAIL_VERIFY_{token}", user.Email, TimeSpan.FromMinutes(15)); + message = "Your email is already in use" + }); + } - // Send verification email - // Send email verify - string senderName = "Back2Me"; - string senderEmail = "baoandng07@gmail.com"; - string toName = user.FirstName + " " + user.LastName; - string toEmail = user.Email; - string subject = "✅ Please Verify Your Email"; - string content = $@" + try + { + var isAddedUser = await usersRepository.SignUp(user); + if (isAddedUser) + { + var student = new Student + { + StudentId = user.StudentId, + UserId = user.UserId, + }; + + var isAddedStudent = await studentRepository.SignUpStudent(student); + + if (isAddedStudent) + { + // Send verification code via email + var token = Guid.NewGuid().ToString(); + memoryCache.Set($"EMAIL_VERIFY_{token}", user.Email, TimeSpan.FromMinutes(15)); + + // Send verification email + // Send email verify + string senderName = "Back2Me"; + string senderEmail = "mycampuslostfound@gmail.com"; + string toName = user.FirstName + " " + user.LastName; + string toEmail = user.Email; + string subject = "✅ Please Verify Your Email"; + string content = $@"