Besciamello (#1)
* Fixed login & auth * Added dynamic breadcrumb * Added DOC * Added Patient * Added Notifications * Added Messages * Refactoring api * Re-writed menu * Removed unused things * Created README
This commit was merged in pull request #1.
This commit is contained in:
committed by
GitHub
parent
191daf8218
commit
1246116804
4
.gitignore
vendored
4
.gitignore
vendored
@@ -260,4 +260,6 @@ paket-files/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
SeniorAssistant/SeniorAssistant/wwwroot/*
|
||||
SeniorAssistant/SeniorAssistant/wwwroot/*
|
||||
/SeniorAssistant/Controllers/TestController.cs
|
||||
/SeniorAssistant/Views/Test/*
|
||||
|
||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# SeniorAssistant
|
||||
Parte del progetto SeniorAssistant che riguarda l'interazione con persone esterne oltre ad un server che raccoglie i dati
|
||||
|
||||
## Funzionalita'
|
||||
Dopo aver fatto login/essersi registrati Dottore e Paziente possono accedere alle seguenti funzionalità:
|
||||
|
||||
#### Paziente
|
||||
- Scegliere il proprio dottore
|
||||
- Visualizzare i propri dati anagrafici
|
||||
- Visualizzare i propri dati "vitali"
|
||||
- Inviare messaggi al proprio dottore
|
||||
|
||||
#### Dottore
|
||||
- Selezionare un paziente fra i propri pazienti
|
||||
- Visualizzarne dati anagrafici e vitali
|
||||
- Aggiungere al paziente note (es malattie croniche, allergie ecc)
|
||||
- Visualizzare notifiche prodotte dal paziente
|
||||
- Inviare messaggi al paziente
|
||||
@@ -4,65 +4,46 @@ using SeniorAssistant.Models;
|
||||
using SeniorAssistant.Controllers;
|
||||
using LinqToDB;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using SeniorAssistant.Models.Users;
|
||||
|
||||
namespace IdentityDemo.Controllers
|
||||
{
|
||||
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[Route("[controller]/[action]")]
|
||||
public class AccountController : BaseController
|
||||
{
|
||||
/*
|
||||
private readonly UserManager<User> _userManager;
|
||||
private readonly SignInManager<User> _signInManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public AccountController(
|
||||
UserManager<User> userManager,
|
||||
SignInManager<User> signInManager,
|
||||
ILogger<AccountController> logger)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
_logger = logger;
|
||||
}
|
||||
/*
|
||||
[TempData]
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Login(string returnUrl = null)
|
||||
{
|
||||
// Clear the existing external cookie to ensure a clean login process
|
||||
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
return View();
|
||||
}
|
||||
*/
|
||||
private static readonly string NoteModified = "Il tuo dottore ha modificato la nota per te";
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _login(string username, string password)
|
||||
{
|
||||
JsonResponse response = new JsonResponse();
|
||||
response.Success = false;
|
||||
response.Message = "Username or password is invalid.";
|
||||
|
||||
var strunz = Db.GetTable<User>().Where(user => user.Username.Equals(username) && user.Password.Equals(password)).ToListAsync().Result;
|
||||
|
||||
if (strunz.Count == 1)
|
||||
JsonResponse response = new JsonResponse
|
||||
{
|
||||
var loggedUser = HttpContext.Session.GetString("username");
|
||||
if (loggedUser==null || !loggedUser.Equals(username))
|
||||
Success = false,
|
||||
Message = "Username or password is invalid."
|
||||
};
|
||||
|
||||
var result = Db.GetTable<User>().Where(user => user.Username.Equals(username) && user.Password.Equals(password)).ToListAsync().Result;
|
||||
|
||||
if (result.Count == 1)
|
||||
{
|
||||
var loggedUser = HttpContext.Session.GetString(Username);
|
||||
if (loggedUser==null || !loggedUser.Equals(username)) // non ha senso
|
||||
{
|
||||
HttpContext.Session.SetString("username", username);
|
||||
HttpContext.Session.SetString("email", strunz.First().Email);
|
||||
HttpContext.Session.SetString("name", strunz.First().Name);
|
||||
HttpContext.Session.SetString("isdoc", strunz.First().Doctor?"true":"false");
|
||||
//HttpContext.Session.SetString("lastname", strunz.First().LastName);
|
||||
User user = result.First();
|
||||
HttpContext.Session.SetString(Username, username);
|
||||
HttpContext.Session.SetString("email", user.Email);
|
||||
HttpContext.Session.SetString("name", user.Name);
|
||||
HttpContext.Session.SetString("lastname", user.LastName);
|
||||
|
||||
var isDoc = (from d in Db.Doctors
|
||||
where d.Username.Equals(username)
|
||||
select d).ToArray().FirstOrDefault() != null;
|
||||
HttpContext.Session.SetString("role", isDoc? "doctor":"patient");
|
||||
|
||||
response.Success = true;
|
||||
response.Message = "";
|
||||
response.Message = Request.Query["ReturnUrl"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -80,28 +61,125 @@ namespace IdentityDemo.Controllers
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _register(Register register)
|
||||
public ActionResult _register(User user)
|
||||
{
|
||||
if(ModelState.IsValid)
|
||||
return Action(() =>
|
||||
{
|
||||
User user = new User() { Username = register.Username, Email = register.Email, Password = register.Password};
|
||||
try
|
||||
{
|
||||
Db.Insert(user);
|
||||
return _login(user.Username, user.Password);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Json(new JsonResponse() { Success = false, Message = "Username already exist" });
|
||||
return Json(new JsonResponse(false, "Username already exists"));
|
||||
}
|
||||
_login(user.Username, user.Password);
|
||||
return Json(new JsonResponse() { Success = true });
|
||||
}
|
||||
return Json(new JsonResponse() { Success = false, Message = "Modello non valido" });
|
||||
});
|
||||
}
|
||||
internal class JsonResponse
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _notification(string username, string message)
|
||||
{
|
||||
public bool Success { get; internal set; }
|
||||
public string Message { get; internal set; }
|
||||
return LoggedAction(() =>
|
||||
{
|
||||
Db.Insert(new Notification()
|
||||
{
|
||||
Message = message,
|
||||
Username = username,
|
||||
Time = DateTime.Now,
|
||||
Seen = false
|
||||
});
|
||||
return Json(OkJson);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public ActionResult _notification(int id)
|
||||
{
|
||||
return LoggedAction(() =>
|
||||
{
|
||||
JsonResponse response = OkJson;
|
||||
|
||||
Notification note = Db.Notifications.Where(n => n.Id == id).ToArray().FirstOrDefault();
|
||||
if(note != null)
|
||||
{
|
||||
note.Seen = true;
|
||||
Db.Update(note);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.Success = false;
|
||||
response.Message = "La notifica da modificare non esiste";
|
||||
}
|
||||
return Json(response);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _addDoc(string doctor)
|
||||
{
|
||||
return LoggedAction(() =>
|
||||
{
|
||||
string username = HttpContext.Session.GetString(Username);
|
||||
var isAlreadyPatient = Db.Patients.Where(p => p.Username.Equals(username)).ToArray().FirstOrDefault() != null;
|
||||
if (isAlreadyPatient)
|
||||
return Json(new JsonResponse()
|
||||
{
|
||||
Success = false,
|
||||
Message = "You are already a patient"
|
||||
});
|
||||
|
||||
var docExist = Db.Doctors.Where(d => d.Username.Equals(doctor)).ToArray().FirstOrDefault() != null;
|
||||
if(!docExist)
|
||||
return Json(new JsonResponse()
|
||||
{
|
||||
Success = false,
|
||||
Message = "Doctor doesn't exist"
|
||||
});
|
||||
|
||||
Db.Insert(new Patient()
|
||||
{
|
||||
Doctor = doctor,
|
||||
Username = username
|
||||
});
|
||||
|
||||
_notification(doctor, "L'utente "+username+" ti ha inserito come il suo dottore.");
|
||||
return Json(new JsonResponse());
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult _sendMessage(string reciver, string body)
|
||||
{
|
||||
return LoggedAction(() => {
|
||||
string username = HttpContext.Session.GetString(Username);
|
||||
Message message = new Message()
|
||||
{
|
||||
Reciver = reciver,
|
||||
Body = body,
|
||||
Time = DateTime.Now,
|
||||
Username = username,
|
||||
Seen = false
|
||||
};
|
||||
|
||||
Db.Insert(message);
|
||||
|
||||
return Json(new JsonResponse());
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public ActionResult _addNote(string patient, string text)
|
||||
{
|
||||
return LoggedAccessDataOf(patient, () =>
|
||||
{
|
||||
var pat = Db.Patients.Where((p) => p.Username.Equals(patient)).FirstOrDefault();
|
||||
pat.Notes = text;
|
||||
Db.Update(pat);
|
||||
_notification(patient, NoteModified);
|
||||
|
||||
return Json(OkJson);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,10 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace SeniorAssistant.Controllers
|
||||
{
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public class HomeController : Controller
|
||||
public class HomeController : BaseController
|
||||
{
|
||||
private readonly ISession session;
|
||||
public HomeController(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this.session = httpContextAccessor.HttpContext.Session;
|
||||
}
|
||||
|
||||
[Route("")]
|
||||
[Route("Home")]
|
||||
[Route("Index")]
|
||||
@@ -23,31 +16,47 @@ namespace SeniorAssistant.Controllers
|
||||
[Route("Heartbeat")]
|
||||
public IActionResult Heartbeat()
|
||||
{
|
||||
return View();
|
||||
return CheckAuthorized("Heartbeat");
|
||||
}
|
||||
|
||||
[Route("Sleep")]
|
||||
public IActionResult Sleep()
|
||||
{
|
||||
return View();
|
||||
return CheckAuthorized("Sleep");
|
||||
}
|
||||
|
||||
[Route("Step")]
|
||||
public IActionResult Step()
|
||||
{
|
||||
return View();
|
||||
return CheckAuthorized("Step");
|
||||
}
|
||||
|
||||
[Route("Users")]
|
||||
public IActionResult Users()
|
||||
{
|
||||
return View();
|
||||
return CheckAuthorized("Users");
|
||||
}
|
||||
|
||||
[Route("User/{User}")]
|
||||
public IActionResult SingleUser(string user)
|
||||
{
|
||||
return View("data", user);
|
||||
return CheckAuthorized("Data", user);
|
||||
}
|
||||
|
||||
[Route("Message/{Id}")]
|
||||
public IActionResult Message(int id)
|
||||
{
|
||||
return CheckAuthorized("Message", id);
|
||||
}
|
||||
|
||||
private IActionResult CheckAuthorized(string view, object model = null)
|
||||
{
|
||||
if (!IsLogged())
|
||||
{
|
||||
model = "/" + view;
|
||||
view = "Index";
|
||||
}
|
||||
return View(view, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SeniorAssistant.Models;
|
||||
using SeniorAssistant.Models.Users;
|
||||
|
||||
namespace SeniorAssistant.Controllers.Services
|
||||
{
|
||||
@@ -18,4 +19,12 @@ namespace SeniorAssistant.Controllers.Services
|
||||
[Route("api/[controller]")]
|
||||
public class UserController : CrudController<User>
|
||||
{ }
|
||||
|
||||
[Route("api/[controller]")]
|
||||
public class PatientController : CrudController<Patient>
|
||||
{ }
|
||||
|
||||
[Route("api/[controller]")]
|
||||
public class DoctorController : CrudController<Doctor>
|
||||
{ }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SeniorAssistant.Data;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
namespace SeniorAssistant.Controllers
|
||||
{
|
||||
public abstract class BaseController : Controller
|
||||
{
|
||||
protected static readonly string MustBeLogged = "Devi essere loggato per vedere/modificare questo dato";
|
||||
protected static readonly string InvalidModel = "Modello non valido";
|
||||
protected static readonly string NoAuthorized = "Non sei autorizzato a vedere questi dati";
|
||||
protected static readonly string Username = "username";
|
||||
protected readonly JsonResponse OkJson = new JsonResponse();
|
||||
|
||||
IDataContextFactory<SeniorDataContext> dbFactory;
|
||||
SeniorDataContext db;
|
||||
|
||||
@@ -20,5 +29,68 @@ namespace SeniorAssistant.Controllers
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected bool IsLogged()
|
||||
{
|
||||
return HttpContext.Session.GetString(Username) != null;
|
||||
}
|
||||
|
||||
protected ActionResult Action(Func<ActionResult> success)
|
||||
{
|
||||
return ModelState.IsValid ?
|
||||
success.Invoke() :
|
||||
Json(new JsonResponse()
|
||||
{
|
||||
Success = false,
|
||||
Message = InvalidModel
|
||||
});
|
||||
}
|
||||
|
||||
protected ActionResult LoggedAction(Func<ActionResult> success)
|
||||
{
|
||||
return Action(() =>
|
||||
{
|
||||
return IsLogged() ?
|
||||
success.Invoke() :
|
||||
Json(new JsonResponse()
|
||||
{
|
||||
Success = false,
|
||||
Message = MustBeLogged
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected ActionResult LoggedAccessDataOf(string username, Func<ActionResult> success, bool patients = true)
|
||||
{
|
||||
return LoggedAction(() =>
|
||||
{
|
||||
var loggedUser = HttpContext.Session.GetString(Username);
|
||||
var condition = username.Equals(loggedUser);
|
||||
|
||||
condition = condition || (patients && (from patient in Db.Patients
|
||||
where patient.Doctor.Equals(loggedUser) && patient.Username.Equals(username)
|
||||
select patient).ToArray().FirstOrDefault() != null);
|
||||
|
||||
return condition ?
|
||||
success.Invoke() :
|
||||
Json(new JsonResponse()
|
||||
{
|
||||
Success = false,
|
||||
Message = NoAuthorized
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class JsonResponse
|
||||
{
|
||||
public JsonResponse(bool success=true, string message="")
|
||||
{
|
||||
Success = success;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,24 +10,24 @@ namespace SeniorAssistant.Controllers.Services
|
||||
public abstract class CrudController<TEntity> : BaseController
|
||||
where TEntity : class, IHasUsername
|
||||
{
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<TEntity>> Read() => await Db.GetTable<TEntity>().ToListAsync();
|
||||
|
||||
[HttpGet("{username}")]
|
||||
public async Task<TEntity> Read(string username) => await Db.GetTable<TEntity>().FirstOrDefaultAsync(c => c.Username.Equals(username));
|
||||
|
||||
[HttpPost]
|
||||
public async Task Create([FromBody]TEntity item) => await Db.InsertAsync(item);
|
||||
|
||||
[HttpPut("{username}")]
|
||||
public async Task Update(string username, [FromBody]TEntity item)
|
||||
public async Task<IActionResult> Read(string username)
|
||||
{
|
||||
item.Username = username;
|
||||
|
||||
await Db.UpdateAsync(item);
|
||||
return LoggedAccessDataOf(username, () =>
|
||||
{
|
||||
return Json(Db.GetTable<TEntity>().Where((u) => u.Username.Equals(username)).ToArray());
|
||||
});
|
||||
}
|
||||
|
||||
[HttpDelete("{username}")]
|
||||
public async Task Delete(string username) => await Db.GetTable<TEntity>().Where(c => c.Username.Equals(username)).DeleteAsync();
|
||||
[HttpPut("{username}")]
|
||||
public async Task<IActionResult> Update(string username, [FromBody] TEntity entity)
|
||||
{
|
||||
return LoggedAccessDataOf(username, () =>
|
||||
{
|
||||
entity.Username = username;
|
||||
Db.Update(entity);
|
||||
return Json(OkJson);
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,74 +2,86 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SeniorAssistant.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SeniorAssistant.Controllers.Services
|
||||
{
|
||||
public class CrudTimeController<TEntity> : BaseController
|
||||
public class CrudTimeController<TEntity> : CrudController<TEntity>
|
||||
where TEntity : class, IHasTime
|
||||
{
|
||||
static readonly object Empty = new { };
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<TEntity>> Read() => await Db.GetTable<TEntity>().ToListAsync();
|
||||
|
||||
[HttpGet("{username}")]
|
||||
public async Task<IEnumerable<TEntity>> Read(string username) => await Db.GetTable<TEntity>().Where(e => e.Username.Equals(username)).ToListAsync();
|
||||
private static readonly string DateNotCorrect = "Il formato della data non e' corretto";
|
||||
|
||||
[HttpGet("{username}/{date:regex((today|\\d{{4}}-\\d{{2}}-\\d{{2}}))}/{hour:range(0, 23)?}")]
|
||||
public async Task<IEnumerable<TEntity>> Read(string username, string date, int hour = -1) => await Read(username, date, date, hour);
|
||||
public async Task<IActionResult> Read(string username, string date, int hour = -1) => await Read(username, date, date, hour);
|
||||
|
||||
[HttpGet("{username}/{from:regex((today|\\d{{4}}-\\d{{2}}-\\d{{2}}))}/{to:regex((today|\\d{{4}}-\\d{{2}}-\\d{{2}}))}/{hour:range(0, 23)?}")]
|
||||
public async Task<IEnumerable<TEntity>> Read(string username, string from, string to, int hour = -1)
|
||||
public async Task<IActionResult> Read(string username, string from, string to, int hour = -1)
|
||||
{
|
||||
try
|
||||
return LoggedAccessDataOf(username, () =>
|
||||
{
|
||||
DateTime dateFrom = (from.Equals("today") ? DateTime.Now : DateTime.ParseExact(from, "yyyy-MM-dd", null));
|
||||
DateTime dateTo = (to.Equals("today") ? DateTime.Now : DateTime.ParseExact(to, "yyyy-MM-dd", null));
|
||||
try
|
||||
{
|
||||
DateTime dateFrom = (from.Equals("today") ? DateTime.Now : DateTime.ParseExact(from, "yyyy-MM-dd", null));
|
||||
DateTime dateTo = (to.Equals("today") ? DateTime.Now : DateTime.ParseExact(to, "yyyy-MM-dd", null));
|
||||
|
||||
return await Db.GetTable<TEntity>().Where(e => e.Username.Equals(username) && dateFrom.Date<=e.Time.Date && dateTo.Date>=e.Time.Date && (hour < 0 || e.Time.Hour == hour)).ToListAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<TEntity>();
|
||||
}
|
||||
return Json((from entity in Db.GetTable<TEntity>()
|
||||
where entity.Username.Equals(username)
|
||||
&& dateFrom.Date <= entity.Time.Date
|
||||
&& dateTo.Date >= entity.Time.Date
|
||||
&& (hour < 0 || entity.Time.Hour == hour)
|
||||
select entity).ToArray());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Json(new JsonResponse(false, DateNotCorrect));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("{username}/last/{hour:min(1)}")]
|
||||
public async Task<IEnumerable<TEntity>> Read(string username, int hour)
|
||||
public async Task<IActionResult> Read(string username, int hour)
|
||||
{
|
||||
DateTime date = DateTime.Now.AddHours(-hour);
|
||||
return await Db.GetTable<TEntity>().Where(e => e.Username.Equals(username) && date <= e.Time).ToListAsync();
|
||||
return LoggedAccessDataOf(username, () =>
|
||||
{
|
||||
DateTime date = DateTime.Now.AddHours(-hour);
|
||||
return Json((from entity in Db.GetTable<TEntity>()
|
||||
where entity.Username.Equals(username)
|
||||
&& date <= entity.Time
|
||||
select entity).ToArray());
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Create([FromBody]TEntity item)
|
||||
{
|
||||
return Action(() =>
|
||||
{
|
||||
Db.Insert(item);
|
||||
return Json(OkJson);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public async Task<IActionResult> Update([FromBody]TEntity item)
|
||||
{
|
||||
return LoggedAccessDataOf(item.Username, () =>
|
||||
{
|
||||
var e = Read(item.Username, item.Time);
|
||||
if (e == null)
|
||||
{
|
||||
Create(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
Db.UpdateAsync(item);
|
||||
}
|
||||
|
||||
return Json(OkJson);
|
||||
}, false);
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public async Task<TEntity> Read(string username, DateTime date) => await Db.GetTable<TEntity>().FirstOrDefaultAsync(e => e.Username.Equals(username) && date == e.Time);
|
||||
|
||||
[HttpPost]
|
||||
public async Task Create([FromBody]TEntity item) => await Db.InsertAsync(item);
|
||||
|
||||
[HttpPut]
|
||||
public async Task<object> Update([FromBody]TEntity item)
|
||||
{
|
||||
var e = await Read(item.Username, item.Time);
|
||||
if (e == null)
|
||||
{
|
||||
await Create(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Db.UpdateAsync(item);
|
||||
}
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
/*
|
||||
[HttpDelete("{username}")]
|
||||
public async Task Delete(string username) => await Db.GetTable<TEntity>().Where(c => c.Username.Equals(username)).DeleteAsync();
|
||||
*/
|
||||
private TEntity Read(string username, DateTime date) => Db.GetTable<TEntity>().FirstOrDefault(e => e.Username.Equals(username) && date == e.Time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using LinqToDB.Data;
|
||||
using LinqToDB.DataProvider;
|
||||
using SeniorAssistant.Models;
|
||||
using SeniorAssistant.Models.Users;
|
||||
|
||||
namespace SeniorAssistant.Data
|
||||
{
|
||||
@@ -11,8 +12,13 @@ namespace SeniorAssistant.Data
|
||||
: base(dataProvider, connectionString)
|
||||
{ }
|
||||
|
||||
public ITable<User> User => GetTable<User>();
|
||||
|
||||
public ITable<User> Users => GetTable<User>();
|
||||
public ITable<Heartbeat> Heartbeats => GetTable<Heartbeat>();
|
||||
public ITable<Sleep> Sleeps => GetTable<Sleep>();
|
||||
public ITable<Step> Steps => GetTable<Step>();
|
||||
public ITable<Doctor> Doctors => GetTable<Doctor>();
|
||||
public ITable<Patient> Patients => GetTable<Patient>();
|
||||
public ITable<Notification> Notifications => GetTable<Notification>();
|
||||
public ITable<Message> Messages => GetTable<Message>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace SeniorAssistant.Models
|
||||
{
|
||||
[PrimaryKey]
|
||||
[NotNull]
|
||||
[Association(ThisKey = nameof(Username), OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[PrimaryKey]
|
||||
@@ -15,5 +14,10 @@ namespace SeniorAssistant.Models
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
public double Value { get; set; }
|
||||
|
||||
/*
|
||||
[Association(ThisKey = nameof(Username), OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public User UserObj { get; set; }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SeniorAssistant.Models
|
||||
{
|
||||
@@ -12,8 +9,7 @@ namespace SeniorAssistant.Models
|
||||
|
||||
public class MenuItem : IMenuItem
|
||||
{
|
||||
public MenuItem(string text) : this(text, "#") { }
|
||||
public MenuItem(string text, string href)
|
||||
public MenuItem(string text, string href = "#")
|
||||
{
|
||||
Text = text;
|
||||
HRef = href;
|
||||
@@ -25,6 +21,6 @@ namespace SeniorAssistant.Models
|
||||
public class SubMenu : IMenuItem
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public IEnumerable<MenuItem> Items { get; set; }
|
||||
public IList<MenuItem> Items { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
26
SeniorAssistant/Models/Message.cs
Normal file
26
SeniorAssistant/Models/Message.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using LinqToDB.Mapping;
|
||||
using System;
|
||||
|
||||
namespace SeniorAssistant.Models
|
||||
{
|
||||
public class Message : IHasTime
|
||||
{
|
||||
[Column(IsPrimaryKey = true, CanBeNull = false, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Username { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Reciver { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Body { get; set; }
|
||||
|
||||
public bool Seen { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
21
SeniorAssistant/Models/Notification.cs
Normal file
21
SeniorAssistant/Models/Notification.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using LinqToDB.Mapping;
|
||||
using System;
|
||||
|
||||
namespace SeniorAssistant.Models
|
||||
{
|
||||
public class Notification : IHasTime
|
||||
{
|
||||
[Column(IsPrimaryKey = true, CanBeNull = false, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Username { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
public bool Seen { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SeniorAssistant.Models
|
||||
{
|
||||
public class Register
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Password { get; set; }
|
||||
public bool Doctor { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ namespace SeniorAssistant.Models
|
||||
{
|
||||
[PrimaryKey]
|
||||
[NotNull]
|
||||
[Association(ThisKey = nameof(Username), OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[PrimaryKey]
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace SeniorAssistant.Models
|
||||
{
|
||||
[PrimaryKey]
|
||||
[NotNull]
|
||||
[Association(ThisKey = nameof(Username), OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[PrimaryKey]
|
||||
|
||||
17
SeniorAssistant/Models/Users/Doctor.cs
Normal file
17
SeniorAssistant/Models/Users/Doctor.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using LinqToDB.Mapping;
|
||||
|
||||
namespace SeniorAssistant.Models.Users
|
||||
{
|
||||
public class Doctor : IHasUsername
|
||||
{
|
||||
[Column(IsPrimaryKey = true, CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[Association(ThisKey = "Username", OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public User UserData { get; set; }
|
||||
|
||||
public string Location { get; set; }
|
||||
|
||||
public string Schedule { get; set; }
|
||||
}
|
||||
}
|
||||
18
SeniorAssistant/Models/Users/Patient.cs
Normal file
18
SeniorAssistant/Models/Users/Patient.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using LinqToDB.Mapping;
|
||||
|
||||
namespace SeniorAssistant.Models.Users
|
||||
{
|
||||
public class Patient : IHasUsername
|
||||
{
|
||||
[Column(IsPrimaryKey = true, CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[Association(ThisKey = "Username", OtherKey = nameof(User.Username), CanBeNull = false)]
|
||||
public User UserData { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Doctor { get; set; }
|
||||
|
||||
public string Notes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,22 @@
|
||||
using LinqToDB.Mapping;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SeniorAssistant.Models
|
||||
{
|
||||
public class User : IHasUsername
|
||||
{
|
||||
[PrimaryKey]
|
||||
[NotNull]
|
||||
[Column(IsPrimaryKey = true, CanBeNull = false)]
|
||||
public string Username { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public string Email { get; set; }
|
||||
|
||||
[NotNull]
|
||||
[JsonIgnore]
|
||||
public string Password { get; set; }
|
||||
|
||||
[NotNull]
|
||||
public bool Doctor { get; set; }
|
||||
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string LastName { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using LinqToDB.DataProvider.SQLite;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SeniorAssistant.Configuration;
|
||||
@@ -13,8 +12,8 @@ using SeniorAssistant.Data;
|
||||
using SeniorAssistant.Models;
|
||||
using SeniorAssistant.Extensions;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using SeniorAssistant.Models.Users;
|
||||
|
||||
namespace SeniorAssistant
|
||||
{
|
||||
@@ -31,7 +30,15 @@ namespace SeniorAssistant
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
services.AddMvc();// config =>
|
||||
// {
|
||||
// var policy = new AuthorizationPolicyBuilder()
|
||||
// .RequireAuthenticatedUser()
|
||||
// .Build();
|
||||
// config.Filters.Add(new AuthorizeFilter(policy));
|
||||
// })
|
||||
// .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
|
||||
services.AddSession();
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
@@ -54,20 +61,30 @@ namespace SeniorAssistant
|
||||
services.Configure<Kendo>(Configuration.GetSection("kendo"));
|
||||
services.Configure<Theme>(Configuration.GetSection("theme"));
|
||||
|
||||
// services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
// .AddCookie(options => {
|
||||
// options.LoginPath = "/";
|
||||
// options.AccessDeniedPath = "/";
|
||||
// });
|
||||
|
||||
// services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>()
|
||||
// .AddEntityFrameworkStores<ApplicationDbContext>();
|
||||
|
||||
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddSingleton<IEnumerable<IMenuItem>>(new IMenuItem[]
|
||||
services.AddSingleton<IList<IMenuItem>>(new List<IMenuItem>
|
||||
{
|
||||
new SubMenu
|
||||
new MenuItem("Index", "/"),
|
||||
new SubMenu()
|
||||
{
|
||||
Text = "Link veloci",
|
||||
Text = "Raw Data",
|
||||
Items = new MenuItem[]
|
||||
{
|
||||
new MenuItem("User", "/"),
|
||||
new MenuItem("Users", "/users"),
|
||||
new MenuItem("Heartbeat", "/heartbeat"),
|
||||
new MenuItem("Sleep", "/sleep"),
|
||||
new MenuItem("Step", "/step")
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
var dbFactory = new SeniorDataContextFactory(
|
||||
@@ -77,6 +94,7 @@ namespace SeniorAssistant
|
||||
|
||||
services.AddSingleton<IDataContextFactory<SeniorDataContext>>(dbFactory);
|
||||
SetupDatabase(dbFactory);
|
||||
FillDatabase(dbFactory);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
@@ -90,6 +108,7 @@ namespace SeniorAssistant
|
||||
|
||||
app.UseSession();
|
||||
app.UseStaticFiles();
|
||||
// app.UseAuthentication();
|
||||
|
||||
// Enable middleware to serve generated Swagger as a JSON endpoint.
|
||||
app.UseSwagger();
|
||||
@@ -120,55 +139,83 @@ namespace SeniorAssistant
|
||||
{
|
||||
using (var db = dataContext.Create())
|
||||
{
|
||||
const string baseUsername = "vecchio";
|
||||
string[] users = { "Mario", "Giovanni", "Aldo", "Giacomo", "Marcello", "Filippo" };
|
||||
|
||||
db.CreateTableIfNotExists<Heartbeat>();
|
||||
db.CreateTableIfNotExists<Sleep>();
|
||||
db.CreateTableIfNotExists<Step>();
|
||||
try
|
||||
db.CreateTableIfNotExists<User>();
|
||||
db.CreateTableIfNotExists<Doctor>();
|
||||
db.CreateTableIfNotExists<Patient>();
|
||||
db.CreateTableIfNotExists<Notification>();
|
||||
db.CreateTableIfNotExists<Message>();
|
||||
}
|
||||
}
|
||||
|
||||
void FillDatabase(IDataContextFactory<SeniorDataContext> dataContext)
|
||||
{
|
||||
using (var db = dataContext.Create())
|
||||
{
|
||||
Random rnd = new Random();
|
||||
|
||||
List<User> users = new List<User>();
|
||||
|
||||
List<Doctor> docs = db.Doctors.ToListAsync().Result;
|
||||
if (docs.Count == 0)
|
||||
{
|
||||
db.CreateTable<User>();
|
||||
users.Add(new User { Name = "Alfredo", LastName = "Parise", Email = "alfred.pary@libero.it", Username = "alfredigno", Password = "alfy" });
|
||||
users.Add(new User { Name = "Edoardo", LastName = "Marzio", Email = "edo.marzio@libero.it", Username = "marzietto", Password = "edo64" });
|
||||
|
||||
docs.Add(new Doctor { Username = "alfredigno", Location = "Brasile" });
|
||||
docs.Add(new Doctor { Username = "marzietto", Location = "Uganda" });
|
||||
|
||||
foreach (var doc in docs)
|
||||
db.InsertOrReplace(doc);
|
||||
}
|
||||
|
||||
List<Patient> patients = db.Patients.ToListAsync().Result;
|
||||
if (patients.Count == 0)
|
||||
{
|
||||
const string baseUsername = "vecchio";
|
||||
string[] names = { "Mario", "Giovanni", "Aldo", "Giacomo", "Marcello", "Filippo" };
|
||||
string[] lastnames = { "Rossi", "Storti", "Baglio", "Poretti", "Marcelli", "Martelli" };
|
||||
int count = 0;
|
||||
foreach (string user in users)
|
||||
for (count=0; count<names.Length; count++)
|
||||
{
|
||||
var username = baseUsername + count;
|
||||
db.InsertOrReplace(new User { Name = user, Username = username, Password = username, Email = username + "@email.st" } );
|
||||
count++;
|
||||
users.Add(new User { Name = names[count], LastName = lastnames[count], Username = username, Password = username, Email = username + "@email.st" });
|
||||
patients.Add(new Patient { Username = username, Doctor = docs[rnd.Next(docs.Count)].Username });
|
||||
}
|
||||
|
||||
foreach (var patient in patients)
|
||||
db.InsertOrReplace(patient);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Random rnd = new Random();
|
||||
foreach (var user in users)
|
||||
db.InsertOrReplace(user);
|
||||
|
||||
DateTime now = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
|
||||
now = now.AddHours(DateTime.Now.Hour).AddMinutes(30);
|
||||
try
|
||||
{
|
||||
double totalHours = 50;
|
||||
try {
|
||||
double totalHours = 48;
|
||||
try
|
||||
{
|
||||
DateTime maxTimeInDB = db.GetTable<Heartbeat>().MaxAsync(x => x.Time).Result;
|
||||
TimeSpan span = now.Subtract(maxTimeInDB);
|
||||
totalHours = span.TotalHours;
|
||||
} catch { }
|
||||
|
||||
for (int i = 0; i<totalHours; i++)
|
||||
}
|
||||
catch { }
|
||||
|
||||
for (int i = 0; i < totalHours; i++)
|
||||
{
|
||||
DateTime time = now.AddHours(-i);
|
||||
for (int num = 0; num < users.Length; num++)
|
||||
foreach (var patient in patients)
|
||||
{
|
||||
string user = baseUsername + num;
|
||||
|
||||
if (time.Day != now.Day)
|
||||
if (time.Day != now.Day && time.Hour == 21)
|
||||
{
|
||||
db.Insert(new Sleep() { Username = user, Time = time, Value = rnd.Next(5 * 3600000, 9 * 3600000) });
|
||||
db.Insert(new Sleep() { Username = patient.Username, Time = time, Value = rnd.Next(5 * 3600000, 9 * 3600000) });
|
||||
}
|
||||
db.Insert(new Heartbeat() { Username = user, Time = time, Value = rnd.Next(50, 120) });
|
||||
db.Insert(new Step() { Username = user, Time = time, Value = rnd.Next(100, 500) });
|
||||
}
|
||||
if (time.Day != now.Day)
|
||||
{
|
||||
now = now.AddDays(-1);
|
||||
db.Insert(new Heartbeat() { Username = patient.Username, Time = time, Value = rnd.Next(50, 120) });
|
||||
db.Insert(new Step() { Username = patient.Username, Time = time, Value = rnd.Next(100, 500) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,93 +1,154 @@
|
||||
@model string
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
@model string
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Hello Razor";
|
||||
var session = HttpContextAccessor.HttpContext.Session;
|
||||
var username = session.GetString("username");
|
||||
|
||||
bool auth = username.Equals(Model);
|
||||
bool isDoc = session.GetString("role").Equals("doctor");
|
||||
Patient patient = null;
|
||||
if (isDoc)
|
||||
{
|
||||
var db = dbFactory.Create();
|
||||
patient = (from p in db.Patients
|
||||
where p.Username.Equals(Model) && p.Doctor.Equals(username)
|
||||
select p).ToArray().FirstOrDefault();
|
||||
auth = auth || patient != null;
|
||||
}
|
||||
}
|
||||
|
||||
<div id="chart"></div>
|
||||
|
||||
<script>
|
||||
var base_url = "@Url.Content("~/api/")";
|
||||
var end_url = "/@Model/last/48";
|
||||
|
||||
$.getJSON(base_url + "heartbeat" + end_url, function (heartbeat) {
|
||||
$.getJSON(base_url + "step" + end_url, function (steps) {
|
||||
$.getJSON(base_url + "sleep" + end_url, function (sleep) {
|
||||
|
||||
var sleepArr = [];
|
||||
sleep.forEach( function (el) {
|
||||
sleepArr.push({ "time": el.time, "value": 1 });
|
||||
var base_time = new Date(el.time).getTime();
|
||||
|
||||
for (var i = 60000; i <= el.value; i += 60000) {
|
||||
sleepArr.push({ "time": new Date(base_time + i), "value": 1 });
|
||||
@if (!auth)
|
||||
{
|
||||
<p class="box-title text-red">Non sei autorizzato a vedere i dati di @Model</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aggiungere un qualcosa per scegliere le ore da vedere (Max 48?)
|
||||
<div>
|
||||
<input id="hours-data" type="text" placeholder="hours" value="24" />
|
||||
<button id="refresh-hours" class="fc-button">Cambia ora</button>
|
||||
<div id="chart-data"></div>
|
||||
</div>
|
||||
@if(isDoc && patient != null)
|
||||
{
|
||||
<div>
|
||||
<textarea id="note-area" placeholder="Scrivi una nota..">@patient.Notes</textarea>
|
||||
<button id="send-note" class="btn">Salva</button>
|
||||
<p id="note-error"></p>
|
||||
</div>
|
||||
<script>
|
||||
$("#send-note").on("click", function () {
|
||||
var text = $("#note-area").val().trim();
|
||||
$.ajax({
|
||||
url: "/Account/_addNote",
|
||||
type: "PUT",
|
||||
data: {
|
||||
Patient: "@Model", Text: text
|
||||
},
|
||||
success: function (data) {
|
||||
$("#note-error").html(data.success?"Nota salvata":data.message);
|
||||
}
|
||||
});
|
||||
|
||||
$("#chart").kendoChart({
|
||||
title: { text: "Visualizzazione attivita' di @Model" },
|
||||
legend: { position: "bottom" },
|
||||
seriesDefaults: {
|
||||
type: "line",
|
||||
style: "smooth"
|
||||
},
|
||||
series: [{
|
||||
name: "Battito",
|
||||
field: "value",
|
||||
color: "red",
|
||||
axis: "Heartbeat",
|
||||
categoryField: "time",
|
||||
data: heartbeat,
|
||||
tooltip: {
|
||||
visible: true,
|
||||
format: "{0}%",
|
||||
template: "Media di: #= value # bpm"
|
||||
}
|
||||
}, {
|
||||
name: "Passi",
|
||||
field: "value",
|
||||
color: "blue",
|
||||
axis: "Steps",
|
||||
categoryField: "time",
|
||||
data: steps,
|
||||
tooltip: {
|
||||
visible: true,
|
||||
format: "{0}%",
|
||||
template: "#= series.name #: #= value #"
|
||||
}
|
||||
}, {
|
||||
type: "area",
|
||||
name: "Sonno",
|
||||
field: "value",
|
||||
color: "black",
|
||||
axis: "Sleep",
|
||||
categoryField: "time",
|
||||
data: sleepArr
|
||||
}],
|
||||
categoryAxis: {
|
||||
labels: {
|
||||
rotation: +45,
|
||||
dateFormats: {
|
||||
hours: "HH:mm"
|
||||
}
|
||||
},
|
||||
type: "Date",
|
||||
baseUnit: "hours"
|
||||
},
|
||||
valueAxes: [{
|
||||
name: "Heartbeat",
|
||||
color: "red"
|
||||
}, {
|
||||
name: "Steps",
|
||||
color: "blue"
|
||||
}, {
|
||||
name: "Sleep",
|
||||
color: "gray",
|
||||
visible: false,
|
||||
max: 1,
|
||||
min: 0
|
||||
}]
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
</script>
|
||||
});
|
||||
</script>
|
||||
}
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
$("#hours-data").on("change keyup paste click", function () {
|
||||
var t = $(this);
|
||||
t.val(t.val().replace(/[^0-9]/g, '').substring(0, 2));
|
||||
});
|
||||
$("#refresh-hours").on("click", function () {
|
||||
var hours = $("#hours-data").val();
|
||||
var base_url = "@Url.Content("~/api/")";
|
||||
var end_url = "/@Model/last/" + hours;
|
||||
|
||||
$.getJSON(base_url + "heartbeat" + end_url, function (heartbeat) {
|
||||
$.getJSON(base_url + "step" + end_url, function (steps) {
|
||||
$.getJSON(base_url + "sleep" + end_url, function (sleep) {
|
||||
var sleepArr = [];
|
||||
sleep.forEach( function (el) {
|
||||
sleepArr.push({ "time": el.time, "value": 1 });
|
||||
var base_time = new Date(el.time).getTime();
|
||||
|
||||
for (var i = 60000; i <= el.value; i += 60000) {
|
||||
sleepArr.push({ "time": new Date(base_time + i), "value": 1 });
|
||||
}
|
||||
});
|
||||
|
||||
$("#chart-data").kendoChart({
|
||||
title: { text: "Visualizzazione attivita' di @Model" },
|
||||
legend: { position: "bottom" },
|
||||
seriesDefaults: {
|
||||
type: "line",
|
||||
style: "smooth"
|
||||
},
|
||||
series: [{
|
||||
name: "Battito",
|
||||
field: "value",
|
||||
color: "red",
|
||||
axis: "Heartbeat",
|
||||
categoryField: "time",
|
||||
data: heartbeat,
|
||||
tooltip: {
|
||||
visible: true,
|
||||
format: "{0}%",
|
||||
template: "Media di: #= value # bpm"
|
||||
}
|
||||
}, {
|
||||
name: "Passi",
|
||||
field: "value",
|
||||
color: "blue",
|
||||
axis: "Steps",
|
||||
categoryField: "time",
|
||||
data: steps,
|
||||
tooltip: {
|
||||
visible: true,
|
||||
format: "{0}%",
|
||||
template: "#= series.name #: #= value #"
|
||||
}
|
||||
}, {
|
||||
type: "area",
|
||||
name: "Sonno",
|
||||
field: "value",
|
||||
color: "black",
|
||||
axis: "Sleep",
|
||||
categoryField: "time",
|
||||
data: sleepArr
|
||||
}],
|
||||
categoryAxis: {
|
||||
labels: {
|
||||
rotation: +45,
|
||||
dateFormats: {
|
||||
hours: "HH:mm"
|
||||
}
|
||||
},
|
||||
type: "Date",
|
||||
baseUnit: "hours"
|
||||
},
|
||||
valueAxes: [{
|
||||
name: "Heartbeat",
|
||||
color: "red"
|
||||
}, {
|
||||
name: "Steps",
|
||||
color: "blue"
|
||||
}, {
|
||||
name: "Sleep",
|
||||
color: "gray",
|
||||
visible: false,
|
||||
max: 1,
|
||||
min: 0
|
||||
}]
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
$("#refresh-hours").click();
|
||||
</script>
|
||||
}
|
||||
@@ -5,26 +5,32 @@ logo sito
|
||||
disattivare l-aside e le opzioni
|
||||
se non loggato deve tornare qua
|
||||
-->
|
||||
@model string
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Hello Razor";
|
||||
string session = HttpContextAccessor.HttpContext.Session.GetString("username");
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
@if (session == null)
|
||||
{
|
||||
@if (Model != null)
|
||||
{
|
||||
<p class="text-red box-title">Per poter accedere alla pagina [@Model] e' necessario essere loggati</p>
|
||||
}
|
||||
|
||||
<div class="login-box">
|
||||
@{ await Html.RenderPartialAsync("Login"); }
|
||||
</div>
|
||||
<div class="login-box">
|
||||
@{ await Html.RenderPartialAsync("Register");
|
||||
}
|
||||
@{ await Html.RenderPartialAsync("Register"); }
|
||||
</div>
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await Html.RenderPartialAsync("Profile");
|
||||
await Html.RenderPartialAsync("Profile"); // magari sostituire qui
|
||||
}
|
||||
</div>
|
||||
|
||||
30
SeniorAssistant/Views/Home/Message.cshtml
Normal file
30
SeniorAssistant/Views/Home/Message.cshtml
Normal file
@@ -0,0 +1,30 @@
|
||||
@model int
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
@using LinqToDB;
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Hello Razor";
|
||||
string username = HttpContextAccessor.HttpContext.Session.GetString("username");
|
||||
var db = dbFactory.Create();
|
||||
var message = (from m in db.Messages
|
||||
where m.Id.Equals(Model) && m.Reciver.Equals(username)
|
||||
select m).ToArray().FirstOrDefault();
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
@if (message == null)
|
||||
{
|
||||
<p class="text-red">Non hai il permesso</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Seen = true;
|
||||
db.Update(message);
|
||||
<p>Messaggio da @message.Username</p>
|
||||
<p>Inviato il @message.Time</p>
|
||||
<div class="info-box-text">
|
||||
@message.Body
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@@ -8,19 +8,11 @@
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
var baseUrl = "@Url.Content("~/api/user/")";
|
||||
|
||||
|
||||
$("#grid").kendoGrid({
|
||||
dataSource: {
|
||||
transport: {
|
||||
read: { url: baseUrl, type: "GET" }
|
||||
|
||||
/*
|
||||
parameterMap: function (model, operation) {
|
||||
if (operation !== "read" && model) {
|
||||
return kendo.stringify(model);
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
serverPaging: false,
|
||||
serverSorting: false,
|
||||
@@ -30,7 +22,8 @@
|
||||
id: "username",
|
||||
fields: {
|
||||
username: { type: "string" },
|
||||
name: { type: "string" }
|
||||
name: { type: "string" },
|
||||
lastName: { type: "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,9 +33,10 @@
|
||||
filterable: true,
|
||||
editable: false,
|
||||
columns: [
|
||||
{ field: "username", title: "Username" },
|
||||
{ field: "name", title: "Name" },
|
||||
{ field: "url", title: "",template:'<a href=/user/#=username#>Vedi Dati</a>'}/*,
|
||||
{ field: "lastName", title: "Lastname" },
|
||||
{ field: "url", title: "", template: '<a href=/user/#=username#>Vedi Dati</a>' }
|
||||
/*,
|
||||
{ field: "time", title: "Date/Time", format: "{dd/MM/yyyy HH}" },
|
||||
{ field: "value", title: "Heartbeats" }
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,15 @@
|
||||
var action = ViewContext.RouteData.Values["Action"];
|
||||
}
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/"><i class="fa fa-dashboard"></i> @controller</a></li>
|
||||
<li class="active">@action</li>
|
||||
</ol>
|
||||
<div class="breadcrumb">
|
||||
@Html.ActionLink("Home", "Index", "Home")
|
||||
@if (controller.ToString() != "Home")
|
||||
{
|
||||
@:> @Html.ActionLink(controller.ToString(), "Index", controller.ToString())
|
||||
}
|
||||
@if (action.ToString() != "Index")
|
||||
{
|
||||
@:> @Html.ActionLink(action.ToString(), action.ToString(), controller.ToString())
|
||||
}
|
||||
|
||||
</div>
|
||||
@@ -1,13 +1,9 @@
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<!-- The user image in the navbar-->
|
||||
<!-- hidden-xs hides the username on small devices so only the image appears. -->
|
||||
</a>
|
||||
<ul style="list-style-type:none">
|
||||
<ul style="list-style-type:none">
|
||||
<li class="user-header">
|
||||
<input type="text" id="username" placeholder="username" />
|
||||
<input type="password" id="password" placeholder="password" />
|
||||
<div>
|
||||
<button class="btn-default btn btn-flat" id="login-btn">Login</button>
|
||||
<button class="btn-default btn btn-flat" id="login-btn">Login</button>
|
||||
</div>
|
||||
<p id="msg" class="login-box-msg"></p>
|
||||
</li>
|
||||
@@ -23,19 +19,17 @@
|
||||
dataType: "json",
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
var msg = $("#msg");
|
||||
if (data.success) {
|
||||
msg.hide();
|
||||
// app.navigate("");
|
||||
window.location.reload();
|
||||
} else {
|
||||
msg.html(data.message).show();
|
||||
$("#user-menu").addClass("open");
|
||||
}
|
||||
return false;
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
alert(xhr.responseText)
|
||||
alert(xhr.status+" "+xhr.responseText)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
@model string
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
|
||||
@{
|
||||
var session = HttpContextAccessor.HttpContext.Session;
|
||||
}
|
||||
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<!-- The user image in the navbar-->
|
||||
<img src="~/AdminLTE-2.4.3/dist/img/user2-160x160.jpg" class="user-image" alt="User Image">
|
||||
@@ -10,29 +16,14 @@
|
||||
<li class="user-header">
|
||||
<img src="~/AdminLTE-2.4.3/dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
|
||||
<p>
|
||||
Alexander Pierce - Web Developer
|
||||
<small>Member since Nov. 2012</small>
|
||||
@session.GetString("name") @session.GetString("lastname") - @session.GetString("role")
|
||||
<small>@session.GetString("email")</small>
|
||||
</p>
|
||||
</li>
|
||||
<!-- Menu Body -->
|
||||
<li class="user-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="#">Followers</a>
|
||||
</div>
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="#">Sales</a>
|
||||
</div>
|
||||
<div class="col-xs-4 text-center">
|
||||
<a href="#">Friends</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</li>
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<div class="pull-left">
|
||||
<a href="#" class="btn btn-default btn-flat">Profile</a>
|
||||
<a href="/" class="btn btn-default btn-flat">Profile</a>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<a href="#" id="logout-btn" class="btn btn-default btn-flat">Logout</a>
|
||||
|
||||
90
SeniorAssistant/Views/Shared/Messages.cshtml
Normal file
90
SeniorAssistant/Views/Shared/Messages.cshtml
Normal file
@@ -0,0 +1,90 @@
|
||||
@model string
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
|
||||
@{
|
||||
var db = dbFactory.Create();
|
||||
var maxMessage = 10;
|
||||
var notSeen = (from n in db.Messages
|
||||
where n.Reciver.Equals(Model) && n.Seen == false
|
||||
orderby n.Time descending
|
||||
select n).Take(maxMessage).ToArray();
|
||||
|
||||
var messages = new Message[maxMessage];
|
||||
var num = notSeen.Length;
|
||||
|
||||
int i;
|
||||
for (i=0; i<num; i++)
|
||||
{
|
||||
messages[i] = notSeen[i];
|
||||
}
|
||||
|
||||
if (num < maxMessage)
|
||||
{
|
||||
var messSeen = (from n in db.Messages
|
||||
where n.Reciver.Equals(Model) && n.Seen == true
|
||||
orderby n.Time descending
|
||||
select n).Take(maxMessage-num).ToArray();
|
||||
|
||||
foreach(var m in messSeen)
|
||||
{
|
||||
messages[i] = m;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<!--
|
||||
<script>
|
||||
$(document).ready(
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
url: "/Account/_message",
|
||||
data: { Username: "@Model", Message: "stronzo" },
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
}
|
||||
})
|
||||
);
|
||||
</script>
|
||||
-->
|
||||
|
||||
<a id="id-message-toggle" href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-envelope-o"></i>
|
||||
@if (num != 0)
|
||||
{
|
||||
<span class="label label-danger">
|
||||
@num
|
||||
@if(num > maxMessage)
|
||||
{
|
||||
@:+
|
||||
}
|
||||
</span>
|
||||
}
|
||||
</a>
|
||||
@if (messages.Length != 0)
|
||||
{
|
||||
<ul id="id-message-drop" class="dropdown-menu">
|
||||
<li class="header">You have @num unread message</li>
|
||||
<li>
|
||||
<!-- Inner Menu: contains the messages -->
|
||||
<ul class="menu">
|
||||
@foreach (var message in messages)
|
||||
{
|
||||
if(message != null)
|
||||
{
|
||||
<li>
|
||||
<!-- start notification -->
|
||||
<a id="message-@message.Id" @if(message.Seen) {<text>class= "bg-gray"</text>} href="/Message/@message.Id">
|
||||
<i class="fa text-lime">@message.Time</i><br />
|
||||
@message.Body
|
||||
</a>
|
||||
</li>
|
||||
<!-- end message -->
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
<!-- <li class="footer"><a href="#">View all</a></li> -->
|
||||
</ul>
|
||||
}
|
||||
@@ -6,116 +6,51 @@
|
||||
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<!-- Messages: style can be found in dropdown.less-->
|
||||
<li class="dropdown messages-menu">
|
||||
<!-- Menu toggle button -->
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-envelope-o"></i>
|
||||
<span class="label label-success">4</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header">You have 4 messages</li>
|
||||
<li>
|
||||
<!-- inner menu: contains the messages -->
|
||||
<ul class="menu">
|
||||
<li>
|
||||
<!-- start message -->
|
||||
@if (session != null)
|
||||
{
|
||||
<!--
|
||||
Scheletro di una roba sopra per le notifiche e messaggi e robe in piu...
|
||||
<li class="dropdown ??-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-??-o"></i>
|
||||
<span class="label label-??">??</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header">??</li>
|
||||
<li>
|
||||
<ul class="menu">
|
||||
<li>Elements Here</li>
|
||||
<a href="#">
|
||||
<div class="pull-left">
|
||||
<!-- User Image -->
|
||||
<img src="~/AdminLTE-2.4.3/dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
|
||||
</div>
|
||||
<!-- Message title and timestamp -->
|
||||
<h4>
|
||||
Support Team
|
||||
<small><i class="fa fa-clock-o"></i> 5 mins</small>
|
||||
</h4>
|
||||
<!-- The message -->
|
||||
<p>Why not buy a new awesome theme?</p>
|
||||
</a>
|
||||
</li>
|
||||
<!-- end message -->
|
||||
</ul>
|
||||
<!-- /.menu -->
|
||||
</li>
|
||||
<li class="footer"><a href="#">See All Messages</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- /.messages-menu -->
|
||||
<!-- Notifications Menu -->
|
||||
<li class="dropdown notifications-menu">
|
||||
<!-- Menu toggle button -->
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-bell-o"></i>
|
||||
<span class="label label-warning">10</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header">You have 10 notifications</li>
|
||||
<li>
|
||||
<!-- Inner Menu: contains the notifications -->
|
||||
<ul class="menu">
|
||||
<li>
|
||||
<!-- start notification -->
|
||||
<a href="#">
|
||||
<i class="fa fa-users text-aqua"></i> 5 new members joined today
|
||||
</a>
|
||||
</li>
|
||||
<!-- end notification -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="footer"><a href="#">View all</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- Tasks Menu -->
|
||||
<li class="dropdown tasks-menu">
|
||||
<!-- Menu Toggle Button -->
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-flag-o"></i>
|
||||
<span class="label label-danger">9</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header">You have 9 tasks</li>
|
||||
<li>
|
||||
<!-- Inner menu: contains the tasks -->
|
||||
<ul class="menu">
|
||||
<li>
|
||||
<!-- Task item -->
|
||||
<a href="#">
|
||||
<!-- Task title and progress text -->
|
||||
<h3>
|
||||
Design some buttons
|
||||
<small class="pull-right">20%</small>
|
||||
</h3>
|
||||
<!-- The progress bar -->
|
||||
<div class="progress xs">
|
||||
<!-- Change the css width attribute to simulate progress -->
|
||||
<div class="progress-bar progress-bar-aqua" style="width: 20%" role="progressbar"
|
||||
aria-valuenow="20" aria-valuemin="0" aria-valuemax="100">
|
||||
<span class="sr-only">20% Complete</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<!-- end task item -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="footer">
|
||||
<a href="#">View all tasks</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- User Account Menu -->
|
||||
<li id="user-menu" class="dropdown user user-menu">
|
||||
<!-- Menu Toggle Button -->
|
||||
@if(session != null)
|
||||
{
|
||||
await Html.RenderPartialAsync("Logout", session);
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
<li class="dropdown messages-menu">
|
||||
@{ await Html.RenderPartialAsync("Messages", session); }
|
||||
</li>
|
||||
<li class="dropdown notifications-menu">
|
||||
@{ await Html.RenderPartialAsync("Notifications", session); }
|
||||
</li>
|
||||
<li id="user-menu" class="dropdown user user-menu">
|
||||
@{ await Html.RenderPartialAsync("Logout", session); }
|
||||
</li>
|
||||
|
||||
</li>
|
||||
<!-- Control Sidebar Toggle Button -->
|
||||
<li>
|
||||
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
|
||||
</li>
|
||||
<!-- Control Sidebar Toggle Button -->
|
||||
<!--
|
||||
<li>
|
||||
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
|
||||
</li>
|
||||
-->
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
82
SeniorAssistant/Views/Shared/Notifications.cshtml
Normal file
82
SeniorAssistant/Views/Shared/Notifications.cshtml
Normal file
@@ -0,0 +1,82 @@
|
||||
@model string
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
|
||||
@{
|
||||
var db = dbFactory.Create();
|
||||
var notifications = (from n in db.Notifications
|
||||
where n.Username.Equals(Model) && n.Seen == false
|
||||
orderby n.Time
|
||||
select n).ToArray();
|
||||
var num = notifications.Length;
|
||||
}
|
||||
|
||||
<!--
|
||||
<script>
|
||||
$(document).ready(
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
url: "/Account/_notification",
|
||||
data: { Username: "@Model", Message: "stronzo" },
|
||||
success: function (data) {
|
||||
console.log(data);
|
||||
}
|
||||
})
|
||||
);
|
||||
</script>
|
||||
-->
|
||||
|
||||
<a id="id-notification-toggle" href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-bell-o"></i>
|
||||
@if (num != 0)
|
||||
{
|
||||
<span class="label label-warning">@num</span>
|
||||
}
|
||||
</a>
|
||||
@if (num != 0)
|
||||
{
|
||||
<ul id="id-notification-drop" class="dropdown-menu">
|
||||
<li class="header">You have @num notifications</li>
|
||||
<li>
|
||||
<!-- Inner Menu: contains the notifications -->
|
||||
<ul class="menu">
|
||||
@foreach (var notification in notifications)
|
||||
{
|
||||
<li>
|
||||
<!-- start notification -->
|
||||
<a id="notification-@notification.Id" href="#">
|
||||
<i class="fa fa-users text-aqua">@notification.Time</i><br />
|
||||
@notification.Message
|
||||
</a>
|
||||
</li>
|
||||
<!-- end notification -->
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
<!-- <li class="footer"><a href="#">View all</a></li> -->
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
var user = "@Model";
|
||||
$("[id^='notification-']").on("click", function () {
|
||||
var id = this.id.replace(/notification-/g, '');
|
||||
var allId = this.id;
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
dataType: "json",
|
||||
url: "/Account/_notification",
|
||||
data: { id: id },
|
||||
success: function () {
|
||||
$("#" + allId).remove();
|
||||
var num = parseInt($("#id-notification-toggle span").html()) - 1;
|
||||
if (num == 0) {
|
||||
$("#id-notification-toggle span").remove();
|
||||
$("#id-notification-drop").remove();
|
||||
}
|
||||
else
|
||||
$("#id-notification-toggle span").html(num);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
}
|
||||
@@ -1,16 +1,162 @@
|
||||
@model User
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
|
||||
@{
|
||||
var session = HttpContextAccessor.HttpContext.Session;
|
||||
var db = dbFactory.Create();
|
||||
var username = session.GetString("username");
|
||||
var patientData = db.Patients.Where(p => p.Username.Equals(username)).ToArray().FirstOrDefault();
|
||||
var hasDoc = patientData != null;
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
<h2 class="alert-success" style="text-align:center">
|
||||
Welcome @session.GetString("username")
|
||||
<div class="pull-left" , style="width: 50%">
|
||||
<h2 class="alert-success" style="text-align:center">
|
||||
Welcome @username
|
||||
</h2>
|
||||
name: @session.GetString("name")<br />
|
||||
lastname: @session.GetString("lastname")<br />
|
||||
email: @session.GetString("email")<br />
|
||||
</div>
|
||||
|
||||
</h2>
|
||||
name: @session.GetString("name")<br />
|
||||
lastname: @session.GetString("lastname")<br />
|
||||
email: @session.GetString("email")
|
||||
<div class="box pull-right" , style="width: 45%">
|
||||
@if (hasDoc) // is patient and has doc, must show doc data
|
||||
{
|
||||
var doctor = (from u in db.Users
|
||||
join d in db.Doctors on u.Username equals d.Username
|
||||
where d.Username.Equals(patientData.Doctor)
|
||||
select new { u.Username, u.Name, u.LastName, d.Location }).ToArray().First();
|
||||
|
||||
<p class="text-bold">Dottore: @doctor.Name @doctor.LastName</p>
|
||||
<p class="text-fuchsia">Dove mi puoi trovare? @doctor.Location</p>
|
||||
<textarea class="progress-text" placeholder="Nessuna nuova nota" readonly>@patientData.Notes</textarea>
|
||||
|
||||
<div id="send-doc-message">
|
||||
<p>Invia un messaggio al tuo dottore</p>
|
||||
<textarea id="doc-message" class="progress-text" placeholder="scrivi qui"></textarea>
|
||||
<button id="btn-send-message">Invia</button>
|
||||
<p id="message-error" class="text-red"></p>
|
||||
|
||||
<script>
|
||||
$("#btn-send-message").on("click", function () {
|
||||
var body = $("#doc-message").val().trim();
|
||||
var endMessage = $("#message-error");
|
||||
if (body.length < 20) {
|
||||
endMessage.html("Messaggio non valido (minimo 20 caratteri)");
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "Account/_sendMessage",
|
||||
type: "POST",
|
||||
data: {
|
||||
Reciver: "@doctor.Username",
|
||||
Body: body
|
||||
},
|
||||
success: function () {
|
||||
$("#doc-message").val("");
|
||||
endMessage.html("Messaggio inviato");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
dynamic[] data;
|
||||
Type type = null;
|
||||
string title = null;
|
||||
var docData = db.Doctors.Where(d => d.Username.Equals(username)).ToArray().FirstOrDefault();
|
||||
|
||||
if (docData != null) // is DOC
|
||||
{
|
||||
// see all the patient of the doc
|
||||
title = "Lista dei pazienti";
|
||||
var patients = (from u in db.Users
|
||||
join p in db.Patients on u.Username equals p.Username
|
||||
where p.Doctor.Equals(docData.Username)
|
||||
select new { u.Username, u.Name, u.LastName, p.Notes, Profile = "<a href=\\\"/user/" + u.Username + "\\\">Profile</a>" }).ToArray();
|
||||
data = patients;
|
||||
type = patients.FirstOrDefault().GetType();
|
||||
}
|
||||
else // is a patient and need to choose a doctor
|
||||
{
|
||||
// choose which doc you want
|
||||
title = "Scegli un Doc";
|
||||
var docs = (from u in db.Users
|
||||
join d in db.Doctors on u.Username equals d.Username
|
||||
select new { u.Username, u.Name, u.LastName, d.Location, Choose = "<a id=\\\"choose-" + u.Username + "\\\" href=#>Scegli</a>" }).ToArray();
|
||||
data = docs;
|
||||
type = docs.FirstOrDefault().GetType();
|
||||
}
|
||||
|
||||
var fields = new List<string>();
|
||||
foreach (var field in type.GetProperties())
|
||||
{
|
||||
fields.Add(field.Name);
|
||||
}
|
||||
|
||||
<p>@title</p>
|
||||
<div id="var-table"></div>
|
||||
<script>
|
||||
var datas = [
|
||||
@foreach (var el in data)
|
||||
{
|
||||
@:{
|
||||
@foreach (var field in fields)
|
||||
{
|
||||
@field@:: "@Html.Raw(type.GetProperty(field).GetValue(el, null))",
|
||||
}
|
||||
@:},
|
||||
}
|
||||
];
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#var-table").kendoGrid({
|
||||
dataSource: {
|
||||
data: datas,
|
||||
schema: {
|
||||
model: {
|
||||
fields: {
|
||||
@foreach (var field in fields)
|
||||
{
|
||||
@field@: : { type: "@field.GetType().Name" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollable: true,
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
columns: [
|
||||
@foreach (var field in fields)
|
||||
{
|
||||
@:{ field: "@field", title: "@field", template: "#=@field#" },
|
||||
}
|
||||
]
|
||||
});
|
||||
@if(docData == null) // choose a doc
|
||||
{
|
||||
<text>
|
||||
$('[id^="choose-"]').on("click", function () {
|
||||
var id = this.id.replace("choose-", '');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/Account/_addDoc",
|
||||
data: { doctor: id },
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</text>
|
||||
}
|
||||
});
|
||||
</script>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<ul style="list-style: none">
|
||||
<li class="user-header">
|
||||
<input type="text" id="regUsername" placeholder="username" />
|
||||
<input type="password" id="regPassword" placeholder="password" />
|
||||
<input type="email" id="regEmail" placeholder="example@qualcosa.qualcosa" />
|
||||
<input type="text" id="regUsername" placeholder="Username" required />
|
||||
<input type="text" id="regName" placeholder="Name" />
|
||||
<input type="text" id="regLastname" placeholder="Lastname" />
|
||||
<input type="password" id="regPassword" placeholder="Password" required />
|
||||
<input type="email" id="regEmail" placeholder="Email" required />
|
||||
<label>Doc?</label><input type="checkbox" id="regDoctor" />
|
||||
<div>
|
||||
<button class="btn-default btn btn-flat" id="register-btn">Register</button>
|
||||
@@ -13,20 +15,26 @@
|
||||
|
||||
<script>
|
||||
$("#register-btn").on("click", function () {
|
||||
var regUsername = $("#regUsername").val();
|
||||
var regPassword = $("#regPassword").val();
|
||||
var regEmail = $("#regEmail").val();
|
||||
var regDoctor = $("#regDoctor").is(":checked");
|
||||
var username = $("#regUsername").val();
|
||||
var name = $("#regName").val();
|
||||
var lastname = $("#regLastname").val();
|
||||
var password = $("#regPassword").val();
|
||||
var email = $("#regEmail").val();
|
||||
var role = $("#regDoctor").is(":checked")? "Doctor":"User";
|
||||
|
||||
$.ajax({
|
||||
url: "/Account/_register",
|
||||
data: { Username: regUsername, Password: regPassword, Email: regEmail},
|
||||
data: {
|
||||
Username: username,
|
||||
Name: name,
|
||||
Lastname: lastname,
|
||||
Password: password,
|
||||
Email: email,
|
||||
Role: role
|
||||
},
|
||||
dataType: "json",
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
//se data.success->reload
|
||||
//se data.fail->indica errori
|
||||
|
||||
console.log(data);
|
||||
var msg = $("#msg-reg");
|
||||
if (data.success) {
|
||||
window.location.reload();
|
||||
|
||||
@@ -1,9 +1,36 @@
|
||||
@inject IEnumerable<IMenuItem> Menu
|
||||
@inject IList<IMenuItem> Menu
|
||||
@inject IHttpContextAccessor HttpContextAccessor
|
||||
@inject IDataContextFactory<SeniorDataContext> dbFactory
|
||||
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
@foreach(var menuItem in Menu)
|
||||
@{
|
||||
var session = HttpContextAccessor.HttpContext.Session;
|
||||
string username = session.GetString("username");
|
||||
|
||||
if (username != null)
|
||||
{
|
||||
switch(menuItem)
|
||||
Menu = new List<IMenuItem>(Menu);
|
||||
Menu.RemoveAt(1);
|
||||
Menu.Insert(1, new MenuItem("Dati personali", "/user/" + username));
|
||||
if (session.GetString("role").Equals("doctor"))
|
||||
{
|
||||
var db = dbFactory.Create();
|
||||
var patients = (from p in db.Patients
|
||||
where p.Doctor.Equals(username)
|
||||
join u in db.Users on p.Username equals u.Username
|
||||
select new { Username = p.Username, Name = u.Name + " " + u.LastName }).ToArray();
|
||||
var sub = new SubMenu() { Text = "Pazienti", Items = new List<MenuItem>() };
|
||||
foreach (var p in patients)
|
||||
{
|
||||
sub.Items.Add(new MenuItem(p.Name, "/user/" + p.Username));
|
||||
}
|
||||
Menu.Add(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
@foreach (var menuItem in Menu)
|
||||
{
|
||||
switch (menuItem)
|
||||
{
|
||||
case MenuItem single:
|
||||
<li>
|
||||
|
||||
@@ -17,7 +17,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>@ViewBag.Title</title>
|
||||
<title>SeniorAssistant @ViewBag.Title</title>
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<link rel="stylesheet" href="~/AdminLTE-2.4.3/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||
@@ -136,75 +136,6 @@ desired effect
|
||||
<div>
|
||||
@{ await Html.RenderPartialAsync("Footer"); }
|
||||
</div>
|
||||
<!-- Control Sidebar -->
|
||||
<aside class="control-sidebar control-sidebar-dark">
|
||||
<!-- Create the tabs -->
|
||||
<ul class="nav nav-tabs nav-justified control-sidebar-tabs">
|
||||
<li class="active"><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li>
|
||||
<li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gears"></i></a></li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<!-- Home tab content -->
|
||||
<div class="tab-pane active" id="control-sidebar-home-tab">
|
||||
<h3 class="control-sidebar-heading">Recent Activity</h3>
|
||||
<ul class="control-sidebar-menu">
|
||||
<li>
|
||||
<a href="javascript:;">
|
||||
<i class="menu-icon fa fa-birthday-cake bg-red"></i>
|
||||
<div class="menu-info">
|
||||
<h4 class="control-sidebar-subheading">Langdon's Birthday</h4>
|
||||
<p>Will be 23 on April 24th</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- /.control-sidebar-menu -->
|
||||
<h3 class="control-sidebar-heading">Tasks Progress</h3>
|
||||
<ul class="control-sidebar-menu">
|
||||
<li>
|
||||
<a href="javascript:;">
|
||||
<h4 class="control-sidebar-subheading">
|
||||
Custom Template Design
|
||||
<span class="pull-right-container">
|
||||
<span class="label label-danger pull-right">70%</span>
|
||||
</span>
|
||||
</h4>
|
||||
<div class="progress progress-xxs">
|
||||
<div class="progress-bar progress-bar-danger" style="width: 70%"></div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- /.control-sidebar-menu -->
|
||||
</div>
|
||||
<!-- /.tab-pane -->
|
||||
<!-- Stats tab content -->
|
||||
<div class="tab-pane" id="control-sidebar-stats-tab">Stats Tab Content</div>
|
||||
<!-- /.tab-pane -->
|
||||
<!-- Settings tab content -->
|
||||
<div class="tab-pane" id="control-sidebar-settings-tab">
|
||||
<form method="post">
|
||||
<h3 class="control-sidebar-heading">General Settings</h3>
|
||||
<div class="form-group">
|
||||
<label class="control-sidebar-subheading">
|
||||
Report panel usage
|
||||
<input type="checkbox" class="pull-right" checked>
|
||||
</label>
|
||||
<p>
|
||||
Some information about this general settings option
|
||||
</p>
|
||||
</div>
|
||||
<!-- /.form-group -->
|
||||
</form>
|
||||
</div>
|
||||
<!-- /.tab-pane -->
|
||||
</div>
|
||||
</aside>
|
||||
<!-- /.control-sidebar -->
|
||||
<!-- Add the sidebar's background. This div must be placed
|
||||
immediately after the control sidebar -->
|
||||
<div class="control-sidebar-bg"></div>
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
<!-- REQUIRED JS SCRIPTS -->
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@using SeniorAssistant.Models
|
||||
@using SeniorAssistant.Models;
|
||||
@using SeniorAssistant.Models.Users;
|
||||
@using SeniorAssistant.Data;
|
||||
@using Microsoft.AspNetCore.Mvc;
|
||||
@using Microsoft.AspNetCore.Http;
|
||||
Binary file not shown.
Reference in New Issue
Block a user