mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 15:20:48 -05:00
huge commit for webfront facelift
This commit is contained in:
@ -19,7 +19,7 @@
|
||||
{
|
||||
<tr>
|
||||
<td class="w-25">
|
||||
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@client.ClientId" class="link-inverse">@client.Name</a>
|
||||
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId" class="link-inverse">@client.Name</a>
|
||||
</td>
|
||||
<td class="w-25">
|
||||
@client.IPAddress
|
||||
@ -39,7 +39,7 @@
|
||||
{
|
||||
<div class="p-2 mb-3 border-bottom" style="background-color: #222;">
|
||||
<div class="d-flex flex-row">
|
||||
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@client.ClientId" class="h4 mr-auto">
|
||||
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId" class="h4 mr-auto">
|
||||
<color-code value="@client.Name"></color-code>
|
||||
</a>
|
||||
<div class="client-location-flag align-self-center" data-ip="@client.IPAddress"></div>
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
var lastHeaderEventDate = DateTime.UtcNow;
|
||||
|
||||
TimeSpan timeSpanForEvent(DateTime When)
|
||||
TimeSpan TimeSpanForEvent(DateTime occuredAt)
|
||||
{
|
||||
var timePassed = (DateTime.UtcNow - When);
|
||||
var timePassed = DateTime.UtcNow - occuredAt;
|
||||
var daysPassed = timePassed.TotalDays;
|
||||
var minutesPassed = timePassed.TotalMinutes;
|
||||
|
||||
@ -22,45 +22,43 @@
|
||||
return TimeSpan.FromHours(1);
|
||||
}
|
||||
|
||||
if (daysPassed > 1 && daysPassed <= 7)
|
||||
if (daysPassed is > 1 and <= 7)
|
||||
{
|
||||
return TimeSpan.FromDays(1);
|
||||
}
|
||||
|
||||
if (daysPassed > 7 && daysPassed <= 31)
|
||||
if (daysPassed is > 7 and <= 31)
|
||||
{
|
||||
return TimeSpan.FromDays(31);
|
||||
}
|
||||
|
||||
if (daysPassed > 31 && daysPassed <= 365)
|
||||
if (daysPassed is > 31 and <= 365)
|
||||
{
|
||||
return TimeSpan.FromDays(31);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return TimeSpan.FromDays(365);
|
||||
}
|
||||
return TimeSpan.FromDays(365);
|
||||
}
|
||||
}
|
||||
|
||||
@if (Model.Count() == 0)
|
||||
@{ var start = 0; }
|
||||
@foreach (var meta in Model.OrderByDescending(meta => meta.When))
|
||||
{
|
||||
<div class="p2 text-muted profile-event-timestep">@ViewBag.Localization["WEBFRONT_CLIENT_META_NONE"]</div>
|
||||
}
|
||||
|
||||
@foreach (var meta in Model.OrderByDescending(_meta => _meta.When))
|
||||
{
|
||||
@if ((lastHeaderEventDate - meta.When) > timeSpanForEvent(lastHeaderEventDate))
|
||||
if (lastHeaderEventDate - meta.When > TimeSpanForEvent(lastHeaderEventDate) && (start > 0 || (DateTime.UtcNow - meta.When).TotalDays > 3))
|
||||
{
|
||||
<div class="p2 text-white profile-event-timestep">
|
||||
<span class="text-primary">—</span>
|
||||
<span>@meta.When.HumanizeForCurrentCulture()</span>
|
||||
</div>
|
||||
TempData["ShowMetaHeader"] = true;
|
||||
lastHeaderEventDate = meta.When;
|
||||
}
|
||||
else
|
||||
{
|
||||
TempData["ShowMetaHeader"] = false;
|
||||
}
|
||||
start++;
|
||||
|
||||
<div class="profile-meta-entry loader-data-time" data-time="@meta.When.ToFileTimeUtc()" title="@Utilities.FormatExt(ViewBag.Localization["WEBFRONT_PROFILE_META_DATE_OCCURRED"], meta.When.ToString())">
|
||||
<partial name="~/Views/Client/Profile/Meta/_@(meta.GetType().Name).cshtml" model="meta" />
|
||||
<div class="profile-meta-entry loader-data-time" data-time="@meta.When.ToFileTimeUtc()" onclick="$('#metaContextDateToggle@(start)').show()">
|
||||
<partial name="~/Views/Client/Profile/Meta/_@(meta.GetType().Name).cshtml" model="meta"/>
|
||||
<div style="display:none" id="metaContextDateToggle@(start)">
|
||||
Event occured at <span class="text-light">@meta.When.ToString()</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
@model Exception
|
||||
@using SharedLibraryCore
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h4 class="text-danger">@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_TITLE"]</h4>
|
||||
<h4 class="text-danger">@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_DESC"]</h4>
|
||||
<strong class="text-warning">
|
||||
@if (Model != null)
|
||||
{
|
||||
@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_CODE"].FormatExt(Model.Message);
|
||||
}
|
||||
</strong>
|
||||
<div class="content">
|
||||
<h2 class="content-title text-danger">@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_TITLE"]</h2>
|
||||
<h2 class="content-title text-muted">@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_DESC"]</h2>
|
||||
<strong class="text-warning">
|
||||
@if (Model != null)
|
||||
{
|
||||
@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_CODE"].FormatExt(Model.Message)
|
||||
}
|
||||
</strong>
|
||||
</div>
|
||||
|
@ -2,12 +2,20 @@
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h4 class="text-danger">@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_TITLE"]</h4>
|
||||
<h4 class="text-danger">@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_DESC"]</h4>
|
||||
<strong class="text-warning">
|
||||
@if (Model.HasValue && Model.Value == 404)
|
||||
{
|
||||
@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_NOTFOUND"]
|
||||
}
|
||||
</strong>
|
||||
<div class="content">
|
||||
<div class="card m-0">
|
||||
<div class="d-flex">
|
||||
<div class="align-self-center w-100 h-100 mr-20 ui-error-icon"></div>
|
||||
<div>
|
||||
<h2 class="content-title text-primary mb-0">@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_TITLE"]</h2>
|
||||
<h2 class="content-title">@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_GENERIC_DESC"]</h2>
|
||||
<div class="text-muted">
|
||||
@if (Model is 404)
|
||||
{
|
||||
@Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_ERROR_NOTFOUND"]
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
69
WebfrontCore/Views/Shared/_DataTable.cshtml
Normal file
69
WebfrontCore/Views/Shared/_DataTable.cshtml
Normal file
@ -0,0 +1,69 @@
|
||||
@model WebfrontCore.ViewModels.TableInfo
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<h4 class="content-title mb-15 mt-15">
|
||||
<color-code value="@Model.Header"></color-code>
|
||||
</h4>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="bg-primary text-light d-none d-lg-table-row">
|
||||
@foreach (var column in Model.Columns)
|
||||
{
|
||||
<th>@column.Title</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@{ var start = 0;}
|
||||
@if (!Model.Rows.Any())
|
||||
{
|
||||
<!-- desktop -->
|
||||
<tr class="bg-dark-dm bg-light-lm d-none d-lg-table-row">
|
||||
<td colspan="@Model.Columns.Count">No data...</td>
|
||||
</tr>
|
||||
<!-- mobile -->
|
||||
<tr class="d-flex d-table-row d-lg-none">
|
||||
<td class="bg-primary text-light text-right w-125">
|
||||
—
|
||||
</td>
|
||||
<td class="bg-dark-dm bg-light-lm flex-fill w-200">No data...</td>
|
||||
</tr>
|
||||
}
|
||||
@foreach (var row in Model.Rows)
|
||||
{
|
||||
<!-- desktop -->
|
||||
<tr class="bg-dark-dm bg-light-lm @(Model.InitialRowCount > 0 && start >= Model.InitialRowCount ? "d-none hidden-row-lg": "d-none d-lg-table-row")">
|
||||
@for (var i = 0; i < Model.Columns.Count; i++)
|
||||
{
|
||||
<td>@row.Datum[i]</td>
|
||||
}
|
||||
</tr>
|
||||
|
||||
<!-- mobile -->
|
||||
<tr class="@(Model.InitialRowCount > 0 && start >= Model.InitialRowCount ? "d-none hidden-row": "d-flex d-table-row d-lg-none")">
|
||||
<td class="bg-primary text-light text-right w-125">
|
||||
@foreach (var column in Model.Columns)
|
||||
{
|
||||
<div class="mt-5 mb-5 text-truncate">@column.Title</div>
|
||||
}
|
||||
</td>
|
||||
<td class="bg-dark-dm bg-light-lm flex-fill w-200">
|
||||
@for (var i = 0; i < Model.Columns.Count; i++)
|
||||
{
|
||||
<div class="mt-5 mb-5 text-truncate" style="min-width:0">@row.Datum[i]</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
start++;
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
@if (Model.InitialRowCount > 0 && Model.Rows.Count > 0)
|
||||
{
|
||||
<button class="btn btn-block table-slide" data-toggle="tooltip" data-title="Show @(Model.Rows.Count - Model.InitialRowCount) more rows">
|
||||
<span class="oi oi-chevron-bottom"></span>
|
||||
</button>
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
@{
|
||||
var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex;
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html >
|
||||
<html xmlns="http://www.w3.org/1999/html" lang="@ViewBag.Language">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>@ViewBag.Title | IW4MAdmin</title>
|
||||
<meta property="og:title" content="@ViewBag.Title | IW4MAdmin">
|
||||
@ -16,111 +13,109 @@
|
||||
<meta name="keywords" content="@ViewBag.Keywords">
|
||||
<link rel="icon" type="image/png" href="~/images/icon.png">
|
||||
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/dynamic/css/global.css?version=@ViewBag.Version" />
|
||||
<link rel="stylesheet" href="~/lib/halfmoon/css/halfmoon-variables.css"/>
|
||||
<link rel="stylesheet" href="/css/src/main.css"/>
|
||||
@if (ViewBag.Configuration.WebfrontPrimaryColor is not null)
|
||||
{
|
||||
<style>
|
||||
:root {
|
||||
--blue-color: @ViewBag.Configuration.WebfrontPrimaryColor;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
@if (ViewBag.Configuration.WebfrontSecondaryColor is not null)
|
||||
{
|
||||
<style>
|
||||
:root {
|
||||
--yellow-color: @ViewBag.Configuration.WebfrontSecondaryColor;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
</environment>
|
||||
<environment include="Production">
|
||||
<link rel="stylesheet" href="~/dynamic/css/global.min.css?version=@ViewBag.Version" />
|
||||
<link rel="stylesheet" href="~/dynamic/css/global.min.css?version=@ViewBag.Version"/>
|
||||
</environment>
|
||||
@await RenderSectionAsync("styles", false)
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
@Html.ActionLink((string)ViewBag.CustomBranding, "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "Index", "Home", new {area = ""}, new {@class = "nav-link nav-icon oi oi-hard-drive", title=@loc["WEBFRONT_NAV_SERVERS"]})</li>
|
||||
<li class="nav-item text-center d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_SERVERS"], "Index", "Home", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
|
||||
@if (ViewBag.Configuration.CommunityInformation.IsEnabled)
|
||||
{
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "Index", "About", new {area = ""}, new {@class = "nav-link nav-icon oi oi-list-rich", title = loc["WEBFRONT_NAV_ABOUT"]})</li>
|
||||
<li class="nav-item text-center text-lg-left d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_ABOUT"], "Index", "About", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
}
|
||||
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "List", "Penalty", new {area = ""}, new {@class = "nav-link nav-icon oi oi-lock-locked", title=loc["WEBFRONT_NAV_PENALTIES"]})</li>
|
||||
<li class="nav-item text-center d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_PENALTIES"], "List", "Penalty", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
|
||||
@if (ViewBag.Authorized)
|
||||
{
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "PrivilegedAsync", "Client", new {area = ""}, new {@class = "nav-link nav-icon oi oi-people", title=loc["WEBFRONT_NAV_PRIVILEGED"]})</li>
|
||||
<li class="nav-item text-center text-lg-left d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_PRIVILEGED"], "PrivilegedAsync", "Client", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
}
|
||||
else if (!ViewBag.Authorized && !ViewBag.EnablePrivilegedUserPrivacy)
|
||||
{
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "PrivilegedAsync", "Client", new {area = ""}, new {@class = "nav-link nav-icon oi oi-people", title=loc["WEBFRONT_NAV_PRIVILEGED"]})</li>
|
||||
<li class="nav-item text-center text-lg-left d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_PRIVILEGED"], "PrivilegedAsync", "Client", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
}
|
||||
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">@Html.ActionLink("", "Help", "Home", new {area = ""}, new {@class = "nav-link nav-icon oi oi-question-mark", title=loc["WEBFRONT_NAV_HELP"]})</li>
|
||||
<li class="nav-item text-center text-lg-left d-lg-none d-xl-inline-block">@Html.ActionLink(loc["WEBFRONT_NAV_HELP"], "Help", "Home", new {area = ""}, new {@class = "nav-link"})</li>
|
||||
|
||||
@foreach (var _page in ViewBag.Pages)
|
||||
{
|
||||
if (_page.Location == "/Stats/TopPlayersAsync")
|
||||
{
|
||||
<li class="nav-item d-none d-lg-inline-block d-xl-none">
|
||||
<a class="nav-link nav-icon oi oi-bar-chart" href="@_page.Location" title="@_page.Name"></a>
|
||||
</li>
|
||||
<li class="nav-item text-center text-lg-left d-lg-none d-xl-inline-block">
|
||||
<a class="nav-link" href="@_page.Location">@_page.Name</a>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="nav-item text-center text-lg-left">
|
||||
<a class="nav-link" href="@_page.Location">@_page.Name</a>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
<li class="nav-item text-center text-lg-left"></li>
|
||||
@if (!string.IsNullOrEmpty(ViewBag.SocialLink))
|
||||
{
|
||||
<li class="nav-item text-center text-lg-left"><a href="@ViewBag.SocialLink" class="nav-link" target="_blank">@ViewBag.SocialTitle</a></li>
|
||||
}
|
||||
@if (ViewBag.Authorized)
|
||||
{
|
||||
<li class="nav-link dropdown text-center text-lg-left p-0">
|
||||
<a href="#" class="nav-link oi oi-person dropdown-toggle oi-fix-navbar w-100" id="account_dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></a>
|
||||
<body class="dark-mode with-custom-webkit-scrollbars with-custom-css-scrollbars" data-set-preferred-mode-onload="true">
|
||||
|
||||
<div class="dropdown-menu p-0" aria-labelledby="account_dropdown">
|
||||
<a asp-controller="Console" asp-action="Index" class="dropdown-item bg-dark text-muted text-center text-lg-left">@loc["WEBFRONT_NAV_CONSOLE"]</a>
|
||||
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@ViewBag.User.ClientId" class="dropdown-item bg-dark text-muted text-center text-lg-left">@loc["WEBFRONT_NAV_PROFILE"]</a>
|
||||
@if (ViewBag.User.Level >= SharedLibraryCore.Database.Models.EFClient.Permission.Owner)
|
||||
{
|
||||
<a asp-controller="Configuration" asp-action="Edit" class="dropdown-item bg-dark text-muted text-center text-lg-left">@loc["WEBFRONT_NAV_EDIT_CONFIGURATION"]</a>
|
||||
}
|
||||
<a asp-controller="Admin" asp-action="AuditLog" class="dropdown-item bg-dark text-muted text-center text-lg-left">@loc["WEBFRONT_NAV_AUDIT_LOG"]</a>
|
||||
<a class="dropdown-item bg-dark text-muted text-center text-lg-left profile-action" href="#" data-action="RecentClients" title="@loc["WEBFRONT_ACTION_RECENT_CLIENTS"]">@loc["WEBFRONT_ACTION_RECENT_CLIENTS"]</a>
|
||||
<a class="dropdown-item bg-dark text-muted text-center text-lg-left profile-action" href="#" data-action="GenerateLoginToken" title="@loc["WEBFRONT_ACTION_TOKEN"]">@loc["WEBFRONT_ACTION_TOKEN"]</a>
|
||||
<a asp-controller="Account" asp-action="LogoutAsync" class="dropdown-item bg-dark text-muted text-center text-lg-left">@loc["WEBFRONT_NAV_LOGOUT"]</a>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="nav-item text-center text-md-left">
|
||||
<a href="#" id="profile_action_login_btn" class="nav-link profile-action oi oi-key oi-fix-navbar w-100" title="Login" data-action="login" aria-hidden="true"></a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<form class="form-inline text-primary pt-3 pb-3" method="get" action="/Client/FindAsync">
|
||||
<input id="client_search" name="clientName" class="form-control mr-lg-2 w-100" type="text" placeholder="@loc["WEBFRONT_NAV_SEARCH"]" />
|
||||
</form>
|
||||
<!-- Action Modal -->
|
||||
<div class="modal" id="actionModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div id="modalLoadingBar" class="progress-bar position-absolute flex-fill position-fixed z-30" style="display:none">
|
||||
<div class="progress-bar-value"></div>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<div class="modal-content">
|
||||
<a href="#" class="btn close" role="button" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</a>
|
||||
<div id="actionModalContent">
|
||||
<h4 class="mt-20">No content available yet...</h4>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- loading icon -->
|
||||
<div class="oi oi-loop-circular layout-loading-icon"></div>
|
||||
<div class="page-wrapper with-navbar with-sidebar" data-sidebar-type="overlayed-sm-and-down">
|
||||
<!-- toast notifications -->
|
||||
<div class="sticky-alerts"></div>
|
||||
<!-- top menu bar -->
|
||||
<nav class="navbar">
|
||||
<button id="toggle-sidebar-btn" class="btn btn-action" type="button" onclick="halfmoon.toggleSidebar()">
|
||||
<i class="oi oi-menu" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
<!-- branding -->
|
||||
<a asp-controller="Home" asp-action="Index" class="navbar-brand mr-20 mr-md-0">
|
||||
<div>@ViewBag.CustomBranding</div>
|
||||
</a>
|
||||
|
||||
<!-- client badges -->
|
||||
<div class="d-none d-md-block">
|
||||
<div class="badge-group ml-20" role="group" aria-label="...">
|
||||
<span class="badge badge-primary">@(ViewBag.ClientCount ?? "-")</span>
|
||||
<span class="badge bg-dark-dm bg-light-lm">Clients</span>
|
||||
</div>
|
||||
|
||||
<has-permission entity="PrivilegedClientsPage" required-permission="Read">
|
||||
<div class="badge-group ml-10" role="group" aria-label="...">
|
||||
<span class="badge badge-success">@(ViewBag.AdminCount ?? "-")</span>
|
||||
<span class="badge bg-dark-dm bg-light-lm">Admins</span>
|
||||
</div>
|
||||
</has-permission>
|
||||
|
||||
<has-permission entity="AdminMenu" required-permission="Read">
|
||||
<div class="badge-group ml-10" role="group">
|
||||
<span class="badge badge-danger">@(ViewBag.ReportCount ?? "-")</span>
|
||||
<span class="badge bg-dark-dm bg-light-lm">Reports</span>
|
||||
</div>
|
||||
</has-permission>
|
||||
</div>
|
||||
|
||||
<div class="d-flex d-lg-none ml-auto">
|
||||
<a href="#contextMenuModal">
|
||||
<button class="btn" type="button">
|
||||
<i class="oi oi-ellipses"></i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@*<div class="d-none d-md-flex ml-auto">
|
||||
<div class="btn oi btn-square btn-action mr-10" data-glyph="moon" onclick="halfmoon.toggleDarkMode()" title="Toggle display mode"></div>
|
||||
</div>*@
|
||||
|
||||
<div class="d-none d-lg-block ml-auto">
|
||||
<partial name="_SearchResourceForm"/>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<partial name="_LeftNavBar"/>
|
||||
|
||||
<!-- Main Modal -->
|
||||
<div class="modal fade" id="mainModal" tabindex="-1" role="dialog" aria-labelledby="mainModalLabel" aria-hidden="true">
|
||||
<!--<div class="modal fade" id="mainModal" tabindex="-1" role="dialog" aria-labelledby="mainModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content bg-dark">
|
||||
<div class="modal-header">
|
||||
@ -133,75 +128,46 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- End Main Modal -->
|
||||
<!-- Action Modal -->
|
||||
<div class="modal fade" id="actionModal" tabindex="-1" role="dialog" aria-labelledby="actionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content bg-dark">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="actionModalLabel">IW4MAdmin</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true" class="text-danger">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="modal-message text-danger mb-3"></div>
|
||||
<div class="modal-body-content"></div>
|
||||
</div>
|
||||
<!--<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary">Action</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||
</div>-->
|
||||
</div>
|
||||
<div id="target_id">
|
||||
@await RenderSectionAsync("targetid", required: false)
|
||||
</div>
|
||||
|
||||
<!-- End Action Modal -->
|
||||
<div class="container-fluid content-wrapper">
|
||||
<div id="mainLoadingBar" class="progress-bar position-absolute flex-fill position-fixed z-30" style="display: none">
|
||||
<div class="progress-bar-value"></div>
|
||||
</div>
|
||||
|
||||
@RenderBody()
|
||||
|
||||
<div class="content">
|
||||
<div class="badge text-muted">threadsafe.pw</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="target_id">
|
||||
@RenderSection("targetid", required: false)
|
||||
</div>
|
||||
<!-- End Action Modal -->
|
||||
|
||||
<div class="@(ViewBag.IsFluid ?? false ? "container-fluid" : "container") pt-4 pb-4 pl-3 pr-3 pr-lg-4 pl-lg-4">
|
||||
@RenderBody()
|
||||
<footer id="footer_text">
|
||||
<div class="d-lg-none d-block text-center pt-4 pb-4">
|
||||
<a href="https://github.com/RaidMax/IW4M-Admin/releases" target="_blank">
|
||||
@Program.Manager.Version
|
||||
</a>
|
||||
<br />
|
||||
<span class="text-muted">Developed by RaidMax</span>
|
||||
</div>
|
||||
<div class="footer-mobile d-lg-block d-none text-center">
|
||||
<a href="https://github.com/RaidMax/IW4M-Admin/releases" target="_blank">
|
||||
@Program.Manager.Version
|
||||
</a>
|
||||
<br />
|
||||
<span class="text-muted">Developed by RaidMax</span>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<environment include="Development">
|
||||
<script type="text/javascript" src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="~/lib/popper.js/dist/umd/popper.js"></script>
|
||||
<script type="text/javascript" src="~/lib/moment.js/moment.js"></script>
|
||||
<script type="text/javascript" src="~/lib/moment-timezone/moment-timezone.js"></script>
|
||||
<script type="text/javascript" src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||
<script type="text/javascript" src="~/lib/canvas.js/canvasjs.js"></script>
|
||||
<script type="text/javascript" src="~/lib/chart.js/dist/Chart.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="~/js/action.js"></script>
|
||||
<script type="text/javascript" src="~/js/search.js"></script>
|
||||
</environment>
|
||||
<environment include="Production">
|
||||
<script type="text/javascript" src="~/js/global.min.js?version=@ViewBag.Version"></script>
|
||||
</environment>
|
||||
<script>
|
||||
</div>
|
||||
<environment include="Development">
|
||||
<script type="text/javascript" src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="~/lib/moment.js/moment.js"></script>
|
||||
<script type="text/javascript" src="~/lib/moment-timezone/moment-timezone.js"></script>
|
||||
<script type="text/javascript" src="~/lib/chart.js/dist/Chart.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="~/lib/halfmoon/js/halfmoon.js"></script>
|
||||
<script type="text/javascript" src="~/js/action.js"></script>
|
||||
<script type="text/javascript" src="~/js/search.js"></script>
|
||||
</environment>
|
||||
<environment include="Production">
|
||||
<script type="text/javascript" src="~/js/global.min.js?version=@ViewBag.Version"></script>
|
||||
</environment>
|
||||
<script>
|
||||
let _localizationTmp = @Html.Raw(Json.Serialize(ViewBag.Localization));
|
||||
const _localization = [];
|
||||
$.each(_localizationTmp.set, function (key, value) {
|
||||
_localization[key] = value;
|
||||
});
|
||||
</script>
|
||||
@await RenderSectionAsync("scripts", required: false)
|
||||
@Html.Raw(ViewBag.ScriptInjection)
|
||||
@await RenderSectionAsync("scripts", required: false)
|
||||
@Html.Raw(ViewBag.ScriptInjection)
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
166
WebfrontCore/Views/Shared/_LeftNavBar.cshtml
Normal file
166
WebfrontCore/Views/Shared/_LeftNavBar.cshtml
Normal file
@ -0,0 +1,166 @@
|
||||
@using SharedLibraryCore.Configuration
|
||||
@using SharedLibraryCore.Dtos
|
||||
@using Data.Models.Client
|
||||
|
||||
<!-- left side navigation -->
|
||||
<div class="sidebar-overlay" onclick="halfmoon.toggleSidebar()"></div>
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu list">
|
||||
<div class="sidebar-content m-0">
|
||||
<div class="pr-20 pl-20 mb-20 d-block d-lg-none">
|
||||
<partial name="_SearchResourceForm"/>
|
||||
</div>
|
||||
<span class="sidebar-title ">Main</span>
|
||||
<div class="sidebar-divider"></div>
|
||||
<!-- servers -->
|
||||
<a asp-controller="Home" asp-action="Index" class="sidebar-link">
|
||||
<i class="oi oi-hard-drive mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_SERVERS"]</span>
|
||||
</a>
|
||||
<!-- about -->
|
||||
<a asp-controller="About" asp-action="Index" class="sidebar-link">
|
||||
<i class="oi oi-info mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_ABOUT"]</span>
|
||||
</a>
|
||||
<!-- penalties -->
|
||||
<a asp-controller="Penalty" asp-action="List" class="sidebar-link">
|
||||
<i class="oi oi-lock-locked mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_PENALTIES"]</span>
|
||||
</a>
|
||||
<!-- privileged -->
|
||||
<has-permission entity="PrivilegedClientsPage" required-permission="Read">
|
||||
<a asp-controller="Client" asp-action="Privileged" class="sidebar-link">
|
||||
<i class="oi oi-people mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_PRIVILEGED"]</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
<!-- help -->
|
||||
<has-permission entity="HelpPage" required-permission="Read">
|
||||
<a asp-controller="Home" asp-action="Help" class="sidebar-link">
|
||||
<i class="oi oi-question-mark mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_HELP"]</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
<!-- profile -->
|
||||
<has-permission entity="ProfilePage" required-permission="Read">
|
||||
<a asp-controller="Client" asp-action="Profile" asp-route-id="@ViewBag.User.ClientId" class="sidebar-link">
|
||||
<i class="oi oi-person mr-5"></i>
|
||||
<span class="name">Profile</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
|
||||
@if (!ViewBag.Authorized)
|
||||
{
|
||||
<a href="#actionModal" class="profile-action sidebar-link" data-action="login">
|
||||
<i class="oi oi-key mr-5"></i>
|
||||
<span class="name">Login</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
<br/>
|
||||
<!-- stats -->
|
||||
<div class="sidebar-title ">Stats</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
|
||||
@foreach (Page pageLink in ViewBag.Pages)
|
||||
{
|
||||
<a class="sidebar-link" href="@pageLink.Location">
|
||||
<i class="oi @(pageLink.Location.EndsWith("Radar/All") ? "oi-wifi" : "oi-bar-chart") mr-5"></i>
|
||||
<span class="name">@pageLink.Name</span>
|
||||
</a>
|
||||
}
|
||||
<!-- scoreboard -->
|
||||
<a asp-controller="Server" asp-action="Scoreboard" class="sidebar-link">
|
||||
<i class="oi oi-spreadsheet mr-5"></i>
|
||||
<span class="name">Scoreboard</span>
|
||||
</a>
|
||||
<br/>
|
||||
|
||||
<!-- socials -->
|
||||
@if (ViewBag.CommunityInformation?.IsEnabled && ViewBag.CommunityInformation.SocialAccounts.Length > 0)
|
||||
{
|
||||
<span class="sidebar-title ">Socials</span>
|
||||
<div class="sidebar-divider"></div>
|
||||
}
|
||||
|
||||
@foreach (var social in ViewBag.CommunityInformation?.SocialAccounts ?? Array.Empty<SocialAccountConfiguration>())
|
||||
{
|
||||
<a href="@social.Url" class="sidebar-link" target="_blank" title="@social.Title">
|
||||
@if (!string.IsNullOrWhiteSpace(social.IconId))
|
||||
{
|
||||
<i class="oi @social.IconId mr-5"></i>
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(social.IconUrl))
|
||||
{
|
||||
var url = Uri.TryCreate(social.IconUrl, UriKind.Absolute, out Uri parsedUrl)
|
||||
? parsedUrl.AbsoluteUri
|
||||
: $"/images/community/{social.IconUrl}";
|
||||
<img class="img-fluid mr-5" style="max-height: 1.2rem" src="@url" alt="@social.Title"/>
|
||||
}
|
||||
<span class="name">@social.Title</span>
|
||||
</a>
|
||||
}
|
||||
<br/>
|
||||
|
||||
<!-- admin -->
|
||||
<has-permission entity="AdminMenu" required-permission="Read">
|
||||
<div class="sidebar-title ">Admin</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
|
||||
<has-permission entity="ConsolePage" required-permission="Read">
|
||||
<a asp-controller="Console" asp-action="Index" class="sidebar-link">
|
||||
<i class="oi oi-terminal mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_CONSOLE"]</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
@if (ViewBag.User.Level == EFClient.Permission.Owner)
|
||||
{
|
||||
<a asp-controller="Configuration" asp-action="Edit" class="sidebar-link">
|
||||
<i class="oi oi-cog mr-5"></i>
|
||||
<span class="name">Configuration</span>
|
||||
</a>
|
||||
}
|
||||
<has-permission entity="AuditPage" required-permission="Read">
|
||||
<a asp-controller="Admin" asp-action="AuditLog" class="sidebar-link">
|
||||
<i class="oi oi-book mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_AUDIT_LOG"]</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
@*<has-permission entity="RecentPlayersPage" required-permission="Read">
|
||||
<a class="sidebar-link profile-action" href="#actionModal" data-action="RecentClients" title="@ViewBag.Localization["WEBFRONT_ACTION_RECENT_CLIENTS"]">
|
||||
<i class="oi oi-timer mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_ACTION_RECENT_CLIENTS"]</span>
|
||||
</a>
|
||||
</has-permission>*@
|
||||
<a class="sidebar-link profile-action" href="#actionModal" data-action="GenerateLoginToken" title="@ViewBag.Localization["WEBFRONT_ACTION_TOKEN"]">
|
||||
<i class="oi oi-key mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_ACTION_TOKEN"]</span>
|
||||
</a>
|
||||
</has-permission>
|
||||
@if (ViewBag.Authorized)
|
||||
{
|
||||
<a asp-controller="Account" asp-action="Logout" class="sidebar-link">
|
||||
<i class="oi oi-account-logout mr-5"></i>
|
||||
<span class="name">@ViewBag.Localization["WEBFRONT_NAV_LOGOUT"]</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
<br/>
|
||||
<!-- version -->
|
||||
<div class="sidebar-link font-size-12 font-weight-light">
|
||||
@if (ViewBag.Authorized)
|
||||
{
|
||||
<span>Logged in as <color-code value="@ViewBag.User.Name"></color-code></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>Not logged in</span>
|
||||
}
|
||||
</div>
|
||||
<div class="sidebar-divider mt-0 mb-0"></div>
|
||||
<a href="https://github.com/RaidMax/IW4M-Admin/releases" class="sidebar-link" target="_blank">
|
||||
<span class="name font-size-12 font-weight-light">IW4MAdmin <span class="text-primary">@Program.Manager.Version</span></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
19
WebfrontCore/Views/Shared/_LoginForm.cshtml
Normal file
19
WebfrontCore/Views/Shared/_LoginForm.cshtml
Normal file
@ -0,0 +1,19 @@
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<form class="action-form" asp-action="Login" asp-controller="Account">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon-clientId">Client ID</span>
|
||||
</div>
|
||||
<input type="text" name="clientId" value="" class="form-control" aria-label="clientId" aria-describedby="basic-addon-clientId">
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon-Password">Token/Password</span>
|
||||
</div>
|
||||
<input type="password" name="Password" value="" class="form-control" aria-label="Password" aria-describedby="basic-addon-Password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-block btn-primary">Login</button>
|
||||
</form>
|
12
WebfrontCore/Views/Shared/_SearchResourceForm.cshtml
Normal file
12
WebfrontCore/Views/Shared/_SearchResourceForm.cshtml
Normal file
@ -0,0 +1,12 @@
|
||||
<form class="form-inline ml-auto" method="get" asp-controller="Client" asp-action="Find">
|
||||
<div class="input-group">
|
||||
<input id="client_search_mobile" name="clientName" class="form-control" type="text" placeholder="@ViewBag.Localization["WEBFRONT_NAV_SEARCH"]" required="required"/>
|
||||
<div class="input-group-append">
|
||||
<button class="btn" type="submit">
|
||||
<i class="oi oi-magnifying-glass"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
</form>
|
44
WebfrontCore/Views/Shared/_SideContextMenu.cshtml
Normal file
44
WebfrontCore/Views/Shared/_SideContextMenu.cshtml
Normal file
@ -0,0 +1,44 @@
|
||||
@model WebfrontCore.ViewModels.SideContextMenuItems
|
||||
@{ Layout = null; }
|
||||
|
||||
<div class="d-none d-lg-flex col-3 col-xl-2">
|
||||
<div class="content mt-0">
|
||||
<div class="on-this-page-nav pt-0">
|
||||
<div class="title">@Model.MenuTitle</div>
|
||||
|
||||
@foreach (var item in Model.Items)
|
||||
{
|
||||
<a href="@(item.IsLink ? item.Reference : "#actionModal")" class="@(item.IsLink ? "" : "profile-action")" data-action="@(item.IsLink ? "" : item.Reference)">
|
||||
<div class="@(item.IsButton ? "btn btn-block" : "")" data-title="@item.Tooltip" data-placement="left" data-toggle="@(string.IsNullOrEmpty(item.Tooltip) ? "" : "tooltip")">
|
||||
<i class="@(string.IsNullOrEmpty(item.Icon) ? "" : $"oi {item.Icon}") mr-5 font-size-12"></i>
|
||||
<span class="@(item.IsActive ? "text-primary" : "") text-truncate">@item.Title</span>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="contextMenuModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-content">
|
||||
<div class="content-title">@Model.MenuTitle</div>
|
||||
<hr/>
|
||||
@foreach (var item in Model.Items)
|
||||
{
|
||||
<div class="mt-15 mb-15">
|
||||
<a href="@(item.IsLink ? item.Reference : "#actionModal")" class="@(item.IsLink ? "" : "profile-action") no-decoration" data-action="@(item.IsLink ? "" : item.Reference)">
|
||||
<div class="btn btn-block btn-lg @(item.IsActive ? "btn-primary" : "") text-truncate" data-title="@item.Tooltip" data-toggle="@(string.IsNullOrEmpty(item.Tooltip) ? "" : "tooltip")">
|
||||
<i class="@(string.IsNullOrEmpty(item.Icon) ? "" : $"oi {item.Icon}") mr-5 font-size-12"></i>
|
||||
<span>@item.Title</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
<hr/>
|
||||
<a href="#" class="btn btn-lg btn-danger btn-block mt-15" role="button">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user