Users page and users service
This commit is contained in:
@@ -1,7 +0,0 @@
|
|||||||
namespace FoodsharingSiegen.Contracts.Entity
|
|
||||||
{
|
|
||||||
public class dfg
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
138
FoodsharingSiegen.Contracts/OperationResult.cs
Normal file
138
FoodsharingSiegen.Contracts/OperationResult.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
namespace FoodsharingSiegen.Contracts
|
||||||
|
{
|
||||||
|
#region OperationResult<T>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Encapsulates the result of an operation. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <typeparam name="T"> Generic type parameter. </typeparam>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public class OperationResult<T>
|
||||||
|
{
|
||||||
|
#region Public Properties
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Gets or sets the exception. </summary>
|
||||||
|
///
|
||||||
|
/// <value> The exception. </value>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Exception? Exception { get; set; }
|
||||||
|
|
||||||
|
/// <summary> Returns an error message if the exception is set </summary>
|
||||||
|
public string ErrorMessage
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Success) return string.Empty;
|
||||||
|
return Exception != null ? Exception.GetBaseException().Message : "Fehler";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Gets or sets a value indicating whether the success. </summary>
|
||||||
|
///
|
||||||
|
/// <value> True if success, false if not. </value>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public bool Success { get; set; } = true;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Gets or sets the data. </summary>
|
||||||
|
///
|
||||||
|
/// <value> The data. </value>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public T? Data { get; set; }
|
||||||
|
|
||||||
|
#endregion Public Properties
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="exception"> The exception. </param>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult(Exception exception)
|
||||||
|
{
|
||||||
|
Success = false;
|
||||||
|
Exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="data"> The data. </param>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult(T data)
|
||||||
|
{
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Default constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 22.10.2021. </remarks>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Constructors
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion OperationResult<T>
|
||||||
|
|
||||||
|
#region OperationResult
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Encapsulates the result of an operation. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public class OperationResult : OperationResult<object>
|
||||||
|
{
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="exception"> The exception. </param>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult(Exception exception) : base(exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="data"> True to data. </param>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult(bool data) : base(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Default constructor. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 22.10.2021. </remarks>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public OperationResult()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Constructors
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion OperationResult
|
||||||
|
}
|
||||||
21
FoodsharingSiegen.Server/Data/Service/ServiceBase.cs
Normal file
21
FoodsharingSiegen.Server/Data/Service/ServiceBase.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
namespace FoodsharingSiegen.Server.Data.Service
|
||||||
|
{
|
||||||
|
public class ServiceBase
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Database Context </summary>
|
||||||
|
///
|
||||||
|
/// <value> The context. </value>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
protected FsContext Context { get; }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Specialised constructor for use only by derived class. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="context"> The context. </param>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
protected ServiceBase(FsContext context) => Context = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
FoodsharingSiegen.Server/Data/Service/UserService.cs
Normal file
73
FoodsharingSiegen.Server/Data/Service/UserService.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using FoodsharingSiegen.Contracts;
|
||||||
|
using FoodsharingSiegen.Contracts.Entity;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace FoodsharingSiegen.Server.Data.Service
|
||||||
|
{
|
||||||
|
public class UserService : ServiceBase
|
||||||
|
{
|
||||||
|
public UserService(FsContext context) : base(context)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult<User>> AddUserAsync(User user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (await Context.Users.AnyAsync(x => x.Mail.ToLower().Equals(user.Mail.ToLower())))
|
||||||
|
return new OperationResult<User>(new Exception("Diese E-Mail Adresse wird bereits verwendet"));
|
||||||
|
|
||||||
|
user.Created = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await Context.Users.AddAsync(user);
|
||||||
|
|
||||||
|
var saveResult = await Context.SaveChangesAsync();
|
||||||
|
if (saveResult == 0) return new OperationResult<User>(new Exception("Fehler bei der Registrierung"));
|
||||||
|
|
||||||
|
return new OperationResult<User>(user);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return new OperationResult<User>(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OperationResult> Update(User user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Context.Users.Update(user);
|
||||||
|
var saveR = await Context.SaveChangesAsync();
|
||||||
|
|
||||||
|
if(saveR < 1) return new OperationResult(new Exception("Fehler beim speichern"));
|
||||||
|
return new OperationResult();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return new OperationResult(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Gets users asynchronous. </summary>
|
||||||
|
///
|
||||||
|
/// <remarks> A Beging, 20.10.2021. </remarks>
|
||||||
|
///
|
||||||
|
/// <returns> An asynchronous result that yields the users. </returns>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
public async Task<OperationResult<List<User>>> GetUsersAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var users = await Context.Users.ToListAsync();
|
||||||
|
return new OperationResult<List<User>>(users);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return new OperationResult<List<User>>(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
@page "/"
|
|
||||||
|
|
||||||
<PageTitle>Index</PageTitle>
|
|
||||||
|
|
||||||
<h1>Hello, world!</h1>
|
|
||||||
|
|
||||||
Welcome to your new app.
|
|
||||||
|
|
||||||
<SurveyPrompt Title="How is Blazor working for you?"/>
|
|
||||||
72
FoodsharingSiegen.Server/Pages/Users.razor
Normal file
72
FoodsharingSiegen.Server/Pages/Users.razor
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
@page "/"
|
||||||
|
@using FoodsharingSiegen.Contracts.Entity
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private RenderFragment PopupTitleTemplate(PopupTitleContext<User> value)
|
||||||
|
{
|
||||||
|
var header = "Benutzer erstellen";
|
||||||
|
if (value.EditState == DataGridEditState.Edit) header = "Benutzer bearbeiten";
|
||||||
|
|
||||||
|
return builder =>
|
||||||
|
{
|
||||||
|
builder.OpenElement(0, "span");
|
||||||
|
builder.AddContent(1, header);
|
||||||
|
builder.CloseElement();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<PageTitle>Benutzer</PageTitle>
|
||||||
|
|
||||||
|
<h2>Benutzerverwaltung <span style="font-size: .5em; line-height: 0;">Admin</span></h2>
|
||||||
|
|
||||||
|
<DataGrid TItem="User"
|
||||||
|
@ref="UserDataGrid"
|
||||||
|
Data="@UserList"
|
||||||
|
CommandMode="DataGridCommandMode.Commands"
|
||||||
|
EditMode="DataGridEditMode.Popup"
|
||||||
|
PopupTitleTemplate="PopupTitleTemplate"
|
||||||
|
RowInserted="RowInserted"
|
||||||
|
RowUpdated="RowUpdated"
|
||||||
|
RowDoubleClicked="arg => UserDataGrid.Edit(arg.Item)"
|
||||||
|
Editable
|
||||||
|
Responsive>
|
||||||
|
<DataGridColumns>
|
||||||
|
<DataGridCommandColumn TItem="User" Caption="Wololo" Width="100px" CellStyle="@(_ => "display: flex; padding-left: 0; padding-right: 0; justify-content: center; align-items: center;")">
|
||||||
|
<NewCommandTemplate>
|
||||||
|
<Button Size="Size.ExtraSmall" Color="Color.Success" Clicked="@context.Clicked" Class="mr-1" Style="min-width: auto;">
|
||||||
|
<i class="oi oi-plus"></i>
|
||||||
|
</Button>
|
||||||
|
</NewCommandTemplate>
|
||||||
|
<EditCommandTemplate>
|
||||||
|
<Button Size="Size.ExtraSmall" Color="Color.Secondary" Clicked="@context.Clicked" Class="mr-1" Style="min-width: auto;">
|
||||||
|
<i class="oi oi-pencil"></i>
|
||||||
|
</Button>
|
||||||
|
</EditCommandTemplate>
|
||||||
|
<DeleteCommandTemplate>
|
||||||
|
<Button Size="Size.ExtraSmall" Color="Color.Danger" Clicked="@context.Clicked" Class="mr-1" Style="min-width: auto;">
|
||||||
|
<i class="oi oi-trash"></i>
|
||||||
|
</Button>
|
||||||
|
</DeleteCommandTemplate>
|
||||||
|
<ClearFilterCommandTemplate>
|
||||||
|
<Button Size="Size.ExtraSmall" Color="Color.Danger" Clicked="@context.Clicked" Style="min-width: auto;">
|
||||||
|
<i class="o"></i> <i class="fas fa-trash"></i>
|
||||||
|
</Button>
|
||||||
|
</ClearFilterCommandTemplate>
|
||||||
|
</DataGridCommandColumn>
|
||||||
|
<DataGridColumn TItem="User" Field="@nameof(User.Name)" Caption="Name" Editable="true"></DataGridColumn>
|
||||||
|
<DataGridColumn TItem="User" Field="@nameof(User.Mail)" Caption="E-Mail" Editable="true"></DataGridColumn>
|
||||||
|
<DataGridColumn TItem="User" Field="@nameof(User.Type)" Caption="Typ" Editable="true">
|
||||||
|
<EditTemplate>
|
||||||
|
<Select TValue="UserType" @bind-SelectedValue="@context.Item.Type">
|
||||||
|
@foreach (var enumValue in Enum.GetValues<UserType>())
|
||||||
|
{
|
||||||
|
<SelectItem TValue="UserType" Value="enumValue">@enumValue</SelectItem>
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
</EditTemplate>
|
||||||
|
</DataGridColumn>
|
||||||
|
</DataGridColumns>
|
||||||
|
</DataGrid>
|
||||||
56
FoodsharingSiegen.Server/Pages/Users.razor.cs
Normal file
56
FoodsharingSiegen.Server/Pages/Users.razor.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using Blazorise.DataGrid;
|
||||||
|
using FoodsharingSiegen.Contracts.Entity;
|
||||||
|
using FoodsharingSiegen.Server.Data.Service;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace FoodsharingSiegen.Server.Pages
|
||||||
|
{
|
||||||
|
public partial class Users
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// <summary> Gets or sets the user service. </summary>
|
||||||
|
///
|
||||||
|
/// <value> The user service. </value>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
[Inject] public UserService UserService { get; set; } = null!;
|
||||||
|
|
||||||
|
private List<User>? UserList { get; set; }
|
||||||
|
public DataGrid<User> UserDataGrid { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
await LoadUsers();
|
||||||
|
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadUsers()
|
||||||
|
{
|
||||||
|
var usersR = await UserService.GetUsersAsync();
|
||||||
|
if (usersR.Success) UserList = usersR.Data;
|
||||||
|
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RowUpdated(SavedRowItem<User, Dictionary<string, object>> arg)
|
||||||
|
{
|
||||||
|
if (arg.Item?.Id == null || arg.Item.Id.Equals(Guid.Empty) || arg.Values?.Any() != true) return;
|
||||||
|
|
||||||
|
await UserService.Update(arg.Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RowInserted(SavedRowItem<User, Dictionary<string, object>> arg)
|
||||||
|
{
|
||||||
|
var addUserR = await UserService.AddUserAsync(arg.Item);
|
||||||
|
if (!addUserR.Success)
|
||||||
|
{
|
||||||
|
// Error Toast
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await LoadUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Blazorise;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Blazorise.Icons.Material;
|
||||||
|
using Blazorise.Material;
|
||||||
using FoodsharingSiegen.Server.Data;
|
using FoodsharingSiegen.Server.Data;
|
||||||
|
using FoodsharingSiegen.Server.Data.Service;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -8,6 +11,14 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
builder.Services.AddServerSideBlazor();
|
builder.Services.AddServerSideBlazor();
|
||||||
builder.Services.AddSingleton<WeatherForecastService>();
|
builder.Services.AddSingleton<WeatherForecastService>();
|
||||||
|
builder.Services.AddDbContextFactory<FsContext>(opt =>
|
||||||
|
opt.UseSqlite($"Data Source=app.db"));
|
||||||
|
|
||||||
|
// DI
|
||||||
|
builder.Services.AddScoped<FsContext>();
|
||||||
|
builder.Services.AddScoped<UserService>();
|
||||||
|
|
||||||
|
builder.Services.AddBlazorise(options => { options.ChangeTextOnKeyPress = true; }).AddMaterialProviders().AddMaterialIcons();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="top-row ps-3 navbar navbar-dark">
|
<div class="top-row ps-3 navbar navbar-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="">FoodsharingSiegen.Server</a>
|
<a class="navbar-brand" href="">Foodsharing Siegen</a>
|
||||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
@@ -11,17 +11,12 @@
|
|||||||
<nav class="flex-column">
|
<nav class="flex-column">
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
<span class="fas fa-users mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Benutzer
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
<NavLink class="nav-link" href="counter">
|
<NavLink class="nav-link" href="counter">
|
||||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
<span class="fas fa-tasks mr-1" aria-hidden="true" style="font-size: 1.4em;"></span> Verifizierung
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="fetchdata">
|
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -30,7 +25,7 @@
|
|||||||
@code {
|
@code {
|
||||||
private bool collapseNavMenu = true;
|
private bool collapseNavMenu = true;
|
||||||
|
|
||||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
private string? NavMenuCssClass => collapseNavMenu ? "" : null;
|
||||||
|
|
||||||
private void ToggleNavMenu()
|
private void ToggleNavMenu()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-item ::deep a {
|
.nav-item ::deep a {
|
||||||
color: #d7d7d7;
|
color: #533a20;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
|
|
||||||
.nav-item ::deep a.active {
|
.nav-item ::deep a.active {
|
||||||
background-color: rgba(255,255,255,0.25);
|
background-color: rgba(255,255,255,0.25);
|
||||||
color: white;
|
color: #64ae24;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item ::deep a:hover {
|
.nav-item ::deep a:hover {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
color: white;
|
color: #64ae24;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 641px) {
|
@media (min-width: 641px) {
|
||||||
|
|||||||
Reference in New Issue
Block a user