Compare commits
No commits in common. "3e0414ad1a7bc7368281f3bdf9e073f1fac0bf7a" and "30c3fbcadc472d94d007efae23bf6b59e134e678" have entirely different histories.
3e0414ad1a
...
30c3fbcadc
|
@ -568,164 +568,5 @@ namespace FIT5032_Assignment.Controllers {
|
||||||
ViewBag.image = image;
|
ViewBag.image = image;
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Review(string id) {
|
|
||||||
// Check login
|
|
||||||
if (Request.Cookies["psg_auth_token"] == null) {
|
|
||||||
// Redirect to home page
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
var user = psgCredentialVerify(Request.Cookies["psg_auth_token"].Value);
|
|
||||||
if (user == null) {
|
|
||||||
// Redirect to home page
|
|
||||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
var userProfile = loginInfo(user);
|
|
||||||
if (userProfile == null) {
|
|
||||||
// Redirect to home page, and remove cookies
|
|
||||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
// Detect user role
|
|
||||||
ViewBag.role = db.Users.Find(userProfile.uuid).role;
|
|
||||||
|
|
||||||
// Only patient can review appointment, but doctor can view
|
|
||||||
/*if (userProfile.role != 1) {
|
|
||||||
TempData["tip"] = "This operation is not allowed.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Check if the appointment is belong to the doctor or patient
|
|
||||||
var appointment = db.Appointments.Find(id);
|
|
||||||
if (appointment == null) {
|
|
||||||
TempData["tip"] = "The appointment does not exist.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
if (appointment.patient != userProfile.uuid && appointment.responsibleBy != userProfile.uuid) {
|
|
||||||
TempData["tip"] = "The appointment does not exist.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check status == 2
|
|
||||||
if (appointment.status != 2) {
|
|
||||||
TempData["tip"] = "Operation invalid";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewBag.appointment = appointment;
|
|
||||||
|
|
||||||
// Fetch doctor profile
|
|
||||||
ViewBag.doctor = db.Doctors.Where(d => d.user == appointment.responsibleBy);
|
|
||||||
ViewBag.doctorUser = db.Users.Find(appointment.responsibleBy);
|
|
||||||
|
|
||||||
// Fetch patient profile
|
|
||||||
ViewBag.patient = db.Users.Find(appointment.patient);
|
|
||||||
|
|
||||||
// Fetch review if exist
|
|
||||||
var review = db.Reviews.Where(r => r.appointment == id);
|
|
||||||
if (review.Count() != 0) {
|
|
||||||
ViewBag.review = review.First();
|
|
||||||
ViewBag.reviewAvailable = true;
|
|
||||||
} else {
|
|
||||||
ViewBag.reviewAvailable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
public ActionResult Review(FormCollection collection) {
|
|
||||||
Trace.WriteLine(collection["appointment"]);
|
|
||||||
|
|
||||||
// Verify login
|
|
||||||
if (Request.Cookies["psg_auth_token"] == null) {
|
|
||||||
// Redirect to home page
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
var user = psgCredentialVerify(Request.Cookies["psg_auth_token"].Value);
|
|
||||||
if (user == null) {
|
|
||||||
// Redirect to home page
|
|
||||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
|
||||||
return RedirectToAction("Index");
|
|
||||||
}
|
|
||||||
var userProfile = loginInfo(user);
|
|
||||||
if (userProfile == null) {
|
|
||||||
// Redirect to home page, and remove cookies
|
|
||||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
|
||||||
return RedirectToAction("Index", "Home");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect if user logined is patient
|
|
||||||
var role = db.Users.Find(userProfile.uuid).role;
|
|
||||||
if (role != 1) {
|
|
||||||
// Redirect to home page
|
|
||||||
TempData["tip"] = "Operation invalid";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the appointment is belong to the doctor or patient
|
|
||||||
var appointment = db.Appointments.Find(collection["appointment"]);
|
|
||||||
if (appointment == null) {
|
|
||||||
TempData["tip"] = "The appointment does not exist.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
if (appointment.patient != userProfile.uuid && appointment.responsibleBy != userProfile.uuid) {
|
|
||||||
TempData["tip"] = "The appointment does not exist.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check status == 2
|
|
||||||
if (appointment.status != 2) {
|
|
||||||
TempData["tip"] = "Operation invalid";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the review exist
|
|
||||||
try {
|
|
||||||
var review = db.Reviews.Find(collection["appointment"]);
|
|
||||||
Trace.WriteLine(review);
|
|
||||||
if (review != null) {
|
|
||||||
TempData["tip"] = "You cannot append a new review to this appointment.";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
} catch(Exception e) {
|
|
||||||
Trace.WriteLine(e);
|
|
||||||
TempData["tip"] = "System error";
|
|
||||||
return Redirect("/Appointments/Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent XSS attack
|
|
||||||
// Replace with < and >
|
|
||||||
var comment = collection["comment"];
|
|
||||||
comment = comment.Replace("<", "<");
|
|
||||||
comment = comment.Replace(">", ">");
|
|
||||||
|
|
||||||
// Prevent SQL injection
|
|
||||||
comment = comment.Replace("'", "''");
|
|
||||||
|
|
||||||
// Create review
|
|
||||||
var uuid = Guid.NewGuid().ToString();
|
|
||||||
Reviews newReview = new Reviews {
|
|
||||||
appointment = collection["appointment"],
|
|
||||||
patient = userProfile.uuid,
|
|
||||||
doctor = appointment.responsibleBy,
|
|
||||||
score = Convert.ToInt32(collection["score"]),
|
|
||||||
comment = comment,
|
|
||||||
reviewAt = DateTime.Now,
|
|
||||||
};
|
|
||||||
db.Reviews.Add(newReview);
|
|
||||||
db.SaveChanges();
|
|
||||||
|
|
||||||
ViewBag.role = role;
|
|
||||||
ViewBag.appointment = appointment;
|
|
||||||
ViewBag.doctor = db.Doctors.Where(d => d.user == appointment.responsibleBy);
|
|
||||||
ViewBag.doctorUser = db.Users.Find(appointment.responsibleBy);
|
|
||||||
ViewBag.patient = db.Users.Find(appointment.patient);
|
|
||||||
ViewBag.review = newReview;
|
|
||||||
ViewBag.reviewAvailable = true;
|
|
||||||
ViewBag.tip = "Thanks for submit your review!";
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ namespace FIT5032_Assignment.Controllers {
|
||||||
public DbSet<Doctors> Doctors { get; set; }
|
public DbSet<Doctors> Doctors { get; set; }
|
||||||
public DbSet<Appointments> Appointments { get; set; }
|
public DbSet<Appointments> Appointments { get; set; }
|
||||||
public DbSet<Images> Images { get; set; }
|
public DbSet<Images> Images { get; set; }
|
||||||
public DbSet<Reviews> Reviews { get; set; }
|
|
||||||
}
|
}
|
||||||
public class HomeController : Controller {
|
public class HomeController : Controller {
|
||||||
public static string GetMd5Hash(string input) {
|
public static string GetMd5Hash(string input) {
|
||||||
|
|
|
@ -13,18 +13,9 @@ namespace FIT5032_Assignment.Controllers {
|
||||||
if (!System.IO.File.Exists(filePath)) {
|
if (!System.IO.File.Exists(filePath)) {
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
}
|
}
|
||||||
// Read binary data from the file
|
var fileContent = System.IO.File.ReadAllText(filePath);
|
||||||
byte[] fileBytes = System.IO.File.ReadAllBytes(filePath);
|
var contentType = MimeMapping.GetMimeMapping(fileName);
|
||||||
|
return File(fileContent, contentType);
|
||||||
// The binary file may png, jpg or jpeg
|
|
||||||
var fileExtension = Path.GetExtension(filePath).ToLowerInvariant();
|
|
||||||
// Set the MIME type
|
|
||||||
if (fileExtension == ".png") {
|
|
||||||
return File(fileBytes, "image/png");
|
|
||||||
} else if (fileExtension == ".jpg" || fileExtension == ".jpeg") {
|
|
||||||
return File(fileBytes, "image/jpeg");
|
|
||||||
}
|
|
||||||
return HttpNotFound();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -325,7 +325,6 @@
|
||||||
<Content Include="Views\Appointments\Create.cshtml" />
|
<Content Include="Views\Appointments\Create.cshtml" />
|
||||||
<Content Include="Views\Appointments\UploadImage.cshtml" />
|
<Content Include="Views\Appointments\UploadImage.cshtml" />
|
||||||
<Content Include="Views\Appointments\Detail.cshtml" />
|
<Content Include="Views\Appointments\Detail.cshtml" />
|
||||||
<Content Include="Views\Appointments\Review.cshtml" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="App_Data\upload_images\" />
|
<Folder Include="App_Data\upload_images\" />
|
||||||
|
|
|
@ -48,26 +48,10 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="field-title">Attached image</div>
|
<div class="field-title">Attached image</div>
|
||||||
<div class="field-content">
|
<div class="field-content">
|
||||||
<img class="field-content-image" src="/System/GetUploadedImage?fileName=@ViewBag.image.file" />
|
<img src="/System/GetUploadedImage?fileName=@ViewBag.image.file" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<hr>
|
|
||||||
<h3>Operations</h3>
|
|
||||||
@if (ViewBag.appointment.status == 0) {
|
|
||||||
// Cancel
|
|
||||||
<a class="btn btn-light" href="../Cancel/@ViewBag.appointment.uuid">Cancel</a>
|
|
||||||
if (ViewBag.role == 2) {
|
|
||||||
// Approve
|
|
||||||
<a class="btn btn-light" href="../Approve/@ViewBag.appointment.uuid">Approve</a>
|
|
||||||
}
|
|
||||||
} else if (ViewBag.appointment.status == 1 && ViewBag.role == 2) {
|
|
||||||
<a href="../UploadImage/@ViewBag.appointment.uuid" class="btn btn-sm btn-primary">Upload Image</a>
|
|
||||||
} else if (ViewBag.appointment.status == 2 && ViewBag.role == 1) {
|
|
||||||
<a href="../Review/@ViewBag.appointment.uuid" class="btn btn-sm btn-primary">Rate your experience</a>
|
|
||||||
} else {
|
|
||||||
<i>No operation available</i>
|
|
||||||
}
|
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<style>
|
<style>
|
||||||
|
@ -90,9 +74,6 @@
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.field .field-content img.field-content-image {
|
|
||||||
max-width: 60%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
|
|
@ -48,8 +48,6 @@
|
||||||
<td>
|
<td>
|
||||||
@if (item.Item1.status == 0) {
|
@if (item.Item1.status == 0) {
|
||||||
<a href='./Cancel/@item.Item1.uuid' class="btn btn-sm btn-danger">Cancel</a>
|
<a href='./Cancel/@item.Item1.uuid' class="btn btn-sm btn-danger">Cancel</a>
|
||||||
} else if (item.Item1.status == 2) {
|
|
||||||
<a href="./Detail/@item.Item1.uuid" class="btn btn-sm btn-primary">Detail</a>
|
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
|
|
||||||
@{
|
|
||||||
ViewBag.Title = "Review";
|
|
||||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (ViewBag.tip != null) {
|
|
||||||
<div class="alert alert-success" role="alert">
|
|
||||||
@ViewBag.tip
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<h2>Rate the experience</h2>
|
|
||||||
|
|
||||||
@if (ViewBag.role == 1 && ViewBag.reviewAvailable == false) {
|
|
||||||
<p>You are about to review the Doctor <b>@ViewBag.doctorUser.displayName</b></p>
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" id="appointment" name="appointment" required value="@ViewBag.appointment.uuid" />
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="score">How about your experience?</label>
|
|
||||||
<input type="hidden" id="score" name="score" required />
|
|
||||||
<button class="btn btn-light" id="btn-good" onClick="rate(1)" type="button">
|
|
||||||
<span class="material-symbols-outlined">
|
|
||||||
thumb_up
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-light" id="btn-bad" onClick="rate(0)" type="button">
|
|
||||||
<span class="material-symbols-outlined">
|
|
||||||
thumb_down
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="comment">Leave your comment</label>
|
|
||||||
<div class='input-group'>
|
|
||||||
<textarea id="comment" class="form-control" name="comment"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary" type="submit">Submit</button>
|
|
||||||
</form>
|
|
||||||
} else {
|
|
||||||
if (ViewBag.reviewAvailable == false) {
|
|
||||||
<p>Review not available yet.</p>
|
|
||||||
} else {
|
|
||||||
<div class="review">
|
|
||||||
<div><img src="@ViewBag.patient.avatar" style="width: 30px; border-radius: 50%; margin-right: 10px;" /><b>@ViewBag.patient.displayName</b> already reviewed this appointment.</div>
|
|
||||||
<div>
|
|
||||||
@if (ViewBag.review.score == 1) {
|
|
||||||
<span style="color: green;"><span class="material-symbols-outlined">thumb_up</span> <b>Recommended</b></span>
|
|
||||||
} else {
|
|
||||||
<span style="color: red;"><span class="material-symbols-outlined">thumb_down</span> <b>Not Recommended</b></span>
|
|
||||||
}
|
|
||||||
<span>@ViewBag.review.comment</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@section Scripts {
|
|
||||||
@Styles.Render("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200")
|
|
||||||
<style>
|
|
||||||
.material-symbols-outlined {
|
|
||||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
/* Spacing between elements inside .review */
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function rate(score) {
|
|
||||||
$("#score").val(score)
|
|
||||||
if (score == 1) {
|
|
||||||
$("#btn-good").removeClass("btn-light")
|
|
||||||
$("#btn-good").addClass("btn-success")
|
|
||||||
$("#btn-bad").removeClass("btn-danger")
|
|
||||||
$("#btn-bad").addClass("btn-light")
|
|
||||||
} else {
|
|
||||||
$("#btn-good").removeClass("btn-success")
|
|
||||||
$("#btn-good").addClass("btn-light")
|
|
||||||
$("#btn-bad").removeClass("btn-light")
|
|
||||||
$("#btn-bad").addClass("btn-danger")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (@ViewBag.reviewAvailable === "True") {
|
|
||||||
alert("Review available")
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user