@@ -24,7 +24,7 @@ namespace Teknik.Areas.Admin | |||
new List<string>() { "admin" }, // Subdomains | |||
new List<string>() { config.Host }, | |||
"", // URL with parameters | |||
new { controller = "Admin", action = "Dashboard", username = string.Empty }, // Parameter defaults | |||
new { controller = "Admin", action = "Dashboard" }, // Parameter defaults | |||
new[] { typeof(Controllers.AdminController).Namespace } | |||
); | |||
context.MapSubdomainRoute( | |||
@@ -32,12 +32,20 @@ namespace Teknik.Areas.Admin | |||
new List<string>() { "admin" }, // Subdomains | |||
new List<string>() { config.Host }, | |||
"Search", // URL with parameters | |||
new { controller = "Admin", action = "Search", username = string.Empty }, // Parameter defaults | |||
new { controller = "Admin", action = "Search" }, // Parameter defaults | |||
new[] { typeof(Controllers.AdminController).Namespace } | |||
); | |||
context.MapSubdomainRoute( | |||
"Admin.UserInfo", // Route name | |||
new List<string>() { "admin" }, // Subdomains | |||
new List<string>() { config.Host }, | |||
"User/{username}", // URL with parameters | |||
new { controller = "Admin", action = "UserInfo", username = string.Empty }, // Parameter defaults | |||
new[] { typeof(Controllers.AdminController).Namespace } | |||
); | |||
context.MapSubdomainRoute( | |||
"Admin.Action", // Route name | |||
new List<string>() { "blog" }, // Subdomains | |||
new List<string>() { "admin" }, // Subdomains | |||
new List<string>() { config.Host }, | |||
"Action/{controller}/{action}", // URL with parameters | |||
new { controller = "Admin", action = "Dashboard" }, // Parameter defaults |
@@ -4,8 +4,10 @@ using System.Linq; | |||
using System.Web; | |||
using System.Web.Mvc; | |||
using Teknik.Areas.Admin.ViewModels; | |||
using Teknik.Areas.Users.Utility; | |||
using Teknik.Attributes; | |||
using Teknik.Controllers; | |||
using Teknik.Models; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.Controllers | |||
@@ -13,16 +15,53 @@ namespace Teknik.Areas.Admin.Controllers | |||
[TeknikAuthorize(Roles = "Admin")] | |||
public class AdminController : DefaultController | |||
{ | |||
private TeknikEntities db = new TeknikEntities(); | |||
[HttpGet] | |||
public ActionResult Dashboard() | |||
{ | |||
DashboardViewModel model = new DashboardViewModel(); | |||
return View(model); | |||
} | |||
[HttpGet] | |||
public ActionResult Search() | |||
{ | |||
SearchViewModel model = new SearchViewModel(); | |||
return View(model); | |||
} | |||
[HttpGet] | |||
public ActionResult UserInfo(string username) | |||
{ | |||
UserInfoViewModel model = new UserInfoViewModel(); | |||
model.Username = username; | |||
return View(model); | |||
} | |||
[HttpPost] | |||
public ActionResult GetSearchResults(string query) | |||
{ | |||
List<SearchResultViewModel> models = new List<SearchResultViewModel>(); | |||
var results = db.Users.Where(u => u.Username.Contains(query)).ToList(); | |||
if (results != null) | |||
{ | |||
foreach (Users.Models.User user in results) | |||
{ | |||
SearchResultViewModel model = new SearchResultViewModel(); | |||
model.Username = user.Username; | |||
if (Config.EmailConfig.Enabled) | |||
{ | |||
model.Email = string.Format("{0}@{1}", user.Username, Config.EmailConfig.Domain); | |||
} | |||
model.JoinDate = user.JoinDate; | |||
model.LastSeen = UserHelper.GetLastAccountActivity(db, Config, user); | |||
models.Add(model); | |||
} | |||
} | |||
return PartialView("~/Areas/Admin/Views/Admin/SearchResults.cshtml", models); | |||
} | |||
} | |||
} |
@@ -1 +1,21 @@ | |||
| |||
$(document).ready(function () { | |||
$('#Query').on('input', function (e) { | |||
query = $(this).val(); | |||
$.ajax({ | |||
type: "POST", | |||
url: searchResultsURL, | |||
data: { query: query }, | |||
success: function (html) { | |||
if (html) { | |||
if (html.error) { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + html.error + '</div>'); | |||
} | |||
else { | |||
$("#results").html(html); | |||
} | |||
} | |||
} | |||
}); | |||
}); | |||
}); |
@@ -9,5 +9,11 @@ namespace Teknik.Areas.Admin.ViewModels | |||
public class SearchResultViewModel : ViewModelBase | |||
{ | |||
public string Username { get; set; } | |||
public string Email { get; set; } | |||
public DateTime JoinDate { get; set; } | |||
public DateTime LastSeen { get; set; } | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.ViewModels | |||
{ | |||
public class UserInfoViewModel : ViewModelBase | |||
{ | |||
public string Username { get; set; } | |||
} | |||
} |
@@ -4,18 +4,20 @@ | |||
<script> | |||
// We need to define the action URLs for the script | |||
var searchResultsURL = '@Url.SubRouteUrl("admin", "Admin.Action")'; | |||
var searchResultsURL = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "GetSearchResults" })'; | |||
</script> | |||
@Scripts.Render("~/bundles/Search") | |||
<div class="container"> | |||
<div class="row"> | |||
<form class="form-inline"> | |||
<div class="form-group"> | |||
<input type="text" class="form-control" id="Query" name="Query" placeholder="Username" /> | |||
</div> | |||
</form> | |||
<div class="col-sm-6 col-sm-offset-3"> | |||
<form> | |||
<div class="form-group center-block"> | |||
<input type="text" class="form-control" id="Query" name="Query" placeholder="Username" /> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1"> |
@@ -1,7 +1,12 @@ | |||
@model Teknik.Areas.Admin.ViewModels.SearchResultViewModel | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1"> | |||
<a href="@Url.SubRouteUrl("admin", "Admin.UserInfo", new { username = Model.Username })">@Model.Username</a> | |||
<div class="row"> | |||
<div class="col-sm-3"> | |||
<a href="@Url.SubRouteUrl("admin", "Admin.UserInfo", new { username = Model.Username })">@Model.Username</a> | |||
</div> | |||
<div class="col-sm-3">@Model.Email</div> | |||
<div class="col-sm-3"><time datetime="@Model.JoinDate.ToString("s")">@Model.JoinDate.ToString("MMMM dd, yyyy hh:mm tt")</time></div> | |||
<div class="col-sm-3"><time datetime="@Model.LastSeen.ToString("s")">@Model.LastSeen.ToString("MMMM dd, yyyy hh:mm tt")</time></div> | |||
</div> | |||
</div> |
@@ -1,6 +1,19 @@ | |||
@model List<Teknik.Areas.Admin.ViewModels.SearchResultViewModel> | |||
@foreach (var post in Model) | |||
@if (Model.Any()) | |||
{ | |||
@Html.Partial("SearchResult", post) | |||
<div class="row text-center"> | |||
<div class="col-sm-3"><b>Username</b></div> | |||
<div class="col-sm-3"><b>Email</b></div> | |||
<div class="col-sm-3"><b>Join Date</b></div> | |||
<div class="col-sm-3"><b>Last Seen</b></div> | |||
</div> | |||
foreach (var post in Model) | |||
{ | |||
@Html.Partial("SearchResult", post) | |||
} | |||
} | |||
else | |||
{ | |||
<h3>No Results</h3> | |||
} |
@@ -0,0 +1,7 @@ | |||
@model Teknik.Areas.Admin.ViewModels.UserInfoViewModel | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1"> | |||
<a href="@Url.SubRouteUrl("user", "User.Index", new { username = Model.Username })">@Model.Username</a> | |||
</div> | |||
</div> |
@@ -5,6 +5,7 @@ using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Web; | |||
using System.Web.Mvc; | |||
namespace Teknik.Modules | |||
{ | |||
@@ -28,17 +29,17 @@ namespace Teknik.Modules | |||
timer.Stop(); | |||
// Don't interfere with non-HTML responses | |||
if (requestContext.Response.ContentType == "text/html" && requestContext.Response.StatusCode == 200) | |||
if (requestContext.Response.ContentType == "text/html" && requestContext.Response.StatusCode == 200 && !new HttpRequestWrapper(requestContext.Request).IsAjaxRequest()) | |||
{ | |||
double ms = (double)timer.ElapsedMilliseconds; | |||
string result = string.Format("{0:F0}", ms); | |||
requestContext.Response.Write( | |||
"<script type=\"text/javascript\">" + | |||
"<script type=\"text/javascript\">" + | |||
"var pageGenerationTime = '" + result + "';" + | |||
"pageloadStopTimer();" + | |||
"</script >"); | |||
} | |||
} | |||
}; | |||
} | |||
} |
@@ -188,6 +188,7 @@ | |||
<Compile Include="Areas\Admin\ViewModels\DashboardViewModel.cs" /> | |||
<Compile Include="Areas\Admin\ViewModels\SearchResultViewModel.cs" /> | |||
<Compile Include="Areas\Admin\ViewModels\SearchViewModel.cs" /> | |||
<Compile Include="Areas\Admin\ViewModels\UserInfoViewModel.cs" /> | |||
<Compile Include="Areas\API\APIAreaRegistration.cs" /> | |||
<Compile Include="Areas\API\Controllers\APIController.cs" /> | |||
<Compile Include="Areas\API\Controllers\APIv1Controller.cs" /> | |||
@@ -588,6 +589,7 @@ | |||
<Content Include="Areas\Admin\Views\Admin\SearchResults.cshtml" /> | |||
<Content Include="Areas\Admin\Views\_ViewStart.cshtml" /> | |||
<Content Include="App_Data\MachineKey.config" /> | |||
<Content Include="Areas\Admin\Views\Admin\UserInfo.cshtml" /> | |||
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" /> | |||
<None Include="Properties\PublishProfiles\Teknik Production.pubxml" /> | |||
<None Include="Scripts\jquery-2.1.4.intellisense.js" /> |