Updated layout to support settings and customization
This commit is contained in:
Родитель
18e8ee8a87
Коммит
b6f84f613c
|
@ -1,24 +0,0 @@
|
|||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
|
||||
@inject NavigationManager Navigation
|
||||
@inject SignOutSessionStateManager SignOutManager
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<a href="authentication/profile">Hello, @context.User.Identity.Name!</a>
|
||||
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<a href="authentication/register">Register</a>
|
||||
<a href="authentication/login">Log in</a>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
|
||||
@code{
|
||||
private async Task BeginSignOut(MouseEventArgs args)
|
||||
{
|
||||
await SignOutManager.SetSignOutState();
|
||||
Navigation.NavigateTo("authentication/logout");
|
||||
}
|
||||
}
|
|
@ -1,44 +1,81 @@
|
|||
@inherits LayoutComponentBase
|
||||
@inject NavigationManager navigationManger
|
||||
@using BlazingCoffee.Client.Shared.NavMenu
|
||||
|
||||
<header class="header">
|
||||
<div class="nav-container">
|
||||
<div class="menu-button">
|
||||
<TelerikButton Icon="@IconName.Menu" OnClick="@(() => Expanded = !Expanded)" />
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<h1>Blazing Coffee Warehouse</h1>
|
||||
</div>
|
||||
<div class="settings">
|
||||
@*<span>Language</span>*@
|
||||
<LoginDisplay />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<TelerikRootComponent>
|
||||
<TelerikDrawer @bind-Expanded="@Expanded" @bind-SelectedItem="SelectedItem"
|
||||
Data="Data" MiniMode="true" Mode="DrawerMode.Push">
|
||||
<TelerikDrawer @bind-Expanded="@Expanded" Width="280px" Data="Data" Mode="DrawerMode.Push" Position="DrawerPosition.Left">
|
||||
<Template>
|
||||
<DrawTemplate Data="context"></DrawTemplate>
|
||||
</Template>
|
||||
<Content>
|
||||
<header class="header">
|
||||
<div class="nav-container">
|
||||
<div class="menu-button">
|
||||
<TelerikButton Icon="@IconName.Menu" OnClick="@(() => Expanded = !Expanded)" />
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<h1>Blazing Coffee Warehouse</h1>
|
||||
</div>
|
||||
<div class="settings">
|
||||
<TelerikButton Icon="@IconName.Gear" OnClick="@(() => SettingsExpanded = !SettingsExpanded)" />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@Body
|
||||
</Content>
|
||||
</TelerikDrawer>
|
||||
<TelerikWindow @bind-Visible="SettingsExpanded" Modal="true">
|
||||
<WindowTitle>
|
||||
Settings
|
||||
</WindowTitle>
|
||||
<WindowActions>
|
||||
<WindowAction Name="Close" />
|
||||
</WindowActions>
|
||||
<WindowContent>
|
||||
<div class="k-widget k-form">
|
||||
<div class="k-form-field">
|
||||
<label class="k-label k-form-label" for="theme">
|
||||
Theme
|
||||
</label>
|
||||
<div class="k-form-field-wrap">
|
||||
<TelerikDropDownList Id="theme" Data="Themes" TValue="string" TItem="string" @bind-Value="SelectedTheme" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="k-form-field">
|
||||
<label class="k-label k-form-label" for="language">
|
||||
Language
|
||||
</label>
|
||||
<div class="k-form-field-wrap">
|
||||
<TelerikDropDownList Id="language" Data="Languages" TValue="string" TItem="string" @bind-Value="SelectedLanguage" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WindowContent>
|
||||
</TelerikWindow>
|
||||
</TelerikRootComponent>
|
||||
|
||||
@code {
|
||||
bool Expanded { get; set; } = false;
|
||||
object SelectedItem { get; set; }
|
||||
bool Expanded { get; set; } = true;
|
||||
bool SettingsExpanded { get; set; }
|
||||
|
||||
IEnumerable<object> Data { get; set; } =
|
||||
new List<object>
|
||||
{
|
||||
new { Text = "Home", Icon = IconName.ArrowRoot, Url="/"},
|
||||
new { Text = "Sales", Icon = IconName.Dollar, Url="/sales"},
|
||||
new { Text = "Human Capital", Icon = IconName.TellAFriend, Url="/manage-employees"},
|
||||
new { Text = "Manage Products", Icon = IconName.Grid, Url="/manage-products"}
|
||||
};
|
||||
|
||||
protected override void OnInitialized()
|
||||
IEnumerable<DrawerItem> Data =>
|
||||
new List<DrawerItem>
|
||||
{
|
||||
SelectedItem = Data.First();
|
||||
}
|
||||
new DrawerItem{ Text = "Home", Icon = IconName.ArrowRoot, Url="/", Group = "app"},
|
||||
new DrawerItem{ Text = "Sales", Icon = IconName.Dollar, Url="/sales", Group = "app"},
|
||||
new DrawerItem{ Text = "Human Capital", Icon = IconName.TellAFriend, Url="/manage-employees", Group = "app"},
|
||||
new DrawerItem{ Text = "Manage Products", Icon = IconName.Grid, Url="/manage-products", Group = "app"},
|
||||
new DrawerItem{ Text = "GitHub", Icon = IconName.Share, Url="https://github.com/telerik/blazing-coffee", Group = "ext"},
|
||||
new DrawerItem{ Text = "Telerik", Icon = IconName.HyperlinkGlobe, Url="https://telerik.com", Group = "ext"},
|
||||
new DrawerItem{ Text = "Documentation", Icon = IconName.Html, Url="https://docs.telerik.com/blazor-ui/introduction", Group = "ext"},
|
||||
new DrawerItem{ Text = "Support", Icon = IconName.Question, Url="https://www.telerik.com/account/support-tickets", Group = "ext"}
|
||||
};
|
||||
|
||||
string SelectedTheme = "auto";
|
||||
IEnumerable<string> Themes => new List<string> { "auto" }; // TODO add manual settings, "light", "dark" };
|
||||
|
||||
string SelectedLanguage = "en";
|
||||
IEnumerable<string> Languages => new List<string> { "en" }; // TODO add Globalization
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
@inject NavigationManager navigationManger
|
||||
@using BlazingCoffee.Client.Shared.NavMenu
|
||||
|
||||
<div class="k-drawer-items">
|
||||
<header>
|
||||
<LoginDisplay />
|
||||
</header>
|
||||
<ul role="menubar" aria-orientation="vertical">
|
||||
@foreach (DrawerItem item in Data.Where(item => item.Group == "app"))
|
||||
{
|
||||
if (item == SelectedItem)
|
||||
{
|
||||
<li class="k-drawer-item k-state-selected" data-index="0" tabindex="0" role="menuitem" aria-label="@item.Text">
|
||||
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
|
||||
<span class="k-item-text">@item.Text</span>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="k-drawer-item" data-index="1" tabindex="-1" role="menuitem" aria-label="@item.Text" @onclick="@(()=> ItemSelected(item))">
|
||||
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
|
||||
<span class="k-item-text">@item.Text</span>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<footer>
|
||||
<h3 class="title">More Info</h3>
|
||||
<ul role="menubar" aria-orientation="vertical">
|
||||
@foreach (DrawerItem item in Data.Where(item => item.Group == "ext"))
|
||||
{
|
||||
<li class="k-drawer-item" data-index="1" tabindex="-1" role="menuitem" aria-label="@item.Text" @onclick="@(()=>navigationManger.NavigateTo(item.Url))">
|
||||
<TelerikIcon Icon="@item.Icon"></TelerikIcon>
|
||||
<span class="k-item-text">@item.Text</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public IEnumerable<DrawerItem> Data { get; set; }
|
||||
|
||||
DrawerItem SelectedItem;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
SelectedItem = Data.First();
|
||||
}
|
||||
|
||||
void ItemSelected(DrawerItem item)
|
||||
{
|
||||
SelectedItem = item;
|
||||
navigationManger.NavigateTo(item.Url);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace BlazingCoffee.Client.Shared.NavMenu
|
||||
{
|
||||
public class DrawerItem
|
||||
{
|
||||
public string Text { get; set; }
|
||||
|
||||
public string Icon { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public string Group { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
@using System.Security.Cryptography
|
||||
@using System.Text
|
||||
@inject NavigationManager Navigation
|
||||
@inject SignOutSessionStateManager SignOutManager
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<TelerikButton Icon="@IconName.User" @onclick="BeginSignOut">Log out</TelerikButton>
|
||||
<img class="k-avatar-rounded" src="@HashEmailForGravatar(context.User.Identity.Name)" />
|
||||
<a href="authentication/profile">@context.User.Identity.Name</a>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<a href="authentication/register">Register</a>
|
||||
<a href="authentication/login">Log in</a>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
|
||||
@code{
|
||||
private async Task BeginSignOut(MouseEventArgs args)
|
||||
{
|
||||
await SignOutManager.SetSignOutState();
|
||||
Navigation.NavigateTo("authentication/logout");
|
||||
}
|
||||
|
||||
/// Hashes an email with MD5. Suitable for use with Gravatar profile
|
||||
/// image urls
|
||||
|
||||
string HashEmailForGravatar(string email)
|
||||
{
|
||||
// Create a new instance of the MD5CryptoServiceProvider object.
|
||||
MD5 md5Hasher = MD5.Create();
|
||||
|
||||
// Convert the input string to a byte array and compute the hash.
|
||||
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(email));
|
||||
|
||||
// Create a new Stringbuilder to collect the bytes
|
||||
// and create a string.
|
||||
StringBuilder sBuilder = new StringBuilder("https://www.gravatar.com/avatar/");
|
||||
|
||||
// Loop through each byte of the hashed data
|
||||
// and format each one as a hexadecimal string.
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
sBuilder.Append(data[i].ToString("x2"));
|
||||
}
|
||||
|
||||
return sBuilder.ToString(); // Return the hexadecimal string.
|
||||
}
|
||||
}
|
|
@ -1,9 +1,32 @@
|
|||
.k-drawer-container {
|
||||
background-color: $background-color;
|
||||
min-height: calc(100vh - 80px);
|
||||
min-height: calc(100vh);
|
||||
|
||||
.k-drawer {
|
||||
box-shadow: 0 0 10px rgba(0,0,0,.2);
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.k-drawer-items {
|
||||
& .title {
|
||||
text-transform: uppercase;
|
||||
font-size: 1em;
|
||||
padding: 1em;
|
||||
font-weight: bold;
|
||||
color: $info;
|
||||
}
|
||||
|
||||
& > header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 1em;
|
||||
|
||||
& > img {
|
||||
border: 2px solid $success;
|
||||
margin: 1em;
|
||||
max-width: 96px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,21 +15,21 @@
|
|||
}
|
||||
|
||||
.menu-button {
|
||||
flex: 0 0 50px;
|
||||
flex: 0 0 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.k-button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
color: $primary-contrast;
|
||||
}
|
||||
.k-button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
color: $primary-contrast;
|
||||
}
|
||||
|
||||
.k-button:hover {
|
||||
background-color: $info;
|
||||
padding: 5px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.k-button:hover {
|
||||
background-color: $info;
|
||||
padding: 5px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -52,10 +52,6 @@
|
|||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
|
@ -89,7 +85,6 @@
|
|||
color: $info;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.k-dropdown {
|
||||
|
|
|
@ -35,4 +35,13 @@ a.k-link.k-state-selected {
|
|||
|
||||
.validation-message {
|
||||
color: $error;
|
||||
}
|
||||
|
||||
.k-window {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.k-window-titlebar {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
Загрузка…
Ссылка в новой задаче