Test plan incomplete, basic compaints support
This commit is contained in:
@@ -156,7 +156,7 @@ namespace Data
|
|||||||
UserRepository userRepository = new UserRepository();
|
UserRepository userRepository = new UserRepository();
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.Append("SELECT * FROM Announcements ");
|
sql.Append("SELECT * FROM Announcements ");
|
||||||
string[] searchStrings = query.Trim().Split(' ');
|
string[] searchStrings = query.Split(' ');
|
||||||
for (int i = 0; i < searchStrings.Length; i++)
|
for (int i = 0; i < searchStrings.Length; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@@ -207,4 +207,37 @@ public class CommentRepository : ICommentRepository
|
|||||||
}
|
}
|
||||||
DeleteComment(commentId);
|
DeleteComment(commentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CreateCommentOnComplaint(User author, string description, string title, DateTime publishDate, int complaintId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Comment> GetAllCommentsOnComplaint(int complaintId)
|
||||||
|
{
|
||||||
|
List<Comment> comments = new List<Comment>();
|
||||||
|
using (SqlConnection connection = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
string sql = "SELECT c.ID, c.Author, c.Description, c.Title, c.PublishDate, " +
|
||||||
|
"u.ID UserID, u.Name UserName, u.Password, u.Role FROM ComplaintsComments cc " +
|
||||||
|
"INNER JOIN Comments c ON c.ID = cc.CommentID " +
|
||||||
|
"INNER JOIN Users u ON u.ID = c.Author " +
|
||||||
|
"WHERE cc.ComplaintID = @complaintID";
|
||||||
|
SqlCommand sqlCommand = new SqlCommand(sql, connection);
|
||||||
|
sqlCommand.Parameters.AddWithValue("@complaintID", complaintId);
|
||||||
|
var reader = sqlCommand.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Comment newComment = new Comment((int)reader["ID"],
|
||||||
|
new User((int)reader["UserID"], reader["UserName"].ToString(),
|
||||||
|
reader["Password"].ToString(), (UserRole)reader["Role"]),
|
||||||
|
reader["Description"].ToString(), reader["Title"].ToString(),
|
||||||
|
(DateTime)reader["PublishDate"]);
|
||||||
|
newComment.Responses = GetAllCommentResponses(newComment.ID);
|
||||||
|
comments.Add(newComment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
}
|
}
|
192
StudentHouseDashboard/Data/ComplaintRepository.cs
Normal file
192
StudentHouseDashboard/Data/ComplaintRepository.cs
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
using Logic;
|
||||||
|
using Logic.Exceptions;
|
||||||
|
using Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
public class ComplaintRepository : IComplaintRepository
|
||||||
|
{
|
||||||
|
public ComplaintRepository()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public List<Complaint> GetAllComplaints()
|
||||||
|
{
|
||||||
|
List<Complaint> complaints = new List<Complaint>();
|
||||||
|
UserRepository userRepository = new UserRepository();
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
string sql = "SELECT * FROM Complaints;";
|
||||||
|
SqlCommand cmd = new SqlCommand(sql, conn);
|
||||||
|
var reader = cmd.ExecuteReader();
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
Complaint complaint = new Complaint(Convert.ToInt32(reader["ID"]),
|
||||||
|
userRepository.GetUserById(Convert.ToInt32(reader["Author"])),
|
||||||
|
reader["Description"].ToString(), reader["Title"].ToString(),
|
||||||
|
(DateTime)reader["PublishDate"], (ComplaintStatus)reader["Status"],
|
||||||
|
(ComplaintSeverity)reader["Severity"]);
|
||||||
|
CommentRepository commentRepository = new CommentRepository();
|
||||||
|
complaint.Responses = commentRepository.GetAllCommentsOnComplaint(complaint.ID);
|
||||||
|
// ID, Name, Password, Role
|
||||||
|
complaints.Add(complaint);
|
||||||
|
}
|
||||||
|
conn.Close();
|
||||||
|
}
|
||||||
|
return complaints;
|
||||||
|
}
|
||||||
|
public Complaint GetComplaintById(int id)
|
||||||
|
{
|
||||||
|
UserRepository userRepository = new UserRepository();
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
string sql = "SELECT * FROM Complaints WHERE ID = @id;";
|
||||||
|
SqlCommand cmd = new SqlCommand(sql, conn);
|
||||||
|
cmd.Parameters.AddWithValue("id", id);
|
||||||
|
var reader = cmd.ExecuteReader();
|
||||||
|
reader.Read();
|
||||||
|
Complaint complaint = new Complaint(Convert.ToInt32(reader["ID"]),
|
||||||
|
userRepository.GetUserById(Convert.ToInt32(reader["Author"])),
|
||||||
|
reader["Description"].ToString(), reader["Title"].ToString(),
|
||||||
|
(DateTime)reader["PublishDate"], (ComplaintStatus)reader["Status"],
|
||||||
|
(ComplaintSeverity)reader["Severity"]);
|
||||||
|
CommentRepository commentRepository = new CommentRepository();
|
||||||
|
complaint.Responses = commentRepository.GetAllCommentsOnComplaint(complaint.ID);
|
||||||
|
conn.Close();
|
||||||
|
return complaint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<Complaint> GetComplaintsByPage(int userId, int p, int c)
|
||||||
|
{
|
||||||
|
List<Complaint> complaints = new List<Complaint>();
|
||||||
|
UserRepository userRepository = new UserRepository();
|
||||||
|
User user = userRepository.GetUserById(userId);
|
||||||
|
string sql = "SELECT * FROM Complaints ORDER BY ID DESC OFFSET @start ROWS FETCH NEXT @count ROWS ONLY;";
|
||||||
|
if (user.Role == UserRole.TENANT)
|
||||||
|
{
|
||||||
|
sql = $"SELECT * FROM Complaints WHERE Author = {userId} ORDER BY ID DESC OFFSET @start ROWS FETCH NEXT @count ROWS ONLY;";
|
||||||
|
}
|
||||||
|
if (c == null)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException("Get complaints: Invalid item count");
|
||||||
|
}
|
||||||
|
if (p == null)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException("Get complaints: Invalid page number");
|
||||||
|
}
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
|
||||||
|
SqlCommand sqlCommand = new SqlCommand(sql, conn);
|
||||||
|
sqlCommand.Parameters.AddWithValue("@start", p * c);
|
||||||
|
sqlCommand.Parameters.AddWithValue("@count", c);
|
||||||
|
var reader = sqlCommand.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
complaints.Add(new Complaint(Convert.ToInt32(reader["ID"]),
|
||||||
|
userRepository.GetUserById(Convert.ToInt32(reader["Author"])),
|
||||||
|
reader["Description"].ToString(), reader["Title"].ToString(),
|
||||||
|
(DateTime)reader["PublishDate"], (ComplaintStatus)reader["Status"],
|
||||||
|
(ComplaintSeverity)reader["Severity"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return complaints;
|
||||||
|
}
|
||||||
|
public Complaint CreateComplaint(string title, string description, User author, DateTime publishDate, ComplaintStatus status, ComplaintSeverity severity)
|
||||||
|
{
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
string sql = "INSERT INTO Complaints (Author, Description, Title, PublishDate, Status, Severity) VALUES (@author, @desc, @title, @date, @status, @severity) " +
|
||||||
|
"SELECT SCOPE_IDENTITY();";
|
||||||
|
SqlCommand cmd = new SqlCommand(sql, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@author", author.ID);
|
||||||
|
cmd.Parameters.AddWithValue("@desc", description);
|
||||||
|
cmd.Parameters.AddWithValue("@title", title);
|
||||||
|
cmd.Parameters.AddWithValue("@date", publishDate);
|
||||||
|
cmd.Parameters.AddWithValue("@status", (int)status);
|
||||||
|
cmd.Parameters.AddWithValue("@severity", (int)severity);
|
||||||
|
int newId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||||
|
if (newId == 0)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException("Database error: Complaint not created");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GetComplaintById(newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void UpdateComplaint(int id, string title, string description, ComplaintStatus status, ComplaintSeverity severity)
|
||||||
|
{
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
string sql = "UPDATE Complaints " +
|
||||||
|
"SET Description = @desc, Title = @title, Status = @status, Severity = @severity " +
|
||||||
|
"WHERE ID = @id " +
|
||||||
|
"SELECT SCOPE_IDENTITY();";
|
||||||
|
SqlCommand cmd = new SqlCommand(sql, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@id", id);
|
||||||
|
cmd.Parameters.AddWithValue("@desc", description);
|
||||||
|
cmd.Parameters.AddWithValue("@title", title);
|
||||||
|
cmd.Parameters.AddWithValue("@status", (int)status);
|
||||||
|
cmd.Parameters.AddWithValue("@severity", (int)severity);
|
||||||
|
var writer = cmd.ExecuteNonQuery();
|
||||||
|
if (writer == -1)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException("Database error: Complaint not created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Complaint> SearchComplaint(string query)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(query))
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException("Search complaints error: Search query is empty");
|
||||||
|
}
|
||||||
|
List<Complaint> complaints = new List<Complaint>();
|
||||||
|
UserRepository userRepository = new UserRepository();
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
sql.Append("SELECT * FROM Complaints ");
|
||||||
|
string[] searchStrings = query.Split(' ');
|
||||||
|
for (int i = 0; i < searchStrings.Length; i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
sql.Append($"WHERE Title LIKE @query{i} OR Description LIKE @query{i} ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql.Append($"OR Title LIKE @query{i} OR Description LIKE @query{i} ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql.Append(';');
|
||||||
|
using (SqlConnection conn = SqlConnectionHelper.CreateConnection())
|
||||||
|
{
|
||||||
|
SqlCommand sqlCommand = new SqlCommand(sql.ToString(), conn);
|
||||||
|
for (int i = 0; i < searchStrings.Length; i++)
|
||||||
|
{
|
||||||
|
sqlCommand.Parameters.AddWithValue($"@query{i}", $"%{searchStrings[i]}%");
|
||||||
|
}
|
||||||
|
var reader = sqlCommand.ExecuteReader();
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
complaints.Add(new Complaint(Convert.ToInt32(reader["ID"]),
|
||||||
|
userRepository.GetUserById(Convert.ToInt32(reader["Author"])),
|
||||||
|
reader["Description"].ToString(), reader["Title"].ToString(),
|
||||||
|
(DateTime)reader["PublishDate"], (ComplaintStatus)reader["Status"],
|
||||||
|
(ComplaintSeverity)reader["Severity"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return complaints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -53,13 +53,16 @@ namespace Logic
|
|||||||
DateTime date;
|
DateTime date;
|
||||||
if (DateTime.TryParse(match.Groups[0].Value, out date))
|
if (DateTime.TryParse(match.Groups[0].Value, out date))
|
||||||
{
|
{
|
||||||
query = Regex.Replace(query, "date:[0-9]{4}-[0-9]{2}-[0-9]{2}", "");
|
query = Regex.Replace(query, "date:[0-9]{4}-[0-9]{2}-[0-9]{2}", "").Trim();
|
||||||
if (string.IsNullOrEmpty(query))
|
if (string.IsNullOrEmpty(query))
|
||||||
{
|
{
|
||||||
|
// search only by date
|
||||||
return announcementRepository.GetAllAnnouncements().Where(x => x.PublishDate.Date == date.Date).ToList();
|
return announcementRepository.GetAllAnnouncements().Where(x => x.PublishDate.Date == date.Date).ToList();
|
||||||
}
|
}
|
||||||
|
// search by date and keywords
|
||||||
else return announcementRepository.SearchAnnouncement(query).Where(x => x.PublishDate.Date == date.Date).ToList();
|
else return announcementRepository.SearchAnnouncement(query).Where(x => x.PublishDate.Date == date.Date).ToList();
|
||||||
}
|
}
|
||||||
|
// search by keywords
|
||||||
else return announcementRepository.SearchAnnouncement(query);
|
else return announcementRepository.SearchAnnouncement(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
StudentHouseDashboard/Logic/ComplaintManager.cs
Normal file
42
StudentHouseDashboard/Logic/ComplaintManager.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Logic
|
||||||
|
{
|
||||||
|
public class ComplaintManager
|
||||||
|
{
|
||||||
|
private IComplaintRepository complaintRepository;
|
||||||
|
public ComplaintManager(IComplaintRepository complaintRepository)
|
||||||
|
{
|
||||||
|
this.complaintRepository = complaintRepository;
|
||||||
|
}
|
||||||
|
public List<Complaint> GetAllComplaints()
|
||||||
|
{
|
||||||
|
return complaintRepository.GetAllComplaints();
|
||||||
|
}
|
||||||
|
public Complaint GetComplaintById(int id)
|
||||||
|
{
|
||||||
|
return complaintRepository.GetComplaintById(id);
|
||||||
|
}
|
||||||
|
public List<Complaint> GetComplaintsByPage(int userId, int p, int c)
|
||||||
|
{
|
||||||
|
return complaintRepository.GetComplaintsByPage(userId, p, c);
|
||||||
|
}
|
||||||
|
public Complaint CreateComplaint(string title, string description, User author, DateTime publishDate, ComplaintStatus status, ComplaintSeverity severity)
|
||||||
|
{
|
||||||
|
return complaintRepository.CreateComplaint(title, description, author, publishDate, status, severity);
|
||||||
|
}
|
||||||
|
public void UpdateComplaint(int id, string title, string description, ComplaintStatus status, ComplaintSeverity severity)
|
||||||
|
{
|
||||||
|
complaintRepository.UpdateComplaint(id, title, description, status, severity);
|
||||||
|
}
|
||||||
|
public List<Complaint> SearchComplaint(string query)
|
||||||
|
{
|
||||||
|
return complaintRepository.SearchComplaint(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7,11 +7,13 @@ namespace Logic;
|
|||||||
public interface ICommentRepository
|
public interface ICommentRepository
|
||||||
{
|
{
|
||||||
public List<Comment> GetAllCommentsOnAnnouncement(int announcementId);
|
public List<Comment> GetAllCommentsOnAnnouncement(int announcementId);
|
||||||
|
public List<Comment> GetAllCommentsOnComplaint(int complaintId);
|
||||||
public List<Comment> GetAllCommentResponses(int commentId);
|
public List<Comment> GetAllCommentResponses(int commentId);
|
||||||
public Comment GetCommentById(int id);
|
public Comment GetCommentById(int id);
|
||||||
public void UpdateComment(int id, string description);
|
public void UpdateComment(int id, string description);
|
||||||
public Comment CreateComment(User author, string description, string title, DateTime publishDate);
|
public Comment CreateComment(User author, string description, string title, DateTime publishDate);
|
||||||
public void CreateCommentOnAnnouncement(User author, string description, string title, DateTime publishDate, int announcementId);
|
public void CreateCommentOnAnnouncement(User author, string description, string title, DateTime publishDate, int announcementId);
|
||||||
|
public void CreateCommentOnComplaint(User author, string description, string title, DateTime publishDate, int complaintId);
|
||||||
public void CreateResponseOnComment(User author, string description, string title, DateTime publishDate, int commentId);
|
public void CreateResponseOnComment(User author, string description, string title, DateTime publishDate, int commentId);
|
||||||
public void DeleteComment(int id);
|
public void DeleteComment(int id);
|
||||||
public void DeleteCommentOnAnnouncement(int commentId, int announcementId);
|
public void DeleteCommentOnAnnouncement(int commentId, int announcementId);
|
||||||
|
20
StudentHouseDashboard/Logic/IComplaintRepository.cs
Normal file
20
StudentHouseDashboard/Logic/IComplaintRepository.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Logic.Exceptions;
|
||||||
|
using Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Logic
|
||||||
|
{
|
||||||
|
public interface IComplaintRepository
|
||||||
|
{
|
||||||
|
public List<Complaint> GetAllComplaints();
|
||||||
|
public Complaint GetComplaintById(int id);
|
||||||
|
public List<Complaint> GetComplaintsByPage(int userId, int p, int c);
|
||||||
|
public Complaint CreateComplaint(string title, string description, User author, DateTime publishDate, ComplaintStatus status, ComplaintSeverity severity);
|
||||||
|
public void UpdateComplaint(int id, string title, string description, ComplaintStatus status, ComplaintSeverity severity);
|
||||||
|
public List<Complaint> SearchComplaint(string query);
|
||||||
|
}
|
||||||
|
}
|
@@ -33,12 +33,12 @@ namespace Logic
|
|||||||
}
|
}
|
||||||
public User? AuthenticatedUser(string name, string password)
|
public User? AuthenticatedUser(string name, string password)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Name or password should not be empty!");
|
||||||
|
}
|
||||||
List<User> users = userRepository.GetAllUsers();
|
List<User> users = userRepository.GetAllUsers();
|
||||||
User? user = users.Find(x => x.Name == name);
|
User? user = users.Find(x => x.Name == name);
|
||||||
if (name == null || password == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException();
|
|
||||||
}
|
|
||||||
if (user != null && BCrypt.Net.BCrypt.Verify(password, user.Password))
|
if (user != null && BCrypt.Net.BCrypt.Verify(password, user.Password))
|
||||||
{
|
{
|
||||||
return user;
|
return user;
|
||||||
@@ -57,12 +57,16 @@ namespace Logic
|
|||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(password))
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(password))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Name or password should not be empty");
|
throw new ArgumentException("Name or password should not be empty!");
|
||||||
}
|
}
|
||||||
return userRepository.CreateUser(name, password, role);
|
return userRepository.CreateUser(name, password, role);
|
||||||
}
|
}
|
||||||
public void UpdateUser(int id, string name, string password, UserRole role)
|
public void UpdateUser(int id, string name, string password, UserRole role)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Name or password should not be empty!");
|
||||||
|
}
|
||||||
userRepository.UpdateUser(id, name, password, role);
|
userRepository.UpdateUser(id, name, password, role);
|
||||||
}
|
}
|
||||||
public void DisableUser(int id)
|
public void DisableUser(int id)
|
||||||
|
@@ -7,6 +7,10 @@ namespace Models
|
|||||||
{
|
{
|
||||||
public class Complaint : GenericMessage
|
public class Complaint : GenericMessage
|
||||||
{
|
{
|
||||||
|
public Complaint()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
public Complaint(int id, User author, string description, string title, DateTime publishDate, ComplaintStatus status, ComplaintSeverity severity) : base(id, author, description, title, publishDate)
|
public Complaint(int id, User author, string description, string title, DateTime publishDate, ComplaintStatus status, ComplaintSeverity severity) : base(id, author, description, title, publishDate)
|
||||||
{
|
{
|
||||||
Status = status;
|
Status = status;
|
||||||
@@ -27,5 +31,9 @@ namespace Models
|
|||||||
{
|
{
|
||||||
get;set;
|
get;set;
|
||||||
}
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"({PublishDate.ToString("d")} - {Author.Name}) {Title}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -7,9 +8,13 @@ namespace Models
|
|||||||
{
|
{
|
||||||
public enum ComplaintSeverity
|
public enum ComplaintSeverity
|
||||||
{
|
{
|
||||||
|
[Description("Low")]
|
||||||
LOW,
|
LOW,
|
||||||
|
[Description("Normal")]
|
||||||
NORMAL,
|
NORMAL,
|
||||||
|
[Description("High")]
|
||||||
HIGH,
|
HIGH,
|
||||||
|
[Description("Urgent")]
|
||||||
URGENT
|
URGENT
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -7,9 +8,13 @@ namespace Models
|
|||||||
{
|
{
|
||||||
public enum ComplaintStatus
|
public enum ComplaintStatus
|
||||||
{
|
{
|
||||||
|
[Description("Filed")]
|
||||||
FILED,
|
FILED,
|
||||||
|
[Description("Under review")]
|
||||||
UNDER_REVIEW,
|
UNDER_REVIEW,
|
||||||
|
[Description("Solved")]
|
||||||
SOLVED,
|
SOLVED,
|
||||||
|
[Description("Archived")]
|
||||||
ARCHIVED
|
ARCHIVED
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ namespace Models
|
|||||||
{
|
{
|
||||||
get;set;
|
get;set;
|
||||||
}
|
}
|
||||||
|
[StringLength(255)]
|
||||||
public string Title
|
public string Title
|
||||||
{
|
{
|
||||||
get;set;
|
get;set;
|
||||||
|
@@ -25,7 +25,7 @@ namespace Models
|
|||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
[StringLength(255)]
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -8,11 +9,11 @@ namespace Models
|
|||||||
{
|
{
|
||||||
public enum UserRole
|
public enum UserRole
|
||||||
{
|
{
|
||||||
[Display(Name = "Tenant")]
|
[Description("Tenant")]
|
||||||
TENANT,
|
TENANT,
|
||||||
[Display(Name = "Manager")]
|
[Description("Manager")]
|
||||||
MANAGER,
|
MANAGER,
|
||||||
[Display(Name = "Administrator")]
|
[Description("Administrator")]
|
||||||
ADMIN
|
ADMIN
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -28,7 +28,7 @@ namespace Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[ExpectedException(typeof(ArgumentNullException))]
|
[ExpectedException(typeof(ArgumentException))]
|
||||||
public void AuthenticatedUserNullPasswordTest()
|
public void AuthenticatedUserNullPasswordTest()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
76
StudentHouseDashboard/WebApp/Pages/Complaints.cshtml
Normal file
76
StudentHouseDashboard/WebApp/Pages/Complaints.cshtml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
@page
|
||||||
|
@using Models;
|
||||||
|
@using System.Security.Claims;
|
||||||
|
@model WebApp.Pages.ComplaintsModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Complaints";
|
||||||
|
List<Complaint> complaints = ((List<Complaint>)ViewData["complaints"]).ToList();
|
||||||
|
int currentPage = 0;
|
||||||
|
if (ViewData["page"] != null)
|
||||||
|
{
|
||||||
|
currentPage = Convert.ToInt32(ViewData["page"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<a href="./CreateComplaint" class="btn btn-primary">Create new complaint</a>
|
||||||
|
|
||||||
|
<div class="mb-3 mt-3">
|
||||||
|
@foreach (Complaint complaint in complaints)
|
||||||
|
{
|
||||||
|
<div class="card" style="display:inline-flex; width: 18rem;">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title" @if (complaint.Severity == ComplaintSeverity.URGENT)
|
||||||
|
{
|
||||||
|
@: style="color: red;"
|
||||||
|
}
|
||||||
|
else if (complaint.Severity == ComplaintSeverity.HIGH)
|
||||||
|
{
|
||||||
|
@: style="color: orange;"
|
||||||
|
}
|
||||||
|
@if (complaint.Severity == ComplaintSeverity.LOW)
|
||||||
|
{
|
||||||
|
@: style="color: darkgreen;"
|
||||||
|
}>@complaint.Title</h5>
|
||||||
|
<h6 class="card-subtitle mb-2 text-muted">@complaint.Status</h6>
|
||||||
|
<h6 class="card-subtitle mb-2 text-muted">@complaint.Author.Name</h6>
|
||||||
|
<p class="card-text">@complaint.Description.PadRight(100).Substring(0,100).Trim()</p>
|
||||||
|
<a href="./complaint?id=@complaint.ID" class="btn btn-primary">More details</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (ViewData["page"] != null)
|
||||||
|
{
|
||||||
|
<nav aria-label="Page navigation">
|
||||||
|
<ul class="pagination justify-content-center">
|
||||||
|
@if (currentPage <= 1)
|
||||||
|
{
|
||||||
|
@: <li class="page-item disabled">
|
||||||
|
@: <a class="page-link" tabindex="-1">Previous</a>
|
||||||
|
@: </li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@: <li class="page-item">
|
||||||
|
@: <a class="page-link" href="./complaints?p=@(currentPage - 1)" tabindex="-1">Previous</a>
|
||||||
|
@: </li>
|
||||||
|
@: <li class="page-item"><a class="page-link" href="./complaints?p=@(currentPage - 1)">@(currentPage - 1)</a></li>
|
||||||
|
}
|
||||||
|
<li class="page-item"><a class="page-link">@currentPage</a>
|
||||||
|
@if (complaints.Count == 0 || complaints.Count < Convert.ToInt32(ViewData["count"]))
|
||||||
|
{
|
||||||
|
@: <li class="page-item disabled">
|
||||||
|
@: <a class="page-link">Next</a>
|
||||||
|
@: </li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@: <li class="page-item"><a class="page-link" href="./complaints?p=@(currentPage + 1)">@(currentPage + 1)</a></li>
|
||||||
|
@: <li class="page-item">
|
||||||
|
@: <a class="page-link" href="./complaints?p=@(currentPage + 1)">Next</a>
|
||||||
|
@: </li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
}
|
38
StudentHouseDashboard/WebApp/Pages/Complaints.cshtml.cs
Normal file
38
StudentHouseDashboard/WebApp/Pages/Complaints.cshtml.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Logic;
|
||||||
|
using Models;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace WebApp.Pages
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
public class ComplaintsModel : PageModel
|
||||||
|
{
|
||||||
|
public ComplaintManager ComplaintManager { get; set; }
|
||||||
|
private readonly IComplaintRepository _complaintRepository;
|
||||||
|
|
||||||
|
public ComplaintsModel(IComplaintRepository complaintRepository)
|
||||||
|
{
|
||||||
|
_complaintRepository = complaintRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGet(int? p, int? c) // page, count
|
||||||
|
{
|
||||||
|
ComplaintManager = new ComplaintManager(_complaintRepository);
|
||||||
|
if (!(p < 0))
|
||||||
|
{
|
||||||
|
p = 1;
|
||||||
|
}
|
||||||
|
if (!(c < 1))
|
||||||
|
{
|
||||||
|
c = 10;
|
||||||
|
}
|
||||||
|
ViewData.Add("complaints", ComplaintManager.GetComplaintsByPage(int.Parse(User.FindFirstValue("id")), p.Value - 1, c.Value));
|
||||||
|
ViewData.Add("page", p);
|
||||||
|
ViewData.Add("count", c);
|
||||||
|
ViewData.Add("allCount", ComplaintManager.GetAllComplaints().Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
StudentHouseDashboard/WebApp/Pages/CreateComplaint.cshtml
Normal file
24
StudentHouseDashboard/WebApp/Pages/CreateComplaint.cshtml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
@page
|
||||||
|
@using Models;
|
||||||
|
@model WebApp.Pages.CreateComplaintModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Create complaint";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label asp-for="Complaint.Title" class="form-label">Title: </label>
|
||||||
|
<input asp-for="Complaint.Title" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label asp-for="Complaint.Severity" class="form-label">Severity: </label>
|
||||||
|
<select asp-for="Complaint.Severity" asp-items="Html.GetEnumSelectList<ComplaintSeverity>()" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label asp-for="Complaint.Description" class="form-label">Description: </label>
|
||||||
|
<textarea asp-for="Complaint.Description" class="form-control" rows="5"></textarea>
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="Create" class="btn btn-primary" />
|
||||||
|
</form>
|
28
StudentHouseDashboard/WebApp/Pages/CreateComplaint.cshtml.cs
Normal file
28
StudentHouseDashboard/WebApp/Pages/CreateComplaint.cshtml.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Data;
|
||||||
|
using Logic;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Models;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace WebApp.Pages
|
||||||
|
{
|
||||||
|
[Authorize]
|
||||||
|
public class CreateComplaintModel : PageModel
|
||||||
|
{
|
||||||
|
[BindProperty]
|
||||||
|
public Complaint Complaint { get; set; }
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public IActionResult OnPost()
|
||||||
|
{
|
||||||
|
ComplaintManager complaintManager = new ComplaintManager(new ComplaintRepository());
|
||||||
|
UserManager userManager = new UserManager(new UserRepository());
|
||||||
|
User user = userManager.GetUserById(int.Parse(User.FindFirstValue("id")));
|
||||||
|
complaintManager.CreateComplaint(Complaint.Title, Complaint.Description, user, DateTime.Now, ComplaintStatus.FILED, Complaint.Severity);
|
||||||
|
return RedirectToPage("Complaints");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -27,6 +27,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" asp-area="" asp-page="/Announcements">Announcements</a>
|
<a class="nav-link text-dark" asp-area="" asp-page="/Announcements">Announcements</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" asp-area="" asp-page="/Complaints">Complaints</a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
|
@@ -21,6 +21,7 @@ namespace WebApp
|
|||||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||||
builder.Services.AddScoped<ICommentRepository, CommentRepository>();
|
builder.Services.AddScoped<ICommentRepository, CommentRepository>();
|
||||||
builder.Services.AddScoped<IAnnouncementRepository, AnnouncementRepository>();
|
builder.Services.AddScoped<IAnnouncementRepository, AnnouncementRepository>();
|
||||||
|
builder.Services.AddScoped<IComplaintRepository, ComplaintRepository>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
237
StudentHouseDashboard/WinForms/ComplaintForm.Designer.cs
generated
Normal file
237
StudentHouseDashboard/WinForms/ComplaintForm.Designer.cs
generated
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
namespace WinForms
|
||||||
|
{
|
||||||
|
partial class ComplaintForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
lblTitle = new Label();
|
||||||
|
tbTitle = new TextBox();
|
||||||
|
lblDescription = new Label();
|
||||||
|
tbDescription = new TextBox();
|
||||||
|
lblPublishDate = new Label();
|
||||||
|
btnSave = new Button();
|
||||||
|
dtpPublishDate = new DateTimePicker();
|
||||||
|
lblAuthor = new Label();
|
||||||
|
lblComments = new Label();
|
||||||
|
listBox1 = new ListBox();
|
||||||
|
btnViewComment = new Button();
|
||||||
|
btnEditComment = new Button();
|
||||||
|
btnDeleteComment = new Button();
|
||||||
|
btnCreateComment = new Button();
|
||||||
|
cbStatus = new ComboBox();
|
||||||
|
cbSeverity = new ComboBox();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblTitle
|
||||||
|
//
|
||||||
|
lblTitle.AutoSize = true;
|
||||||
|
lblTitle.Location = new Point(12, 9);
|
||||||
|
lblTitle.Name = "lblTitle";
|
||||||
|
lblTitle.Size = new Size(32, 15);
|
||||||
|
lblTitle.TabIndex = 0;
|
||||||
|
lblTitle.Text = "Title:";
|
||||||
|
//
|
||||||
|
// tbTitle
|
||||||
|
//
|
||||||
|
tbTitle.Location = new Point(94, 6);
|
||||||
|
tbTitle.Name = "tbTitle";
|
||||||
|
tbTitle.Size = new Size(405, 23);
|
||||||
|
tbTitle.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// lblDescription
|
||||||
|
//
|
||||||
|
lblDescription.AutoSize = true;
|
||||||
|
lblDescription.Location = new Point(12, 38);
|
||||||
|
lblDescription.Name = "lblDescription";
|
||||||
|
lblDescription.Size = new Size(70, 15);
|
||||||
|
lblDescription.TabIndex = 2;
|
||||||
|
lblDescription.Text = "Description:";
|
||||||
|
//
|
||||||
|
// tbDescription
|
||||||
|
//
|
||||||
|
tbDescription.Location = new Point(94, 35);
|
||||||
|
tbDescription.Multiline = true;
|
||||||
|
tbDescription.Name = "tbDescription";
|
||||||
|
tbDescription.Size = new Size(405, 112);
|
||||||
|
tbDescription.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// lblPublishDate
|
||||||
|
//
|
||||||
|
lblPublishDate.AutoSize = true;
|
||||||
|
lblPublishDate.Location = new Point(12, 159);
|
||||||
|
lblPublishDate.Name = "lblPublishDate";
|
||||||
|
lblPublishDate.Size = new Size(76, 15);
|
||||||
|
lblPublishDate.TabIndex = 4;
|
||||||
|
lblPublishDate.Text = "Publish Date:";
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Location = new Point(424, 180);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(75, 23);
|
||||||
|
btnSave.TabIndex = 6;
|
||||||
|
btnSave.Text = "Save changes";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// dtpPublishDate
|
||||||
|
//
|
||||||
|
dtpPublishDate.Location = new Point(94, 153);
|
||||||
|
dtpPublishDate.Name = "dtpPublishDate";
|
||||||
|
dtpPublishDate.Size = new Size(151, 23);
|
||||||
|
dtpPublishDate.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// lblAuthor
|
||||||
|
//
|
||||||
|
lblAuthor.AutoSize = true;
|
||||||
|
lblAuthor.Location = new Point(12, 184);
|
||||||
|
lblAuthor.Name = "lblAuthor";
|
||||||
|
lblAuthor.Size = new Size(70, 15);
|
||||||
|
lblAuthor.TabIndex = 10;
|
||||||
|
lblAuthor.Text = "Created by: ";
|
||||||
|
//
|
||||||
|
// lblComments
|
||||||
|
//
|
||||||
|
lblComments.AutoSize = true;
|
||||||
|
lblComments.Location = new Point(12, 209);
|
||||||
|
lblComments.Name = "lblComments";
|
||||||
|
lblComments.Size = new Size(66, 15);
|
||||||
|
lblComments.TabIndex = 11;
|
||||||
|
lblComments.Text = "Comments";
|
||||||
|
//
|
||||||
|
// listBox1
|
||||||
|
//
|
||||||
|
listBox1.FormattingEnabled = true;
|
||||||
|
listBox1.ItemHeight = 15;
|
||||||
|
listBox1.Location = new Point(12, 227);
|
||||||
|
listBox1.Name = "listBox1";
|
||||||
|
listBox1.Size = new Size(399, 154);
|
||||||
|
listBox1.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// btnViewComment
|
||||||
|
//
|
||||||
|
btnViewComment.Location = new Point(424, 271);
|
||||||
|
btnViewComment.Name = "btnViewComment";
|
||||||
|
btnViewComment.Size = new Size(75, 23);
|
||||||
|
btnViewComment.TabIndex = 13;
|
||||||
|
btnViewComment.Text = "View";
|
||||||
|
btnViewComment.UseVisualStyleBackColor = true;
|
||||||
|
btnViewComment.Click += btnViewComment_Click;
|
||||||
|
//
|
||||||
|
// btnEditComment
|
||||||
|
//
|
||||||
|
btnEditComment.Location = new Point(424, 300);
|
||||||
|
btnEditComment.Name = "btnEditComment";
|
||||||
|
btnEditComment.Size = new Size(75, 23);
|
||||||
|
btnEditComment.TabIndex = 14;
|
||||||
|
btnEditComment.Text = "Edit";
|
||||||
|
btnEditComment.UseVisualStyleBackColor = true;
|
||||||
|
btnEditComment.Click += btnEditComment_Click;
|
||||||
|
//
|
||||||
|
// btnDeleteComment
|
||||||
|
//
|
||||||
|
btnDeleteComment.Location = new Point(424, 329);
|
||||||
|
btnDeleteComment.Name = "btnDeleteComment";
|
||||||
|
btnDeleteComment.Size = new Size(75, 23);
|
||||||
|
btnDeleteComment.TabIndex = 15;
|
||||||
|
btnDeleteComment.Text = "Delete";
|
||||||
|
btnDeleteComment.UseVisualStyleBackColor = true;
|
||||||
|
btnDeleteComment.Click += btnDeleteComment_Click;
|
||||||
|
//
|
||||||
|
// btnCreateComment
|
||||||
|
//
|
||||||
|
btnCreateComment.Location = new Point(424, 358);
|
||||||
|
btnCreateComment.Name = "btnCreateComment";
|
||||||
|
btnCreateComment.Size = new Size(75, 23);
|
||||||
|
btnCreateComment.TabIndex = 16;
|
||||||
|
btnCreateComment.Text = "New";
|
||||||
|
btnCreateComment.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateComment.Click += btnCreateComment_Click;
|
||||||
|
//
|
||||||
|
// cbStatus
|
||||||
|
//
|
||||||
|
cbStatus.FormattingEnabled = true;
|
||||||
|
cbStatus.Location = new Point(251, 153);
|
||||||
|
cbStatus.Name = "cbStatus";
|
||||||
|
cbStatus.Size = new Size(121, 23);
|
||||||
|
cbStatus.TabIndex = 17;
|
||||||
|
//
|
||||||
|
// cbSeverity
|
||||||
|
//
|
||||||
|
cbSeverity.FormattingEnabled = true;
|
||||||
|
cbSeverity.Location = new Point(378, 153);
|
||||||
|
cbSeverity.Name = "cbSeverity";
|
||||||
|
cbSeverity.Size = new Size(121, 23);
|
||||||
|
cbSeverity.TabIndex = 18;
|
||||||
|
//
|
||||||
|
// ComplaintForm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(511, 400);
|
||||||
|
Controls.Add(cbSeverity);
|
||||||
|
Controls.Add(cbStatus);
|
||||||
|
Controls.Add(btnCreateComment);
|
||||||
|
Controls.Add(btnDeleteComment);
|
||||||
|
Controls.Add(btnEditComment);
|
||||||
|
Controls.Add(btnViewComment);
|
||||||
|
Controls.Add(listBox1);
|
||||||
|
Controls.Add(lblComments);
|
||||||
|
Controls.Add(lblAuthor);
|
||||||
|
Controls.Add(dtpPublishDate);
|
||||||
|
Controls.Add(btnSave);
|
||||||
|
Controls.Add(lblPublishDate);
|
||||||
|
Controls.Add(tbDescription);
|
||||||
|
Controls.Add(lblDescription);
|
||||||
|
Controls.Add(tbTitle);
|
||||||
|
Controls.Add(lblTitle);
|
||||||
|
Name = "ComplaintForm";
|
||||||
|
Text = "Complaint";
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblTitle;
|
||||||
|
private TextBox tbTitle;
|
||||||
|
private Label lblDescription;
|
||||||
|
private TextBox tbDescription;
|
||||||
|
private Label lblPublishDate;
|
||||||
|
private Button btnSave;
|
||||||
|
private DateTimePicker dtpPublishDate;
|
||||||
|
private Label lblAuthor;
|
||||||
|
private Label lblComments;
|
||||||
|
private ListBox listBox1;
|
||||||
|
private Button btnViewComment;
|
||||||
|
private Button btnEditComment;
|
||||||
|
private Button btnDeleteComment;
|
||||||
|
private Button btnCreateComment;
|
||||||
|
private ComboBox cbStatus;
|
||||||
|
private ComboBox cbSeverity;
|
||||||
|
}
|
||||||
|
}
|
149
StudentHouseDashboard/WinForms/ComplaintForm.cs
Normal file
149
StudentHouseDashboard/WinForms/ComplaintForm.cs
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
using Data;
|
||||||
|
using Logic;
|
||||||
|
using Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace WinForms
|
||||||
|
{
|
||||||
|
public partial class ComplaintForm : Form
|
||||||
|
{
|
||||||
|
Complaint complaint;
|
||||||
|
User currentUser;
|
||||||
|
public ComplaintForm(Complaint? complaint, bool readOnly, User currentUser)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.complaint = complaint;
|
||||||
|
this.currentUser = currentUser;
|
||||||
|
|
||||||
|
dtpPublishDate.Enabled = false;
|
||||||
|
foreach (var item in Enum.GetValues(typeof(ComplaintStatus)))
|
||||||
|
{
|
||||||
|
cbStatus.Items.Add(item);
|
||||||
|
}
|
||||||
|
foreach (var item in Enum.GetValues(typeof(ComplaintSeverity)))
|
||||||
|
{
|
||||||
|
cbSeverity.Items.Add(item);
|
||||||
|
}
|
||||||
|
if (readOnly)
|
||||||
|
{
|
||||||
|
btnSave.Enabled = false;
|
||||||
|
tbTitle.Enabled = false;
|
||||||
|
tbDescription.Enabled = false;
|
||||||
|
cbStatus.Enabled = false;
|
||||||
|
cbSeverity.Enabled = false;
|
||||||
|
}
|
||||||
|
if (complaint != null)
|
||||||
|
{
|
||||||
|
tbTitle.Text = complaint.Title;
|
||||||
|
lblAuthor.Text = $"Created by: {complaint.Author.Name}";
|
||||||
|
tbDescription.Text = complaint.Description;
|
||||||
|
dtpPublishDate.Value = complaint.PublishDate;
|
||||||
|
cbStatus.SelectedIndex = (int)complaint.Status;
|
||||||
|
cbSeverity.SelectedIndex = (int)complaint.Severity;
|
||||||
|
RefreshComments();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btnCreateComment.Enabled = false;
|
||||||
|
btnDeleteComment.Enabled = false;
|
||||||
|
btnEditComment.Enabled = false;
|
||||||
|
btnViewComment.Enabled = false;
|
||||||
|
}
|
||||||
|
if (currentUser != null)
|
||||||
|
{
|
||||||
|
lblAuthor.Text = $"Created by: {currentUser.Name}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ComplaintManager complaintManager = new ComplaintManager(new ComplaintRepository());
|
||||||
|
if (string.IsNullOrEmpty(tbTitle.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please enter a title");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.complaint == null)
|
||||||
|
{
|
||||||
|
complaintManager.CreateComplaint(tbTitle.Text, tbDescription.Text, currentUser, dtpPublishDate.Value, (ComplaintStatus)cbStatus.SelectedIndex, (ComplaintSeverity)cbSeverity.SelectedIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
complaintManager.UpdateComplaint(complaint.ID, tbTitle.Text, tbDescription.Text, (ComplaintStatus)cbStatus.SelectedIndex, (ComplaintSeverity)cbSeverity.SelectedIndex);
|
||||||
|
}
|
||||||
|
this.DialogResult = DialogResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnViewComment_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (listBox1.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommentForm form = new CommentForm((Comment)listBox1.SelectedItem, true, currentUser);
|
||||||
|
form.ShowDialog();
|
||||||
|
RefreshComments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnEditComment_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (listBox1.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommentForm form = new CommentForm((Comment)listBox1.SelectedItem, false, currentUser);
|
||||||
|
form.ShowDialog();
|
||||||
|
RefreshComments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnDeleteComment_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (listBox1.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Comment currentComment = (Comment)listBox1.SelectedItem;
|
||||||
|
if (MessageBox.Show($"Are you sure you want to delete\n{currentComment.Title}\nCreated at {currentComment.PublishDate.ToString("g")} by {currentComment.Author.Name}",
|
||||||
|
"Delete announcement", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
CommentManager commentManager = new CommentManager(new CommentRepository());
|
||||||
|
commentManager.DeleteCommentOnAnnouncement(currentComment.ID, complaint.ID);
|
||||||
|
}
|
||||||
|
RefreshComments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCreateComment_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CommentForm form = new CommentForm(null, false, currentUser, true, complaint.ID);
|
||||||
|
form.ShowDialog();
|
||||||
|
RefreshComments();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshComments()
|
||||||
|
{
|
||||||
|
listBox1.Items.Clear();
|
||||||
|
foreach (var item in complaint.Responses)
|
||||||
|
{
|
||||||
|
listBox1.Items.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
StudentHouseDashboard/WinForms/ComplaintForm.resx
Normal file
120
StudentHouseDashboard/WinForms/ComplaintForm.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
143
StudentHouseDashboard/WinForms/Dashboard.Designer.cs
generated
143
StudentHouseDashboard/WinForms/Dashboard.Designer.cs
generated
@@ -38,17 +38,26 @@
|
|||||||
tpUsers = new TabPage();
|
tpUsers = new TabPage();
|
||||||
panelUserFunctions = new Panel();
|
panelUserFunctions = new Panel();
|
||||||
tpAnnouncements = new TabPage();
|
tpAnnouncements = new TabPage();
|
||||||
lbAnnouncements = new ListBox();
|
panelAnnouncementsFunctions = new Panel();
|
||||||
panel1 = new Panel();
|
|
||||||
btnNewAnnouncement = new Button();
|
btnNewAnnouncement = new Button();
|
||||||
btnDeleteAnnouncement = new Button();
|
btnDeleteAnnouncement = new Button();
|
||||||
btnViewAnnouncement = new Button();
|
btnViewAnnouncement = new Button();
|
||||||
btnEditAnnouncement = new Button();
|
btnEditAnnouncement = new Button();
|
||||||
|
lbAnnouncements = new ListBox();
|
||||||
|
tpComplaints = new TabPage();
|
||||||
|
tpEvents = new TabPage();
|
||||||
|
lbComplaints = new ListBox();
|
||||||
|
panelComplaintFunctions = new Panel();
|
||||||
|
btnArchiveComplaint = new Button();
|
||||||
|
btnViewComplaint = new Button();
|
||||||
|
btnEditComplaint = new Button();
|
||||||
tabControl1.SuspendLayout();
|
tabControl1.SuspendLayout();
|
||||||
tpUsers.SuspendLayout();
|
tpUsers.SuspendLayout();
|
||||||
panelUserFunctions.SuspendLayout();
|
panelUserFunctions.SuspendLayout();
|
||||||
tpAnnouncements.SuspendLayout();
|
tpAnnouncements.SuspendLayout();
|
||||||
panel1.SuspendLayout();
|
panelAnnouncementsFunctions.SuspendLayout();
|
||||||
|
tpComplaints.SuspendLayout();
|
||||||
|
panelComplaintFunctions.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// lblUserStatus
|
// lblUserStatus
|
||||||
@@ -116,6 +125,8 @@
|
|||||||
//
|
//
|
||||||
tabControl1.Controls.Add(tpUsers);
|
tabControl1.Controls.Add(tpUsers);
|
||||||
tabControl1.Controls.Add(tpAnnouncements);
|
tabControl1.Controls.Add(tpAnnouncements);
|
||||||
|
tabControl1.Controls.Add(tpComplaints);
|
||||||
|
tabControl1.Controls.Add(tpEvents);
|
||||||
tabControl1.Dock = DockStyle.Fill;
|
tabControl1.Dock = DockStyle.Fill;
|
||||||
tabControl1.Location = new Point(0, 0);
|
tabControl1.Location = new Point(0, 0);
|
||||||
tabControl1.Name = "tabControl1";
|
tabControl1.Name = "tabControl1";
|
||||||
@@ -149,7 +160,7 @@
|
|||||||
//
|
//
|
||||||
// tpAnnouncements
|
// tpAnnouncements
|
||||||
//
|
//
|
||||||
tpAnnouncements.Controls.Add(panel1);
|
tpAnnouncements.Controls.Add(panelAnnouncementsFunctions);
|
||||||
tpAnnouncements.Controls.Add(lbAnnouncements);
|
tpAnnouncements.Controls.Add(lbAnnouncements);
|
||||||
tpAnnouncements.Location = new Point(4, 24);
|
tpAnnouncements.Location = new Point(4, 24);
|
||||||
tpAnnouncements.Name = "tpAnnouncements";
|
tpAnnouncements.Name = "tpAnnouncements";
|
||||||
@@ -159,27 +170,17 @@
|
|||||||
tpAnnouncements.Text = "Announcements";
|
tpAnnouncements.Text = "Announcements";
|
||||||
tpAnnouncements.UseVisualStyleBackColor = true;
|
tpAnnouncements.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// lbAnnouncements
|
// panelAnnouncementsFunctions
|
||||||
//
|
//
|
||||||
lbAnnouncements.Dock = DockStyle.Fill;
|
panelAnnouncementsFunctions.Controls.Add(btnNewAnnouncement);
|
||||||
lbAnnouncements.FormattingEnabled = true;
|
panelAnnouncementsFunctions.Controls.Add(btnDeleteAnnouncement);
|
||||||
lbAnnouncements.ItemHeight = 15;
|
panelAnnouncementsFunctions.Controls.Add(btnViewAnnouncement);
|
||||||
lbAnnouncements.Location = new Point(3, 3);
|
panelAnnouncementsFunctions.Controls.Add(btnEditAnnouncement);
|
||||||
lbAnnouncements.Name = "lbAnnouncements";
|
panelAnnouncementsFunctions.Dock = DockStyle.Bottom;
|
||||||
lbAnnouncements.Size = new Size(717, 334);
|
panelAnnouncementsFunctions.Location = new Point(3, 298);
|
||||||
lbAnnouncements.TabIndex = 0;
|
panelAnnouncementsFunctions.Name = "panelAnnouncementsFunctions";
|
||||||
//
|
panelAnnouncementsFunctions.Size = new Size(717, 39);
|
||||||
// panel1
|
panelAnnouncementsFunctions.TabIndex = 7;
|
||||||
//
|
|
||||||
panel1.Controls.Add(btnNewAnnouncement);
|
|
||||||
panel1.Controls.Add(btnDeleteAnnouncement);
|
|
||||||
panel1.Controls.Add(btnViewAnnouncement);
|
|
||||||
panel1.Controls.Add(btnEditAnnouncement);
|
|
||||||
panel1.Dock = DockStyle.Bottom;
|
|
||||||
panel1.Location = new Point(3, 298);
|
|
||||||
panel1.Name = "panel1";
|
|
||||||
panel1.Size = new Size(717, 39);
|
|
||||||
panel1.TabIndex = 7;
|
|
||||||
//
|
//
|
||||||
// btnNewAnnouncement
|
// btnNewAnnouncement
|
||||||
//
|
//
|
||||||
@@ -221,6 +222,87 @@
|
|||||||
btnEditAnnouncement.UseVisualStyleBackColor = true;
|
btnEditAnnouncement.UseVisualStyleBackColor = true;
|
||||||
btnEditAnnouncement.Click += btnEditAnnouncement_Click;
|
btnEditAnnouncement.Click += btnEditAnnouncement_Click;
|
||||||
//
|
//
|
||||||
|
// lbAnnouncements
|
||||||
|
//
|
||||||
|
lbAnnouncements.Dock = DockStyle.Fill;
|
||||||
|
lbAnnouncements.FormattingEnabled = true;
|
||||||
|
lbAnnouncements.ItemHeight = 15;
|
||||||
|
lbAnnouncements.Location = new Point(3, 3);
|
||||||
|
lbAnnouncements.Name = "lbAnnouncements";
|
||||||
|
lbAnnouncements.Size = new Size(717, 334);
|
||||||
|
lbAnnouncements.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// tpComplaints
|
||||||
|
//
|
||||||
|
tpComplaints.Controls.Add(panelComplaintFunctions);
|
||||||
|
tpComplaints.Controls.Add(lbComplaints);
|
||||||
|
tpComplaints.Location = new Point(4, 24);
|
||||||
|
tpComplaints.Name = "tpComplaints";
|
||||||
|
tpComplaints.Size = new Size(723, 340);
|
||||||
|
tpComplaints.TabIndex = 2;
|
||||||
|
tpComplaints.Text = "Complaints";
|
||||||
|
tpComplaints.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// tpEvents
|
||||||
|
//
|
||||||
|
tpEvents.Location = new Point(4, 24);
|
||||||
|
tpEvents.Name = "tpEvents";
|
||||||
|
tpEvents.Size = new Size(723, 340);
|
||||||
|
tpEvents.TabIndex = 3;
|
||||||
|
tpEvents.Text = "Events";
|
||||||
|
tpEvents.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// lbComplaints
|
||||||
|
//
|
||||||
|
lbComplaints.Dock = DockStyle.Top;
|
||||||
|
lbComplaints.FormattingEnabled = true;
|
||||||
|
lbComplaints.ItemHeight = 15;
|
||||||
|
lbComplaints.Location = new Point(0, 0);
|
||||||
|
lbComplaints.Name = "lbComplaints";
|
||||||
|
lbComplaints.Size = new Size(723, 289);
|
||||||
|
lbComplaints.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// panelComplaintFunctions
|
||||||
|
//
|
||||||
|
panelComplaintFunctions.Controls.Add(btnArchiveComplaint);
|
||||||
|
panelComplaintFunctions.Controls.Add(btnViewComplaint);
|
||||||
|
panelComplaintFunctions.Controls.Add(btnEditComplaint);
|
||||||
|
panelComplaintFunctions.Dock = DockStyle.Bottom;
|
||||||
|
panelComplaintFunctions.Location = new Point(0, 285);
|
||||||
|
panelComplaintFunctions.Name = "panelComplaintFunctions";
|
||||||
|
panelComplaintFunctions.Size = new Size(723, 55);
|
||||||
|
panelComplaintFunctions.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// btnArchiveComplaint
|
||||||
|
//
|
||||||
|
btnArchiveComplaint.Location = new Point(8, 10);
|
||||||
|
btnArchiveComplaint.Name = "btnArchiveComplaint";
|
||||||
|
btnArchiveComplaint.Size = new Size(75, 23);
|
||||||
|
btnArchiveComplaint.TabIndex = 7;
|
||||||
|
btnArchiveComplaint.Text = "Archive";
|
||||||
|
btnArchiveComplaint.UseVisualStyleBackColor = true;
|
||||||
|
btnArchiveComplaint.Click += btnArchiveComplaint_Click;
|
||||||
|
//
|
||||||
|
// btnViewComplaint
|
||||||
|
//
|
||||||
|
btnViewComplaint.Location = new Point(170, 10);
|
||||||
|
btnViewComplaint.Name = "btnViewComplaint";
|
||||||
|
btnViewComplaint.Size = new Size(75, 23);
|
||||||
|
btnViewComplaint.TabIndex = 9;
|
||||||
|
btnViewComplaint.Text = "View";
|
||||||
|
btnViewComplaint.UseVisualStyleBackColor = true;
|
||||||
|
btnViewComplaint.Click += btnViewComplaint_Click;
|
||||||
|
//
|
||||||
|
// btnEditComplaint
|
||||||
|
//
|
||||||
|
btnEditComplaint.Location = new Point(89, 10);
|
||||||
|
btnEditComplaint.Name = "btnEditComplaint";
|
||||||
|
btnEditComplaint.Size = new Size(75, 23);
|
||||||
|
btnEditComplaint.TabIndex = 8;
|
||||||
|
btnEditComplaint.Text = "Edit";
|
||||||
|
btnEditComplaint.UseVisualStyleBackColor = true;
|
||||||
|
btnEditComplaint.Click += btnEditComplaint_Click;
|
||||||
|
//
|
||||||
// Dashboard
|
// Dashboard
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
@@ -235,7 +317,9 @@
|
|||||||
tpUsers.ResumeLayout(false);
|
tpUsers.ResumeLayout(false);
|
||||||
panelUserFunctions.ResumeLayout(false);
|
panelUserFunctions.ResumeLayout(false);
|
||||||
tpAnnouncements.ResumeLayout(false);
|
tpAnnouncements.ResumeLayout(false);
|
||||||
panel1.ResumeLayout(false);
|
panelAnnouncementsFunctions.ResumeLayout(false);
|
||||||
|
tpComplaints.ResumeLayout(false);
|
||||||
|
panelComplaintFunctions.ResumeLayout(false);
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
}
|
}
|
||||||
@@ -252,11 +336,18 @@
|
|||||||
private TabPage tpUsers;
|
private TabPage tpUsers;
|
||||||
private TabPage tpAnnouncements;
|
private TabPage tpAnnouncements;
|
||||||
private Panel panelUserFunctions;
|
private Panel panelUserFunctions;
|
||||||
private Panel panel1;
|
private Panel panelAnnouncementsFunctions;
|
||||||
private Button btnNewAnnouncement;
|
private Button btnNewAnnouncement;
|
||||||
private Button btnDeleteAnnouncement;
|
private Button btnDeleteAnnouncement;
|
||||||
private Button btnViewAnnouncement;
|
private Button btnViewAnnouncement;
|
||||||
private Button btnEditAnnouncement;
|
private Button btnEditAnnouncement;
|
||||||
private ListBox lbAnnouncements;
|
private ListBox lbAnnouncements;
|
||||||
|
private TabPage tpComplaints;
|
||||||
|
private Panel panelComplaintFunctions;
|
||||||
|
private ListBox lbComplaints;
|
||||||
|
private TabPage tpEvents;
|
||||||
|
private Button btnArchiveComplaint;
|
||||||
|
private Button btnViewComplaint;
|
||||||
|
private Button btnEditComplaint;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,6 +31,7 @@ namespace WinForms
|
|||||||
btnNewAnnouncement.Enabled = false;
|
btnNewAnnouncement.Enabled = false;
|
||||||
btnDeleteAnnouncement.Enabled = false;
|
btnDeleteAnnouncement.Enabled = false;
|
||||||
btnEditAnnouncement.Enabled = true;
|
btnEditAnnouncement.Enabled = true;
|
||||||
|
btnEditComplaint.Enabled = false;
|
||||||
}
|
}
|
||||||
else if (user.Role == UserRole.ADMIN)
|
else if (user.Role == UserRole.ADMIN)
|
||||||
{
|
{
|
||||||
@@ -40,6 +41,7 @@ namespace WinForms
|
|||||||
btnNewAnnouncement.Enabled = true;
|
btnNewAnnouncement.Enabled = true;
|
||||||
btnDeleteAnnouncement.Enabled = true;
|
btnDeleteAnnouncement.Enabled = true;
|
||||||
btnEditAnnouncement.Enabled = true;
|
btnEditAnnouncement.Enabled = true;
|
||||||
|
btnEditComplaint.Enabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -49,6 +51,7 @@ namespace WinForms
|
|||||||
btnNewAnnouncement.Enabled = false;
|
btnNewAnnouncement.Enabled = false;
|
||||||
btnDeleteAnnouncement.Enabled = false;
|
btnDeleteAnnouncement.Enabled = false;
|
||||||
btnEditAnnouncement.Enabled = false;
|
btnEditAnnouncement.Enabled = false;
|
||||||
|
btnEditComplaint.Enabled = false;
|
||||||
}
|
}
|
||||||
RefreshLists();
|
RefreshLists();
|
||||||
}
|
}
|
||||||
@@ -120,6 +123,12 @@ namespace WinForms
|
|||||||
{
|
{
|
||||||
lbAnnouncements.Items.Add(announcement);
|
lbAnnouncements.Items.Add(announcement);
|
||||||
}
|
}
|
||||||
|
ComplaintManager complaintManager = new ComplaintManager(new ComplaintRepository());
|
||||||
|
lbComplaints.Items.Clear();
|
||||||
|
foreach (Complaint complaint in complaintManager.GetAllComplaints())
|
||||||
|
{
|
||||||
|
lbComplaints.Items.Add(complaint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Dashboard_FormClosed(object sender, FormClosedEventArgs e)
|
private void Dashboard_FormClosed(object sender, FormClosedEventArgs e)
|
||||||
@@ -180,5 +189,52 @@ namespace WinForms
|
|||||||
RefreshLists();
|
RefreshLists();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnArchiveComplaint_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lbComplaints.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Complaint currentComplaint = (Complaint)lbComplaints.SelectedItem;
|
||||||
|
if (MessageBox.Show($"Are you sure you want to archive\n{currentComplaint.Title}\nCreated at {currentComplaint.PublishDate.ToString("g")} by {currentComplaint.Author.Name}",
|
||||||
|
"Archive complaint", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
AnnouncementManager announcementManager = new AnnouncementManager(new AnnouncementRepository());
|
||||||
|
announcementManager.DeleteAnnouncement(currentComplaint.ID);
|
||||||
|
}
|
||||||
|
RefreshLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnEditComplaint_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lbComplaints.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplaintForm complaintForm = new ComplaintForm((Complaint)lbComplaints.SelectedItem, false, user);
|
||||||
|
complaintForm.ShowDialog();
|
||||||
|
RefreshLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnViewComplaint_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lbComplaints.SelectedIndex == -1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please select an item from the list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplaintForm complaintForm = new ComplaintForm((Complaint)lbComplaints.SelectedItem, true, user);
|
||||||
|
complaintForm.ShowDialog();
|
||||||
|
RefreshLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,64 @@
|
|||||||
<root>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
@@ -19,6 +19,10 @@ namespace WinForms
|
|||||||
{
|
{
|
||||||
MessageBox.Show("Wrong username or password", "Login failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("Wrong username or password", "Login failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
|
/*else if (user.Role == UserRole.TENANT)
|
||||||
|
{
|
||||||
|
MessageBox.Show("This application is for the management. Please use the web portal", "Access denied", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Dashboard dashboard = new Dashboard(this, user);
|
Dashboard dashboard = new Dashboard(this, user);
|
||||||
|
@@ -16,6 +16,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Update="ComplaintForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Update="AnnouncementForm.cs">
|
<Compile Update="AnnouncementForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
BIN
docs/testplan.docx
Normal file
BIN
docs/testplan.docx
Normal file
Binary file not shown.
22
queries.sql
22
queries.sql
@@ -10,9 +10,25 @@ GO
|
|||||||
|
|
||||||
INSERT INTO Users ([Name], [Password], [Role])
|
INSERT INTO Users ([Name], [Password], [Role])
|
||||||
VALUES
|
VALUES
|
||||||
('Admin', '1234', 2),
|
('admin', 'admin', 2),
|
||||||
('Manager', '1234', 1),
|
('manager', 'manager', 1),
|
||||||
('Room1', '1234', 0)
|
('room1', 'room1', 0)
|
||||||
|
GO
|
||||||
|
|
||||||
|
INSERT INTO ComplaintStatus ([Status])
|
||||||
|
VALUES
|
||||||
|
('FILED'),
|
||||||
|
('UNDER_REVIEW'),
|
||||||
|
('SOLVED'),
|
||||||
|
('ARCHIVED')
|
||||||
|
GO
|
||||||
|
|
||||||
|
INSERT INTO ComplaintSeverity ([Severity])
|
||||||
|
VALUES
|
||||||
|
('LOW'),
|
||||||
|
('NORMAL'),
|
||||||
|
('HIGH'),
|
||||||
|
('URGENT')
|
||||||
GO
|
GO
|
||||||
|
|
||||||
SELECT * FROM Users u JOIN UserRole r ON u.[Role] = r.ID
|
SELECT * FROM Users u JOIN UserRole r ON u.[Role] = r.ID
|
29
table.sql
29
table.sql
@@ -52,4 +52,33 @@ CREATE TABLE CommentsResponses (
|
|||||||
CommentID INT FOREIGN KEY REFERENCES Comments(ID) NOT NULL,
|
CommentID INT FOREIGN KEY REFERENCES Comments(ID) NOT NULL,
|
||||||
ResponseID INT FOREIGN KEY REFERENCES Comments(ID) NOT NULL
|
ResponseID INT FOREIGN KEY REFERENCES Comments(ID) NOT NULL
|
||||||
)
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE ComplaintStatus (
|
||||||
|
ID INT PRIMARY KEY IDENTITY(0,1) NOT NULL,
|
||||||
|
[Status] NVARCHAR(255)
|
||||||
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE ComplaintSeverity (
|
||||||
|
ID INT PRIMARY KEY IDENTITY(0,1) NOT NULL,
|
||||||
|
[Severity] NVARCHAR(255)
|
||||||
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE Complaints (
|
||||||
|
ID INT PRIMARY KEY IDENTITY NOT NULL,
|
||||||
|
[Author] INT FOREIGN KEY REFERENCES Users(ID) NOT NULL,
|
||||||
|
[Description] NVARCHAR(MAX),
|
||||||
|
[Title] NVARCHAR(255) NOT NULL,
|
||||||
|
[PublishDate] DATETIME NOT NULL,
|
||||||
|
[Status] INT FOREIGN KEY REFERENCES ComplaintStatus(ID) NOT NULL
|
||||||
|
[Severity] INT FOREIGN KEY REFERENCES ComplaintSeverity(ID) NOT NULL
|
||||||
|
)
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE ComplaintsComments (
|
||||||
|
ComplaintID INT FOREIGN KEY REFERENCES Complaints(ID) NOT NULL,
|
||||||
|
CommentID INT FOREIGN KEY REFERENCES Comments(ID) NOT NULL
|
||||||
|
)
|
||||||
GO
|
GO
|
Reference in New Issue
Block a user