commit 62178f1f321feffeb044db090b5c720859848bef Author: Alexandr Sulimov Date: Sat Apr 29 09:17:17 2023 +0300 Add project files. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e0ab77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,382 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +/MyOffice.SPA/.vscode +/MyOffice.SPA/dist/ +/MyOffice.SPA/src/environments/environment.ts +/MyOffice.SPA/src/environments/environment.prod.ts + +/MyOffice.Web/.config +/MyOffice.Web/appsettings.Production.json +/MyOffice.Web/appsettings.Development.json +/MyOffice.Web/tempkey.jwk +/MyOffice.Web/AppDbContext.Dev.db +/MyOffice.Web/AppDbContext.db +/MyOffice.Web/AppDbContext.Dev.db-shm +/MyOffice.Web/AppDbContext.Dev.db-wal + +/_Published + +package-lock.json +.angular +/.template.config/template.json +/MyOffice.Shared/appsettings.shared.Development.json +/MyOffice.Shared/appsettings.shared.Production.json diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..8aa2645 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/MyOffice.Core/Exec.cs b/MyOffice.Core/Exec.cs new file mode 100644 index 0000000..7f9ba59 --- /dev/null +++ b/MyOffice.Core/Exec.cs @@ -0,0 +1,105 @@ +namespace MyOffice.Core; + +public enum GeneralExecStatus +{ + success, + failure, + not_found +} + +public class Exec : Exec + where TResult : class +{ + public Exec(TResult result, GeneralExecStatus status) : base(result, status) + { + } + + public Exec(GeneralExecStatus status) : base(status) + { + } + + public Exec() : base(GeneralExecStatus.success) + { + } + + public new Exec Set(GeneralExecStatus status) + { + Status = status; + + return this; + } + + public new Exec Set(TResult? result) + { + Result = result; + Status = result == null ? GeneralExecStatus.failure : GeneralExecStatus.success; + + return this; + } +} + +public class Exec + where TResult : class + where TStatus : Enum +{ + public static Exec Start(TResult result, TStatus status) + { + return new Exec(result, status); + } + + public static Exec Start(TStatus status) + { + return new Exec(status); + } + + public static Exec StartSuccess() + { + return new Exec(GeneralExecStatus.success); + } + + public static Exec StartFailure() + { + return new Exec(GeneralExecStatus.failure); + } + + public static Exec StartNotFound() + { + return new Exec(GeneralExecStatus.not_found); + } + + public Exec(TResult result, TStatus status) + { + Result = result; + Status = status; + } + + public Exec(TStatus status) + { + Status = status; + } + + public TResult? Result { get; internal set; } + public TStatus Status { get; internal set; } + + public Exec Set(TResult result, TStatus status) + { + Result = result; + Status = status; + + return this; + } + + public Exec Set(TStatus status) + { + Status = status; + + return this; + } + + public Exec Set(TResult result) + { + Result = result; + + return this; + } +} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/BoolExtensions.cs b/MyOffice.Core/Extensions/BoolExtensions.cs new file mode 100644 index 0000000..8639085 --- /dev/null +++ b/MyOffice.Core/Extensions/BoolExtensions.cs @@ -0,0 +1,14 @@ +namespace MyOffice.Core.Extensions; + +public static class BoolExtensions +{ + public static string ToLowerCase(this bool value) + { + return value.ToString().ToLower(); + } + + public static string? ToLowerCase(this bool? value) + { + return value == null ? null : value.ToString()?.ToLower(); + } +} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/ClaimsExtensions.cs b/MyOffice.Core/Extensions/ClaimsExtensions.cs new file mode 100644 index 0000000..af77327 --- /dev/null +++ b/MyOffice.Core/Extensions/ClaimsExtensions.cs @@ -0,0 +1,31 @@ +namespace MyOffice.Core.Extensions; + +using System.Security.Claims; + +public static class ClaimsExtensions +{ + public static string? GetValue(this IEnumerable claims, string type) + { + return claims.FirstOrDefault(x => x.Type.Equals(type, StringComparison.OrdinalIgnoreCase))?.Value; + } + + public static string? GetValue(this IEnumerable claims, string[] types) + { + return claims.FirstOrDefault(x => types.Any(z => x.Type.Equals(z, StringComparison.OrdinalIgnoreCase)))?.Value; + } + + public static string? GetEmail(this IEnumerable claims) + { + return GetValue(claims, new[] { ClaimTypes.Email, "email" }); + } + + public static string? GetNameIdentifier(this IEnumerable claims) + { + return GetValue(claims, ClaimTypes.NameIdentifier); + } + + public static string? GetSID(this IEnumerable claims) + { + return GetValue(claims, "sid"); + } +} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/GuidExtensions.cs b/MyOffice.Core/Extensions/GuidExtensions.cs new file mode 100644 index 0000000..65234b4 --- /dev/null +++ b/MyOffice.Core/Extensions/GuidExtensions.cs @@ -0,0 +1,9 @@ +namespace MyOffice.Core.Extensions; + +public static class GuidExtensions +{ + public static bool EqualsString(this Guid guid, string str) + { + return guid.ToString().EqualsIgnoreCase(str); + } +} \ No newline at end of file diff --git a/MyOffice.Core/Extensions/StringExtensions.cs b/MyOffice.Core/Extensions/StringExtensions.cs new file mode 100644 index 0000000..ae7e772 --- /dev/null +++ b/MyOffice.Core/Extensions/StringExtensions.cs @@ -0,0 +1,29 @@ +namespace MyOffice.Core.Extensions; + +public static class StringExtensions +{ + public static bool IsMissing(this string? str) + { + return str == null || string.IsNullOrEmpty(str) || string.IsNullOrEmpty(str.Trim()); + } + + public static bool IsPresent(this string? str) + { + return !IsMissing(str); + } + + public static string? NullIfEmpty(this string? str) + { + return IsMissing(str) ? null : str; + } + + public static bool EqualsIgnoreCase(this string? str, string? value) + { + return str != null && str.Equals(value, StringComparison.OrdinalIgnoreCase); + } + + public static bool AsBool(this string? str, bool defaultValue = false) + { + return true.ToString().Equals(str, StringComparison.OrdinalIgnoreCase) || defaultValue; + } +} \ No newline at end of file diff --git a/MyOffice.Core/Identity/IExternalProviderValidator.cs b/MyOffice.Core/Identity/IExternalProviderValidator.cs new file mode 100644 index 0000000..d74d303 --- /dev/null +++ b/MyOffice.Core/Identity/IExternalProviderValidator.cs @@ -0,0 +1,47 @@ +namespace MyOffice.Core.Identity; + +using System; +using System.Diagnostics.Contracts; + +public interface IExternalProviderValidator +{ + string Provider { get; } + public bool IsConfigured { get; } + + Task ValidateAsync(string token); +} + +public class ExternalProviderValidatorResult +{ + public static ExternalProviderValidatorResult Failed() + { + return new ExternalProviderValidatorResult(); + } + + public static ExternalProviderValidatorResult Success(string email, bool emailVerified, string externalId, + string? fullName) + { + return new ExternalProviderValidatorResult(email, emailVerified, externalId, fullName); + } + + public ExternalProviderValidatorResult() + { + IsSuccessed = false; + } + + public ExternalProviderValidatorResult(string email, bool emailVerified, string externalId, string? fullName) : + this() + { + Email = email; + EmailVerified = emailVerified; + IsSuccessed = true; + ExternalId = externalId; + FullName = fullName; + } + + public bool IsSuccessed { get; } + public string? Email { get; } + public bool EmailVerified { get; } + public string? ExternalId { get; } + public string? FullName { get; } +} \ No newline at end of file diff --git a/MyOffice.Core/MyOffice.Core.csproj b/MyOffice.Core/MyOffice.Core.csproj new file mode 100644 index 0000000..7fb9614 --- /dev/null +++ b/MyOffice.Core/MyOffice.Core.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/MyOffice.Data.Models/Accounts/Account.cs b/MyOffice.Data.Models/Accounts/Account.cs new file mode 100644 index 0000000..e1068b4 --- /dev/null +++ b/MyOffice.Data.Models/Accounts/Account.cs @@ -0,0 +1,70 @@ +namespace MyOffice.Data.Models.Account; + +using MyOffice.Data.Models.Users; + +public class CurrencyGlobal +{ + public string Id { get; set; } + public string Name { get; set; } + public string ShortName { get; set; } + public IEnumerable? Currencies { get; set; } + public IEnumerable? Accounts { get; set; } +} + +public class Currency +{ + public Guid Id { get; set; } + public string CurrencyGlobalId { get; set; } + public CurrencyGlobal? CurrencyGlobal { get; set; } + public Guid UserId { get; set; } + public User? User { get; set; } + + public string Name { get; set; } + public string ShortName { get; set; } + public IEnumerable? Rates { get; set; } +} + +public class CurrencyRate +{ + public int Id { get; set; } + public Guid CurrencyId { get; set; } + public Currency? Currency { get; set; } + public DateTime DateTime { get; set; } + public decimal Rate { get; set; } +} + +public class Account +{ + public Guid Id { get; set; } + public string CurrencyGlobalId { get; set; } + public CurrencyGlobal? CurrencyGlobal { get; set; } + public string Name { get; set; } + public IEnumerable AccessRights { get; set; } + public IEnumerable Motions { get; set; } +} + +public class AccountAccess +{ + public int Id { get; set; } + public Guid AccountId { get; set; } + public Account? Account { get; set; } + public Guid UserId { get; set; } + public User? User { get; set; } + + public bool IsAllowRead { get; set; } + public bool IsAllowWrite { get; set; } + public bool IsAllowManage { get; set; } +} + +public class AccountMotion +{ + public long Id { get; set; } + public DateTime CreatedOn { get; set; } + public DateTime DateTime { get; set; } + public Guid AccountId { get; set; } + public Account? Account { get; set; } + public Guid UserId { get; set; } + public User? User { get; set; } + public decimal AmountIn { get; set; } + public decimal AmountOut { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Data.Models/MyOffice.Data.Models.csproj b/MyOffice.Data.Models/MyOffice.Data.Models.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/MyOffice.Data.Models/MyOffice.Data.Models.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/MyOffice.Data.Models/Users/User.cs b/MyOffice.Data.Models/Users/User.cs new file mode 100644 index 0000000..7d72731 --- /dev/null +++ b/MyOffice.Data.Models/Users/User.cs @@ -0,0 +1,19 @@ +namespace MyOffice.Data.Models.Users; + +using Account; + +public class User +{ + public Guid Id { get; set; } + public string UserName { get; set; } = null!; + public string Email { get; set; } = null!; + public string PasswordHash { get; set; } = null!; + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? FullName { get; set; } + public string? Phone { get; set; } + public bool IsEmailConfirmed { get; set; } + public IEnumerable? UserClaims { get; set; } + + public IEnumerable? Currencies { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Data.Models/Users/UserExternal.cs b/MyOffice.Data.Models/Users/UserExternal.cs new file mode 100644 index 0000000..b86f5df --- /dev/null +++ b/MyOffice.Data.Models/Users/UserExternal.cs @@ -0,0 +1,12 @@ +namespace MyOffice.Data.Models.Users; + +public class UserExternal +{ + public int Id { get; set; } + public DateTime CreatedOn { get; set; } + public Guid UserId { get; set; } + public User User { get; set; } = null!; + public string ExternalId { get; set; } = null!; + public string Email { get; set; } = null!; + public string Provider { get; set; } = null!; +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/AppRepository.cs b/MyOffice.Data.Repositories/AppRepository.cs new file mode 100644 index 0000000..8e3bb13 --- /dev/null +++ b/MyOffice.Data.Repositories/AppRepository.cs @@ -0,0 +1,10 @@ +namespace MyOffice.Data.Repositories; + +using DbContext; + +public class AppRepository : RepositoryBase where TEntity : class +{ + public AppRepository() : base(AppDbContextFactory.Instance.CreateDbContext()) + { + } +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj b/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj new file mode 100644 index 0000000..8638a88 --- /dev/null +++ b/MyOffice.Data.Repositories/MyOffice.Data.Repositories.csproj @@ -0,0 +1,33 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + diff --git a/MyOffice.Data.Repositories/RepositoryBase.cs b/MyOffice.Data.Repositories/RepositoryBase.cs new file mode 100644 index 0000000..bcabf2f --- /dev/null +++ b/MyOffice.Data.Repositories/RepositoryBase.cs @@ -0,0 +1,78 @@ +namespace MyOffice.Data.Repositories; + +using Microsoft.EntityFrameworkCore; +using DbContext; + +public class RepositoryBase where TEntity : class +{ + protected readonly AppDbContext _context; + + protected RepositoryBase( + AppDbContext context + ) + { + _context = context; + } + + protected async Task SaveChangesAsync() + { + try + { + return await _context.SaveChangesAsync(); + } + catch (DbUpdateException updateException) + { + throw updateException; + } + } + + protected int SaveChanges() + { + try + { + return _context.SaveChanges(); + } + catch (DbUpdateException updateException) + { + throw updateException; + } + } + + + protected async Task GetAsync(Guid id) + { + return await _context.Set().FindAsync(id); + } + + protected async Task AddAsync(TEntity entity) + { + await _context.Set().AddAsync(entity); + return await SaveChangesAsync(); + } + + protected int Add(TEntity entity) + { + _context.Set().Add(entity); + return SaveChanges(); + } + + protected int Remove(TEntity entity) + { + _context.Set().Remove(entity); + return SaveChanges(); + } + + protected async Task UpdateAsync(TEntity entity) + { + _context.Attach(entity); + _context.Entry(entity).State = EntityState.Modified; + + return await SaveChangesAsync(); + } + + protected int Update(TEntity entity) + { + _context.Attach(entity); + return SaveChanges(); + } +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs b/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs new file mode 100644 index 0000000..0bd2b73 --- /dev/null +++ b/MyOffice.Data.Repositories/Users/IUserExternalRepository.cs @@ -0,0 +1,20 @@ +namespace MyOffice.Data.Repositories.Users; + +using Models.Users; + +public interface IUserExternalRepository +{ + Task AddUserExternalAsync(UserExternal external); + int AddUserExternal(UserExternal external); + Task AddUserExternalsAsync(IEnumerable claims); + + Task> GetUserExternalsByUserIdAsync(Guid userId); + + Task GetByUserIdAsync(Guid userId, string provider); + UserExternal? GetByUserId(Guid userId, string provider); + + UserExternal? GetByExternalId(string externalId, string provider); + Task GetByExternalIdAsync(string externalId, string provider); + + void RemoveUserExternal(UserExternal userExternal); +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/IUserRepository.cs b/MyOffice.Data.Repositories/Users/IUserRepository.cs new file mode 100644 index 0000000..1f8f6f1 --- /dev/null +++ b/MyOffice.Data.Repositories/Users/IUserRepository.cs @@ -0,0 +1,14 @@ +namespace MyOffice.Data.Repositories.Users; + +using MyOffice.Data.Models.Users; + +public interface IUserRepository +{ + Task GetUserAsync(Guid id); + + Task GetByUserUserNameAsync(string userName); + User? GetByUserUserName(string userName); + + Task AddUserAsync(User user); + Task UpdateUserAsync(User user); +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/UserExternalRepository.cs b/MyOffice.Data.Repositories/Users/UserExternalRepository.cs new file mode 100644 index 0000000..6ef84e8 --- /dev/null +++ b/MyOffice.Data.Repositories/Users/UserExternalRepository.cs @@ -0,0 +1,98 @@ +namespace MyOffice.Data.Repositories.Users; + +using MyOffice.Data.Models.Users; +using Repositories; +using Microsoft.EntityFrameworkCore; + +public class UserExternalRepository : AppRepository, IUserExternalRepository +{ + public async Task AddUserExternalAsync(UserExternal userExternal) + { + return await AddAsync(userExternal); + } + + public int AddUserExternal(UserExternal userExternal) + { + return Add(userExternal); + } + + public async Task AddUserExternalsAsync(IEnumerable claims) + { + _context.AddRange(claims); + return await SaveChangesAsync(); + } + + + public async Task> GetUserExternalsByUserNameAsync(string userName) + { + return await _context + .UserClaims + .Where(x => x.User.UserName == userName) + .Include(x => x.User) + .ToListAsync(); + } + + public async Task> GetUserExternalsByUserIdAsync(Guid userId) + { + return await _context + .UserClaims + .Where(x => x.UserId == userId) + .Include(x => x.User) + .ToListAsync(); + } + + public List GetUserExternalsByUser(Guid userId) + { + return _context + .UserClaims + .Where(x => x.UserId == userId) + .Include(x => x.User) + .ToList(); + } + + public List GetUserExternalsByUserName(string userName) + { + return _context + .UserClaims + .Where(x => x.User.UserName == userName) + .Include(x => x.User) + .ToList(); + } + + public async Task GetByUserIdAsync(Guid userId, string provider) + { + return await _context + .UserClaims + .Include(x => x.User) + .FirstOrDefaultAsync(x => x.UserId == userId && x.Provider == provider); + } + + public UserExternal? GetByUserId(Guid userId, string provider) + { + return _context + .UserClaims + .Include(x => x.User) + .FirstOrDefault(x => x.UserId == userId && x.Provider == provider); + } + + public UserExternal? GetByExternalId(string externalId, string provider) + { + return _context + .UserClaims + .Include(x => x.User) + .FirstOrDefault(x => x.ExternalId == externalId && x.Provider == provider); + } + + public Task GetByExternalIdAsync(string externalId, string provider) + { + return _context + .UserClaims + .Include(x => x.User) + .FirstOrDefaultAsync(x => x.ExternalId == externalId && x.Provider == provider); + } + + public void RemoveUserExternal(UserExternal userExternal) + { + Remove(userExternal); + } +} \ No newline at end of file diff --git a/MyOffice.Data.Repositories/Users/UserRepository.cs b/MyOffice.Data.Repositories/Users/UserRepository.cs new file mode 100644 index 0000000..555bfca --- /dev/null +++ b/MyOffice.Data.Repositories/Users/UserRepository.cs @@ -0,0 +1,33 @@ +namespace MyOffice.Data.Repositories.Users; + +using MyOffice.Data.Models.Users; +using Repositories; +using Microsoft.EntityFrameworkCore; + +public class UserRepository : AppRepository, IUserRepository +{ + public async Task GetUserAsync(Guid id) + { + return await GetAsync(id); + } + + public async Task GetByUserUserNameAsync(string userName) + { + return await _context.Users.FirstOrDefaultAsync(x => x.UserName == userName); + } + + public User? GetByUserUserName(string userName) + { + return _context.Users.FirstOrDefault(x => x.UserName == userName); + } + + public async Task AddUserAsync(User user) + { + return await AddAsync(user); + } + + public async Task UpdateUserAsync(User user) + { + return await UpdateAsync(user); + } +} \ No newline at end of file diff --git a/MyOffice.DbContext/AppDbContext.cs b/MyOffice.DbContext/AppDbContext.cs new file mode 100644 index 0000000..8b00dd1 --- /dev/null +++ b/MyOffice.DbContext/AppDbContext.cs @@ -0,0 +1,121 @@ +namespace MyOffice.DbContext; + +using Data.Models.Account; +using Microsoft.EntityFrameworkCore; +using Data.Models.Users; + +public enum AppDbContextProvidersEnum +{ + sqlite, + mssql, + npgsql +} + +public class AppDbContext : DbContext +{ + private readonly AppDbContextProvidersEnum _provider; + + private readonly Dictionary _noCaseCollation = new() + { + { AppDbContextProvidersEnum.sqlite, "NOCASE" }, + { AppDbContextProvidersEnum.npgsql, "my_ci_collation" } + }; + + public AppDbContext(AppDbContextProvidersEnum provider, DbContextOptions options) : base(options) + { + _provider = provider; + } + + public DbSet Users { get; set; } = null!; + public DbSet UserClaims { get; set; } = null!; + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + var noCaseCollation = _noCaseCollation[_provider]; + + if (_provider == AppDbContextProvidersEnum.npgsql) + modelBuilder.HasCollation("my_ci_collation", "en-u-ks-primary", "icu", false); + + /* NOCASE PROPERTIES */ + modelBuilder.Entity() + .Property(x => x.UserName) + .UseCollation(noCaseCollation); + + modelBuilder.Entity() + .Property(x => x.Email) + .UseCollation(noCaseCollation); + + modelBuilder.Entity() + .Property(x => x.Provider) + .UseCollation(noCaseCollation); + + modelBuilder.Entity() + .Property(x => x.Email) + .UseCollation(noCaseCollation); + + + modelBuilder.Entity() + .HasOne(x => x.User) + .WithMany(x => x.UserClaims) + .HasForeignKey(x => x.UserId); + + CurrencyCreating(modelBuilder); + AccountCreating(modelBuilder); + + base.OnModelCreating(modelBuilder); + } + + private void CurrencyCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasOne(x => x.CurrencyGlobal) + .WithMany(x => x.Currencies) + .HasForeignKey(x => x.CurrencyGlobalId); + + modelBuilder.Entity() + .HasOne(x => x.User) + .WithMany(x => x.Currencies) + .HasForeignKey(x => x.UserId); + + modelBuilder.Entity() + .HasOne(x => x.Currency) + .WithMany(x => x.Rates) + .HasForeignKey(x => x.CurrencyId); + } + + private void AccountCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasKey(x => x.Id); + + modelBuilder.Entity() + .HasOne(x => x.CurrencyGlobal) + .WithMany(x => x.Accounts) + .HasForeignKey(x => x.CurrencyGlobalId); + + modelBuilder.Entity() + .HasOne(x => x.Account) + .WithMany(x => x.AccessRights) + .HasForeignKey(x => x.AccountId); + + modelBuilder.Entity() + .HasOne(x => x.User) + .WithMany(x => x.AccessRights) + .HasForeignKey(x => x.AccountId); + } +} \ No newline at end of file diff --git a/MyOffice.DbContext/AppDbContextFactory.cs b/MyOffice.DbContext/AppDbContextFactory.cs new file mode 100644 index 0000000..9edac7c --- /dev/null +++ b/MyOffice.DbContext/AppDbContextFactory.cs @@ -0,0 +1,45 @@ +namespace MyOffice.DbContext; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +public class AppDbContextFactory : IDesignTimeDbContextFactory +{ + public static AppDbContextFactory Instance = new(); + + public AppDbContext CreateDbContext() + { + return CreateDbContext(null); + } + + public AppDbContext CreateDbContext(string[]? args) + { + var connection = RepositoryInitializer.ConnectionString; + + var builder = new DbContextOptionsBuilder(); + + var provider = connection?.Provider ?? args?[0] ?? ""; + var connectionString = connection?.ConnectionString ?? args?[1] ?? ""; + + if (!Enum.TryParse(provider, out var providerEnum)) + throw new InvalidOperationException($"No such provider: [{provider}]"); + + switch (providerEnum) + { + case AppDbContextProvidersEnum.npgsql: + builder.UseNpgsql(connectionString, x => x.MigrationsAssembly("MyOffice.Migrations.Postgres")); + break; + case AppDbContextProvidersEnum.sqlite: + builder.UseSqlite(connectionString, x => x.MigrationsAssembly("MyOffice.Migrations.Sqlite")); + break; + + default: + throw new NotSupportedException($"No such provider: [{provider}]"); + } + + var db = new AppDbContext(providerEnum, builder.Options); + db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + + return db; + } +} \ No newline at end of file diff --git a/MyOffice.DbContext/MyOffice.DbContext.csproj b/MyOffice.DbContext/MyOffice.DbContext.csproj new file mode 100644 index 0000000..1d262e0 --- /dev/null +++ b/MyOffice.DbContext/MyOffice.DbContext.csproj @@ -0,0 +1,24 @@ + + + + net6.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/MyOffice.DbContext/RepositoryInitializer.cs b/MyOffice.DbContext/RepositoryInitializer.cs new file mode 100644 index 0000000..9bfc49b --- /dev/null +++ b/MyOffice.DbContext/RepositoryInitializer.cs @@ -0,0 +1,26 @@ +namespace MyOffice.DbContext; + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +public record ConnectionConfiguration(string Provider, string ConnectionString); + +public class RepositoryInitializer +{ + public static void Initialize( + IServiceCollection services, + ConnectionConfiguration connectionString + ) + { + Services = services!; + ConnectionString = connectionString; + + var db = AppDbContextFactory.Instance.CreateDbContext(); + db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + //db.Database.EnsureCreated(); + db.Database.Migrate(); + } + + public static ConnectionConfiguration ConnectionString { get; internal set; } = null!; + public static IServiceCollection Services { get; internal set; } = null!; +} \ No newline at end of file diff --git a/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs b/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs new file mode 100644 index 0000000..31c175a --- /dev/null +++ b/MyOffice.Migration.Postgres/AppDbContextFactoryPostgres.cs @@ -0,0 +1,27 @@ +namespace MyOffice.Migrations; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using DbContext; +using Shared; + +public class AppDbContextFactoryPostgres : IDesignTimeDbContextFactory +{ + public AppDbContext CreateDbContext(string[]? args) + { + var builder = new DbContextOptionsBuilder(); + + var sharedConfiguration = SharedConfiguration.CreateConfigurationContainer(); + var connectionString = + args?.FirstOrDefault() + ?? sharedConfiguration.GetConnectionString("npgsql"); + + builder.UseNpgsql(connectionString, b => b.MigrationsAssembly("MyOffice.Migrations.Postgres")); + + var db = new AppDbContext(AppDbContextProvidersEnum.npgsql, builder.Options); + db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + + return db; + } +} \ No newline at end of file diff --git a/MyOffice.Migration.Postgres/Migrations/20230408172132_init.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230408172132_init.Designer.cs new file mode 100644 index 0000000..ad20c54 --- /dev/null +++ b/MyOffice.Migration.Postgres/Migrations/20230408172132_init.Designer.cs @@ -0,0 +1,119 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MyOffice.Migrations.Postgres.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20230408172132_init")] + partial class init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("FirstName") + .HasColumnType("text"); + + b.Property("FullName") + .HasColumnType("text"); + + b.Property("IsEmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LastName") + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Postgres/Migrations/20230408172132_init.cs b/MyOffice.Migration.Postgres/Migrations/20230408172132_init.cs new file mode 100644 index 0000000..9df66cc --- /dev/null +++ b/MyOffice.Migration.Postgres/Migrations/20230408172132_init.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MyOffice.Migrations.Postgres.Migrations +{ + /// + public partial class init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False"); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserName = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), + Email = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), + PasswordHash = table.Column(type: "text", nullable: false), + FirstName = table.Column(type: "text", nullable: true), + LastName = table.Column(type: "text", nullable: true), + FullName = table.Column(type: "text", nullable: true), + IsEmailConfirmed = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedOn = table.Column(type: "timestamp with time zone", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + ExternalId = table.Column(type: "text", nullable: false), + Email = table.Column(type: "text", nullable: false, collation: "my_ci_collation"), + Provider = table.Column(type: "text", nullable: false, collation: "my_ci_collation") + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.Designer.cs b/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.Designer.cs new file mode 100644 index 0000000..5f6e6b1 --- /dev/null +++ b/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.Designer.cs @@ -0,0 +1,122 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MyOffice.Migrations.Postgres.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20230408172213_phone")] + partial class phone + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("FirstName") + .HasColumnType("text"); + + b.Property("FullName") + .HasColumnType("text"); + + b.Property("IsEmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LastName") + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("Phone") + .HasColumnType("text"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.cs b/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.cs new file mode 100644 index 0000000..9a735e4 --- /dev/null +++ b/MyOffice.Migration.Postgres/Migrations/20230408172213_phone.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MyOffice.Migrations.Postgres.Migrations +{ + /// + public partial class phone : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Phone", + table: "Users", + type: "text", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Phone", + table: "Users"); + } + } +} diff --git a/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs b/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..0a84170 --- /dev/null +++ b/MyOffice.Migration.Postgres/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,119 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MyOffice.Migrations.Postgres.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("FirstName") + .HasColumnType("text"); + + b.Property("FullName") + .HasColumnType("text"); + + b.Property("IsEmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LastName") + .HasColumnType("text"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("Phone") + .HasColumnType("text"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text") + .UseCollation("my_ci_collation"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj b/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj new file mode 100644 index 0000000..44ff1a0 --- /dev/null +++ b/MyOffice.Migration.Postgres/MyOffice.Migrations.Postgres.csproj @@ -0,0 +1,26 @@ + + + + net6.0 + enable + enable + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + diff --git a/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs b/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs new file mode 100644 index 0000000..7cce6e4 --- /dev/null +++ b/MyOffice.Migration.Sqlite/AppDbContextFactorySqlite.cs @@ -0,0 +1,27 @@ +namespace MyOffice.Migrations; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using DbContext; +using Shared; + +public class AppDbContextFactorySqlite : IDesignTimeDbContextFactory +{ + public AppDbContext CreateDbContext(string[]? args) + { + var builder = new DbContextOptionsBuilder(); + + var sharedConfiguration = SharedConfiguration.CreateConfigurationContainer(); + var connectionString = + args?.FirstOrDefault() + ?? sharedConfiguration.GetConnectionString("sqlite"); + + builder.UseSqlite(connectionString, b => b.MigrationsAssembly("MyOffice.Migrations.Sqlite")); + + var db = new AppDbContext(AppDbContextProvidersEnum.sqlite, builder.Options); + db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + + return db; + } +} \ No newline at end of file diff --git a/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.Designer.cs b/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.Designer.cs new file mode 100644 index 0000000..0c7acc6 --- /dev/null +++ b/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.Designer.cs @@ -0,0 +1,111 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MyOffice.Migrations.Sqlite.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20230408180122_init")] + partial class init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.0"); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("FullName") + .HasColumnType("TEXT"); + + b.Property("IsEmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.cs b/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.cs new file mode 100644 index 0000000..f199468 --- /dev/null +++ b/MyOffice.Migration.Sqlite/Migrations/20230408180122_init.cs @@ -0,0 +1,71 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MyOffice.Migrations.Sqlite.Migrations +{ + /// + public partial class init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + UserName = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), + Email = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), + PasswordHash = table.Column(type: "TEXT", nullable: false), + FirstName = table.Column(type: "TEXT", nullable: true), + LastName = table.Column(type: "TEXT", nullable: true), + FullName = table.Column(type: "TEXT", nullable: true), + IsEmailConfirmed = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedOn = table.Column(type: "TEXT", nullable: false), + UserId = table.Column(type: "TEXT", nullable: false), + ExternalId = table.Column(type: "TEXT", nullable: false), + Email = table.Column(type: "TEXT", nullable: false, collation: "NOCASE"), + Provider = table.Column(type: "TEXT", nullable: false, collation: "NOCASE") + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.Designer.cs b/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.Designer.cs new file mode 100644 index 0000000..9e9b303 --- /dev/null +++ b/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.Designer.cs @@ -0,0 +1,114 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MyOffice.Migrations.Sqlite.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20230408180149_phone")] + partial class phone + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.0"); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("FullName") + .HasColumnType("TEXT"); + + b.Property("IsEmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Phone") + .HasColumnType("TEXT"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.cs b/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.cs new file mode 100644 index 0000000..470ea12 --- /dev/null +++ b/MyOffice.Migration.Sqlite/Migrations/20230408180149_phone.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MyOffice.Migrations.Sqlite.Migrations +{ + /// + public partial class phone : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Phone", + table: "Users", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Phone", + table: "Users"); + } + } +} diff --git a/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs b/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..b788eb0 --- /dev/null +++ b/MyOffice.Migration.Sqlite/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,111 @@ +// +using System; +using MyOffice.DbContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MyOffice.Migrations.Sqlite.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.0"); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("FullName") + .HasColumnType("TEXT"); + + b.Property("IsEmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Phone") + .HasColumnType("TEXT"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("ExternalId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b => + { + b.HasOne("MyOffice.Data.Models.Users.User", "User") + .WithMany("UserClaims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MyOffice.Data.Models.Users.User", b => + { + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj b/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj new file mode 100644 index 0000000..d409654 --- /dev/null +++ b/MyOffice.Migration.Sqlite/MyOffice.Migrations.Sqlite.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/MyOffice.SPA/.editorconfig b/MyOffice.SPA/.editorconfig new file mode 100644 index 0000000..f99379e --- /dev/null +++ b/MyOffice.SPA/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = tabs +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/MyOffice.SPA/.eslintrc.json b/MyOffice.SPA/.eslintrc.json new file mode 100644 index 0000000..99d2907 --- /dev/null +++ b/MyOffice.SPA/.eslintrc.json @@ -0,0 +1,46 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended" + ], + "rules": {} + } + ] +} diff --git a/MyOffice.SPA/.gitignore b/MyOffice.SPA/.gitignore new file mode 100644 index 0000000..0711527 --- /dev/null +++ b/MyOffice.SPA/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/MyOffice.SPA/.npmrc b/MyOffice.SPA/.npmrc new file mode 100644 index 0000000..e9ee3cb --- /dev/null +++ b/MyOffice.SPA/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true \ No newline at end of file diff --git a/MyOffice.SPA/MyOffice.SPA.esproj b/MyOffice.SPA/MyOffice.SPA.esproj new file mode 100644 index 0000000..85eac4d --- /dev/null +++ b/MyOffice.SPA/MyOffice.SPA.esproj @@ -0,0 +1,43 @@ + + + b02d9868-26cb-4e98-95d8-7286bf255f89 + + + npm start + Jasmine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MyOffice.SPA/README.md b/MyOffice.SPA/README.md new file mode 100644 index 0000000..747ce2e --- /dev/null +++ b/MyOffice.SPA/README.md @@ -0,0 +1,27 @@ +# MyOffice + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.6. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/MyOffice.SPA/angular.json b/MyOffice.SPA/angular.json new file mode 100644 index 0000000..6e87b16 --- /dev/null +++ b/MyOffice.SPA/angular.json @@ -0,0 +1,116 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "MyOffice": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/angular-template", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets", + "src/silent-refresh.html" + ], + "styles": [ + "@angular/material/prebuilt-themes/indigo-pink.css", + "./node_modules/bootstrap/dist/css/bootstrap.min.css", + "src/assets/scss/style.scss", + "src/assets/scss/theme/all-themes.scss", + "src/styles.scss" + ], + "stylePreprocessorOptions": { + "includePaths": ["node_modules/"] + }, + "scripts": [ + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "1mb", + "maximumError": "3mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "MyOffice:build:production" + }, + "development": { + "browserTarget": "MyOffice:build:development" + } + }, + "defaultConfiguration": "development", + "options": { + "proxyConfig": "src/proxy.conf.js" + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "MyOffice:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + ], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": false + } +} diff --git a/MyOffice.SPA/aspnetcore-https.js b/MyOffice.SPA/aspnetcore-https.js new file mode 100644 index 0000000..81a924e --- /dev/null +++ b/MyOffice.SPA/aspnetcore-https.js @@ -0,0 +1,36 @@ +// This script sets up HTTPS for the application using the ASP.NET Core HTTPS certificate +const fs = require('fs'); +const spawn = require('child_process').spawn; +const path = require('path'); + +const baseFolder = + process.env.APPDATA !== undefined && process.env.APPDATA !== '' + ? `${process.env.APPDATA}/ASP.NET/https` + : `${process.env.HOME}/.aspnet/https`; + +const certificateArg = process.argv.map(arg => arg.match(/--name=(?.+)/i)).filter(Boolean)[0]; +const certificateName = certificateArg ? certificateArg.groups.value : process.env.npm_package_name; + +if (!certificateName) { + console.error( + 'Invalid certificate name. Run this script in the context of an npm/yarn script or pass --name=<> explicitly.'); + process.exit(-1); +} + +const certFilePath = path.join(baseFolder, `${certificateName}.pem`); +const keyFilePath = path.join(baseFolder, `${certificateName}.key`); + +if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) { + spawn('dotnet', + [ + 'dev-certs', + 'https', + '--export-path', + certFilePath, + '--format', + 'Pem', + '--no-password', + ], + { stdio: 'inherit', }) + .on('exit', (code) => process.exit(code)); +} diff --git a/MyOffice.SPA/karma.conf.js b/MyOffice.SPA/karma.conf.js new file mode 100644 index 0000000..b5ce0eb --- /dev/null +++ b/MyOffice.SPA/karma.conf.js @@ -0,0 +1,45 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function(config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage/angular-template'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/MyOffice.SPA/nuget.config b/MyOffice.SPA/nuget.config new file mode 100644 index 0000000..04437b9 --- /dev/null +++ b/MyOffice.SPA/nuget.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/MyOffice.SPA/package.json b/MyOffice.SPA/package.json new file mode 100644 index 0000000..6d770dd --- /dev/null +++ b/MyOffice.SPA/package.json @@ -0,0 +1,97 @@ +{ + "name": "angular-template", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "start-ssl": + "ng serve --ssl --ssl-cert %APPDATA%\\ASP.NET\\https\\%npm_package_name%.pem --ssl-key %APPDATA%\\ASP.NET\\https\\%npm_package_name%.key", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "prestart": "node aspnetcore-https" + }, + "private": true, + "dependencies": { + "@abacritt/angularx-social-login": "^2.0.0", + "@angular/animations": "^15.2.0", + "@angular/cdk": "^15.2.0", + "@angular/common": "^15.2.0", + "@angular/compiler": "^15.2.0", + "@angular/core": "^15.2.0", + "@angular/forms": "^15.2.0", + "@angular/google-maps": "^15.2.0", + "@angular/localize": "^15.2.0", + "@angular/material": "^15.2.0", + "@angular/platform-browser": "^15.2.0", + "@angular/platform-browser-dynamic": "^15.2.0", + "@angular/router": "^15.2.0", + "@ckeditor/ckeditor5-angular": "^5.1.0", + "@ckeditor/ckeditor5-build-classic": "^36.0.1", + "@danielmoncada/angular-datetime-picker": "^15.0.2", + "@fullcalendar/angular": "^6.1.4", + "@fullcalendar/core": "^6.1.4", + "@fullcalendar/daygrid": "^6.1.4", + "@fullcalendar/interaction": "^6.1.4", + "@fullcalendar/list": "^6.1.4", + "@fullcalendar/timegrid": "^6.1.4", + "@ngx-loading-bar/core": "^6.0.2", + "@ngx-loading-bar/http-client": "^6.0.2", + "@ngx-loading-bar/router": "^6.0.2", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "@popperjs/core": "^2.11.6", + "@swimlane/ngx-charts": "^20.1.2", + "@swimlane/ngx-datatable": "^20.1.0", + "@types/d3-shape": "^3.1.1", + "angular-oauth2-oidc": "^15.0.1", + "angular-auth-oidc-client": "^15.0.3", + "@auth0/auth0-angular": "^2.0.2", + "angular-feather": "^6.5.0", + "angular-gauge": "^4.0.0", + "apexcharts": "^3.37.0", + "bootstrap": "^5.2.3", + "browser-sync": "^2.27.5", + "chart.js": "^4.2.1", + "core-js": "^3.28.0", + "echarts": "^5.4.1", + "moment": "^2.29.4", + "ng-apexcharts": "^1.7.4", + "ng-image-fullscreen-view": "^3.0.3", + "ng2-charts": "^4.1.1", + "ngx-dropzone-wrapper": "^13.0.0", + "ngx-echarts": "^15.0.1", + "ngx-gauge": "^7.0.0", + "ngx-mask": "^14.2.4", + "ngx-scrollbar": "^11.0.0", + "rxjs": "~7.8.0", + "subsink": "^1.0.2", + "sweetalert2": "^11.4.8", + "tslib": "^2.3.0", + "xlsx": "^0.18.5", + "zone.js": "~0.12.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^15.2.0", + "@angular-eslint/builder": "15.2.1", + "@angular-eslint/eslint-plugin": "15.2.1", + "@angular-eslint/eslint-plugin-template": "15.2.1", + "@angular-eslint/schematics": "15.2.1", + "@angular-eslint/template-parser": "15.2.1", + "@angular/cli": "~15.2.0", + "@angular/compiler-cli": "^15.2.0", + "@types/ckeditor__ckeditor5-build-classic": "^29.0.1", + "@types/d3": "^7.4.0", + "@types/jasmine": "~4.3.0", + "@typescript-eslint/eslint-plugin": "5.48.2", + "@typescript-eslint/parser": "5.48.2", + "eslint": "^8.33.0", + "jasmine-core": "~4.5.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.0.0", + "typescript": "~4.9.4" + } +} diff --git a/MyOffice.SPA/src/app/api-routes.ts b/MyOffice.SPA/src/app/api-routes.ts new file mode 100644 index 0000000..de957c2 --- /dev/null +++ b/MyOffice.SPA/src/app/api-routes.ts @@ -0,0 +1,7 @@ +export enum ApiRoutes { + UserRegister = '/api/user/register', + UserLogin = '/api/user/login', + UserProfile = '/api/user/profile', + UserAttach = '/api/user/attach', + UserDeattach = '/api/user/deattach', +} diff --git a/MyOffice.SPA/src/app/app-routing.module.ts b/MyOffice.SPA/src/app/app-routing.module.ts new file mode 100644 index 0000000..0abbfad --- /dev/null +++ b/MyOffice.SPA/src/app/app-routing.module.ts @@ -0,0 +1,61 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { Page404Component } from './authentication/page404/page404.component'; +import { AuthGuard } from './core/guard/auth.guard'; +import { AuthLayoutComponent } from './layout/app-layout/auth-layout/auth-layout.component'; +import { MainLayoutComponent } from './layout/app-layout/main-layout/main-layout.component'; + +const routes: Routes = [ + { + path: '', + component: MainLayoutComponent, + canActivate: [AuthGuard], + children: [ + { path: '', redirectTo: '/authentication/signin', pathMatch: 'full' }, + { + path: 'dashboard', + loadChildren: () => + import('./dashboard/dashboard.module').then((m) => m.DashboardModule), + }, + { + path: 'extra-pages', + loadChildren: () => + import('./extra-pages/extra-pages.module').then( + (m) => m.ExtraPagesModule + ), + }, + { + path: 'multilevel', + loadChildren: () => + import('./multilevel/multilevel.module').then( + (m) => m.MultilevelModule + ), + }, + ], + }, + { + path: 'authentication', + component: AuthLayoutComponent, + loadChildren: () => + import('./authentication/authentication.module').then( + (m) => m.AuthenticationModule + ), + }, + { + path: '', + component: MainLayoutComponent, + canActivate: [AuthGuard], + loadChildren: () => + import('./pages/pages.module').then( + (m) => m.PagesModule + ), + }, + { path: '**', component: Page404Component }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, {})], + exports: [RouterModule], +}) +export class AppRoutingModule { +} diff --git a/MyOffice.SPA/src/app/app.component.html b/MyOffice.SPA/src/app/app.component.html new file mode 100644 index 0000000..7e31ebd --- /dev/null +++ b/MyOffice.SPA/src/app/app.component.html @@ -0,0 +1,2 @@ + + diff --git a/MyOffice.SPA/src/app/app.component.scss b/MyOffice.SPA/src/app/app.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/app.component.spec.ts b/MyOffice.SPA/src/app/app.component.spec.ts new file mode 100644 index 0000000..39d0388 --- /dev/null +++ b/MyOffice.SPA/src/app/app.component.spec.ts @@ -0,0 +1,39 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', + () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + }); + + it('should create the app', + () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'spire'`, + () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('spire'); + }); + + it('should render title', + () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain('spire app is running!'); + }); + }); diff --git a/MyOffice.SPA/src/app/app.component.ts b/MyOffice.SPA/src/app/app.component.ts new file mode 100644 index 0000000..3d9e17f --- /dev/null +++ b/MyOffice.SPA/src/app/app.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { Event, Router, NavigationStart, NavigationEnd } from '@angular/router'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent { + currentUrl!: string; + + constructor(public _router: Router) { + this._router.events.subscribe((routerEvent: Event) => { + if (routerEvent instanceof NavigationStart) { + this.currentUrl = routerEvent.url.substring( + routerEvent.url.lastIndexOf('/') + 1 + ); + } + if (routerEvent instanceof NavigationEnd) { + /* empty */ + } + window.scrollTo(0, 0); + }); + } +} diff --git a/MyOffice.SPA/src/app/app.module.ts b/MyOffice.SPA/src/app/app.module.ts new file mode 100644 index 0000000..9f28e44 --- /dev/null +++ b/MyOffice.SPA/src/app/app.module.ts @@ -0,0 +1,70 @@ +// angular +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { LocationStrategy, HashLocationStrategy } from '@angular/common'; +import { HttpClientModule, HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http'; + +// libs +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { LoadingBarRouterModule } from '@ngx-loading-bar/router'; +import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'; +import { NgScrollbarModule } from 'ngx-scrollbar'; + +// app +import { CoreModule } from './core/core.module'; +import { SharedModule } from './shared/shared.module'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { HeaderComponent } from './layout/header/header.component'; +import { PageLoaderComponent } from './layout/page-loader/page-loader.component'; +import { SidebarComponent } from './layout/sidebar/sidebar.component'; +import { RightSidebarComponent } from './layout/right-sidebar/right-sidebar.component'; +import { AuthLayoutComponent } from './layout/app-layout/auth-layout/auth-layout.component'; +import { MainLayoutComponent } from './layout/app-layout/main-layout/main-layout.component'; +import { ErrorInterceptor } from './core/interceptor/error.interceptor'; +import { JwtInterceptor } from './core/interceptor/jwt.interceptor'; + +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); +} + +@NgModule({ + declarations: [ + AppComponent, + HeaderComponent, + PageLoaderComponent, + SidebarComponent, + RightSidebarComponent, + AuthLayoutComponent, + MainLayoutComponent, + ], + imports: [ + BrowserModule, + BrowserAnimationsModule, + AppRoutingModule, + HttpClientModule, + LoadingBarHttpClientModule, + LoadingBarRouterModule, + NgScrollbarModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: createTranslateLoader, + deps: [HttpClient], + }, + }), + // core & shared + CoreModule, + SharedModule, + ], + providers: [ + { provide: LocationStrategy, useClass: HashLocationStrategy }, + { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, + { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, + ], + bootstrap: [AppComponent], +}) +export class AppModule { +} diff --git a/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts b/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts new file mode 100644 index 0000000..ad46f3d --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/authentication-routing.module.ts @@ -0,0 +1,47 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { SigninComponent } from './signin/signin.component'; +import { SignupComponent } from './signup/signup.component'; +import { ForgotPasswordComponent } from './forgot-password/forgot-password.component'; +import { LockedComponent } from './locked/locked.component'; +import { Page404Component } from './page404/page404.component'; +import { Page500Component } from './page500/page500.component'; + +const routes: Routes = [ + { + path: '', + redirectTo: 'signin', + pathMatch: 'full', + }, + { + path: 'signin', + component: SigninComponent, + }, + { + path: 'signup', + component: SignupComponent, + }, + { + path: 'forgot-password', + component: ForgotPasswordComponent, + }, + { + path: 'locked', + component: LockedComponent, + }, + { + path: 'page404', + component: Page404Component, + }, + { + path: 'page500', + component: Page500Component, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class AuthenticationRoutingModule { +} diff --git a/MyOffice.SPA/src/app/authentication/authentication.module.ts b/MyOffice.SPA/src/app/authentication/authentication.module.ts new file mode 100644 index 0000000..0886973 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/authentication.module.ts @@ -0,0 +1,50 @@ +// angular +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; + +// libs +import { GoogleSigninButtonModule } from '@abacritt/angularx-social-login'; + +// app +import { AuthenticationRoutingModule } from './authentication-routing.module'; +import { Page500Component } from './page500/page500.component'; +import { Page404Component } from './page404/page404.component'; +import { SigninComponent } from './signin/signin.component'; +import { SignupComponent } from './signup/signup.component'; +import { LockedComponent } from './locked/locked.component'; +import { ForgotPasswordComponent } from './forgot-password/forgot-password.component'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + AuthenticationRoutingModule, + MatFormFieldModule, + MatInputModule, + MatIconModule, + MatButtonModule, + GoogleSigninButtonModule, + ], + declarations: [ + Page500Component, + Page404Component, + SigninComponent, + SignupComponent, + LockedComponent, + ForgotPasswordComponent, + ], + providers: [ + ], + schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] +}) +export class AuthenticationModule { +} diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html new file mode 100644 index 0000000..68d6049 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.html @@ -0,0 +1,45 @@ +
+
+
+
+
+
+
+
+
+

Reset Password

+ +
+
+
+ + Enter your registered email address. + + + Email + + mail + + Please enter a valid email address + + +
+
+
+ +
+
+ +
+
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.scss b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts new file mode 100644 index 0000000..cc3bdc0 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ForgotPasswordComponent } from './forgot-password.component'; +describe('ForgotPasswordComponent', + () => { + let component: ForgotPasswordComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ForgotPasswordComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(ForgotPasswordComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts new file mode 100644 index 0000000..a81fdf4 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/forgot-password/forgot-password.component.ts @@ -0,0 +1,50 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { + UntypedFormBuilder, + UntypedFormGroup, + Validators, +} from '@angular/forms'; + +@Component({ + selector: 'app-forgot-password', + templateUrl: './forgot-password.component.html', + styleUrls: ['./forgot-password.component.scss'], +}) +export class ForgotPasswordComponent implements OnInit { + authForm!: UntypedFormGroup; + submitted = false; + returnUrl!: string; + + constructor( + private formBuilder: UntypedFormBuilder, + private route: ActivatedRoute, + private router: Router + ) { + } + + ngOnInit() { + this.authForm = this.formBuilder.group({ + email: [ + '', + [Validators.required, Validators.email, Validators.minLength(5)], + ], + }); + // get return url from route parameters or default to '/' + this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; + } + + get f() { + return this.authForm.controls; + } + + onSubmit() { + this.submitted = true; + // stop here if form is invalid + if (this.authForm.invalid) { + return; + } else { + this.router.navigate(['/dashboard/main']); + } + } +} diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.html b/MyOffice.SPA/src/app/authentication/locked/locked.component.html new file mode 100644 index 0000000..a0db47e --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/locked/locked.component.html @@ -0,0 +1,58 @@ +
+
+
+
+
+
+
+
+
+
+
+
+ User +
+
+ + {{userFullName}} + +
+

+ Locked +

+
+
+
+ + Enter your password here. + + + Password + + + {{hide ? 'visibility_off' : 'visibility'}} + + + Password is required + + +
+
+
+ +
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.scss b/MyOffice.SPA/src/app/authentication/locked/locked.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts b/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts new file mode 100644 index 0000000..88664c6 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/locked/locked.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { LockedComponent } from './locked.component'; +describe('LockedComponent', + () => { + let component: LockedComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [LockedComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(LockedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/locked/locked.component.ts b/MyOffice.SPA/src/app/authentication/locked/locked.component.ts new file mode 100644 index 0000000..7273316 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/locked/locked.component.ts @@ -0,0 +1,51 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { AuthService } from 'src/app/core/service/auth.service'; + +@Component({ + selector: 'app-locked', + templateUrl: './locked.component.html', + styleUrls: ['./locked.component.scss'], +}) +export class LockedComponent implements OnInit { + authForm!: UntypedFormGroup; + submitted = false; + userImg!: string; + userFullName!: string; + hide = true; + + constructor( + private formBuilder: UntypedFormBuilder, + private router: Router, + private authService: AuthService + ) { + } + + ngOnInit() { + this.authForm = this.formBuilder.group({ + password: ['', Validators.required], + }); + + this.userImg = this.authService.currentUserValue.img || 'assets/images/user/admin.jpg'; + + this.userFullName = + this.authService.currentUserValue.firstName + + ' ' + + this.authService.currentUserValue.lastName; + } + + get f() { + return this.authForm.controls; + } + + onSubmit() { + this.submitted = true; + // stop here if form is invalid + if (this.authForm.invalid) { + return; + } else { + this.router.navigate(['/dashboard/dashboard1']); + } + } +} diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.html b/MyOffice.SPA/src/app/authentication/page404/page404.component.html new file mode 100644 index 0000000..29e5aeb --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page404/page404.component.html @@ -0,0 +1,37 @@ +
+
+
+
+
+
+
+
+
+
+ + 404 + + + Looks Like You're Lost + + + The Page You Are Looking For Not Available! + +
+ +
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.scss b/MyOffice.SPA/src/app/authentication/page404/page404.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts b/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts new file mode 100644 index 0000000..f4a6b82 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page404/page404.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Page404Component } from './page404.component'; + +describe('Page404Component', + () => { + let component: Page404Component; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [Page404Component], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(Page404Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/page404/page404.component.ts b/MyOffice.SPA/src/app/authentication/page404/page404.component.ts new file mode 100644 index 0000000..f3ba68c --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page404/page404.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-page404', + templateUrl: './page404.component.html', + styleUrls: ['./page404.component.scss'], +}) +export class Page404Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.html b/MyOffice.SPA/src/app/authentication/page500/page500.component.html new file mode 100644 index 0000000..ce00254 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page500/page500.component.html @@ -0,0 +1,34 @@ +
+
+
+
+
+
+
+
+
+
+ + 500 + + + Oops, Something went wrong. Please try after some times. + +
+ +
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.scss b/MyOffice.SPA/src/app/authentication/page500/page500.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts b/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts new file mode 100644 index 0000000..adaba77 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page500/page500.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Page500Component } from './page500.component'; + +describe('Page500Component', + () => { + let component: Page500Component; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [Page500Component], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(Page500Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/page500/page500.component.ts b/MyOffice.SPA/src/app/authentication/page500/page500.component.ts new file mode 100644 index 0000000..589f767 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/page500/page500.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-page500', + templateUrl: './page500.component.html', + styleUrls: ['./page500.component.scss'], +}) +export class Page500Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.html b/MyOffice.SPA/src/app/authentication/signin/signin.component.html new file mode 100644 index 0000000..3c38680 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signin/signin.component.html @@ -0,0 +1,114 @@ +
+
+
+
+
+
+
+
+
+

+
Welcome to ase.com.ua
+
angular/asp.net core template
+

+ + +
+
+
+ + Username + + face + + Username is required + + +
+
+
+
+ + Password + + + + {{hide ? 'visibility_off' : 'visibility'}} + + + + Password is required + + +
+
+
+
+ +
+ Forgot Password? +
+ +
{{error}}
+ +
+
+ +
+
+
+ + +
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.scss b/MyOffice.SPA/src/app/authentication/signin/signin.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts b/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts new file mode 100644 index 0000000..639f76b --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signin/signin.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SigninComponent } from './signin.component'; + +describe('SigninComponent', + () => { + let component: SigninComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SigninComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(SigninComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/signin/signin.component.ts b/MyOffice.SPA/src/app/authentication/signin/signin.component.ts new file mode 100644 index 0000000..0c9f826 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signin/signin.component.ts @@ -0,0 +1,98 @@ +// angular +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; + +// libs +import { SocialAuthService } from '@abacritt/angularx-social-login'; + +// app +import { AuthService } from 'src/app/core/service/auth.service'; +import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; + +@Component({ + selector: 'app-signin', + templateUrl: './signin.component.html', + styleUrls: ['./signin.component.scss'], +}) +export class SigninComponent extends UnsubscribeOnDestroyAdapter +implements OnInit { + authForm!: UntypedFormGroup; + submitted = false; + loading = false; + error?= ''; + hide = true; + + constructor( + private formBuilder: UntypedFormBuilder, + private router: Router, + private route: ActivatedRoute, + private authService: AuthService, + //private externalAuthService: SocialAuthService, + ) { + super(); + } + + ngOnInit() { + this.authForm = this.formBuilder.group({ + username: ['', Validators.required], + password: ['', Validators.required], + }); + + this.authService.isAuthenticated$.subscribe(isAuthenticated => { + if (isAuthenticated) { + this.router.navigate([this.getRedirect() || '/dashboard/dashboard1']); + } + }); + } + + onSubmit() { + if (this.authForm.invalid) { + this.error = 'Username and Password not valid!'; + return; + } + + this.submitted = true; + this.loading = true; + this.error = ''; + + var user = { + username: this.authForm.controls['username'].value, + password: this.authForm.controls['password'].value + }; + + this.subs.sink = this.authService + .login(user) + .subscribe({ + next: (resp) => { + if (!resp.success) { + this.error = 'Invalid Login'; + if (!resp.success && resp.error?.code === 'invalid_grant') { + this.error = 'Invalid username or password'; + } + this.submitted = false; + this.loading = false; + } + }, + error: (error) => { + this.error = 'Invalid username or password'; + this.submitted = false; + this.loading = false; + }, + }); + } + + loginAuth0() { + this.authService.loginAuth0().subscribe(resp => { + if (!resp.success) { + this.error = 'Invalid login'; + } + }); + } + + private getRedirect(): string | undefined { + var redirectUrl = this.route.snapshot.queryParams['r']; + redirectUrl = redirectUrl ? decodeURIComponent(redirectUrl) : undefined; + return redirectUrl; + } +} diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.html b/MyOffice.SPA/src/app/authentication/signup/signup.component.html new file mode 100644 index 0000000..ec7591d --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signup/signup.component.html @@ -0,0 +1,117 @@ +
+
+
+
+
+
+
+
+
+

Sign Up

+ +
+
+
+ + Email + + mail + + Please enter a valid email address + + +
+
+
+
+ + Password + + + + {{hide ? 'visibility_off' : 'visibility'}} + + + + Password is required + + +
+
+
+
+ + Confirm Password + + + + {{hide ? 'visibility_off' : 'visibility'}} + + + + Confirm Password is required + + +
+
+
+
+ {{error.description}} +
+
+
+
+ + Already Registered? + + Login + + +
+
+
+ +
+
+ + +
+
+
+
+
diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.scss b/MyOffice.SPA/src/app/authentication/signup/signup.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts b/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts new file mode 100644 index 0000000..e43607c --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signup/signup.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SignupComponent } from './signup.component'; + +describe('SignupComponent', + () => { + let component: SignupComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SignupComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(SignupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/authentication/signup/signup.component.ts b/MyOffice.SPA/src/app/authentication/signup/signup.component.ts new file mode 100644 index 0000000..1a1de41 --- /dev/null +++ b/MyOffice.SPA/src/app/authentication/signup/signup.component.ts @@ -0,0 +1,72 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { GeneralErrorModel } from '../../core/models/general-error.model'; +import { AuthService } from '../../core/service/auth.service'; + +@Component({ + selector: 'app-signup', + templateUrl: './signup.component.html', + styleUrls: ['./signup.component.scss'], +}) +export class SignupComponent implements OnInit { + authForm!: UntypedFormGroup; + submitted = false; + returnUrl!: string; + hide = true; + chide = true; + generalError?: GeneralErrorModel; + + constructor( + private formBuilder: UntypedFormBuilder, + private route: ActivatedRoute, + private router: Router, + private authService: AuthService + ) { + + } + + ngOnInit() { + this.authForm = this.formBuilder.group({ + email: ['', [Validators.required, Validators.email, Validators.minLength(5)]], + password: ['', Validators.required], + cpassword: ['', Validators.required], + }); + // get return url from route parameters or default to '/' + this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; + } + + get f() { + return this.authForm.controls; + } + + onSubmit() { + this.submitted = true; + // stop here if form is invalid + if (this.authForm.invalid) { + return; + } + //this.router.navigate(['/admin/dashboard/main']); + this.authService.register({ + username: this.authForm.get('email')!.value!, + password: this.authForm.get('password')!.value!, + confirmPassword: this.authForm.get('cpassword')!.value!, + }).subscribe( + resp => { + if (!resp.succeeded) { + this.generalError = resp as GeneralErrorModel; + } else { + this.router.navigate(['authentication/signin']); + } + }, + err => { + this.generalError = err.error as GeneralErrorModel; + } + ); + } + + loginAuth0() { + this.authService.loginAuth0().subscribe(x => { + }); + } +} diff --git a/MyOffice.SPA/src/app/config.external-login.ts b/MyOffice.SPA/src/app/config.external-login.ts new file mode 100644 index 0000000..e736dd6 --- /dev/null +++ b/MyOffice.SPA/src/app/config.external-login.ts @@ -0,0 +1,67 @@ +import { SocialAuthServiceConfig } from '@abacritt/angularx-social-login'; +import { GoogleLoginProvider } from '@abacritt/angularx-social-login'; +import { FacebookLoginProvider } from '@abacritt/angularx-social-login'; +import { MicrosoftLoginProvider } from '@abacritt/angularx-social-login'; + +import { environment } from '../environments/environment'; + +export class ExternalLoginConfig { + + static readonly GOOGLE = 'google'; + static readonly AUTH0 = 'auth0'; + static readonly FACEBOOK = 'facebook'; + static readonly MICROSOFT = 'microsoft'; + + static getConfiguredProviders() { + return [ + { + provider: ExternalLoginConfig.GOOGLE, + name: 'Google', + }, + { + provider: ExternalLoginConfig.AUTH0, + name: 'Auth0', + }, + /*{ + provider: ExternalLoginConfig.FACEBOOK, + name: "FaceBook", + }, + { + provider: ExternalLoginConfig.MICROSOFT, + name: "Microsoft", + },*/ + ]; + } + + static getSocialConfig(): SocialAuthServiceConfig { + var providers = []; + + if (environment.externalLogins && + environment.externalLogins.google && + environment.externalLogins.google.clientId + ) { + providers.push({ + id: GoogleLoginProvider.PROVIDER_ID, + provider: new GoogleLoginProvider( + environment.externalLogins.google.clientId, + { scopes: 'email', } + ) + }); + } + + return { + autoLogin: false, + providers: providers, + onError: (err) => { + console.error(err); + } + }; + } + + static getAuth0Config() { + return { + clientId: environment.externalLogins.auth0.clientId, + domain: environment.externalLogins.auth0.domain, + }; + } +} diff --git a/MyOffice.SPA/src/app/config.oidc.ts b/MyOffice.SPA/src/app/config.oidc.ts new file mode 100644 index 0000000..eecbe14 --- /dev/null +++ b/MyOffice.SPA/src/app/config.oidc.ts @@ -0,0 +1,46 @@ +import { AuthConfig } from 'angular-oauth2-oidc'; +import { OAuthModuleConfig } from 'angular-oauth2-oidc'; + +import { environment } from '../environments/environment'; + +export const AuthCodeFlowConfig: AuthConfig = { + // Url of the Identity Provider + issuer: environment.identityServer, + requireHttps: false, + strictDiscoveryDocumentValidation: false, + + // URL of the SPA to redirect the user to after login + redirectUri: window.location.origin + '/', + silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html', + useSilentRefresh: true, + silentRefreshTimeout: 5000, // For faster testing + timeoutFactor: 0.25, // For faster testing + sessionChecksEnabled: true, + + // The SPA's id. The SPA is registerd with this id at the auth-server + // clientId: 'server.code', + clientId: 'angulartemplate_spa', + + // Just needed if your auth server demands a secret. In general, this + // is a sign that the auth server is not configured with SPAs in mind + // and it might not enforce further best practices vital for security + // such applications. + // dummyClientSecret: 'secret', + + responseType: 'code', + + // set the scope for the permissions the client should request + // The first four are defined by OIDC. + // Important: Request offline_access to get a refresh token + // The api scope is a usecase specific one + scope: 'openid profile email api', + + showDebugInformation: true, +}; + +export const AuthModuleConfig: OAuthModuleConfig = { + resourceServer: { + allowedUrls: environment.allowedUrls, + sendAccessToken: true, + } +}; diff --git a/MyOffice.SPA/src/app/config/config.service.ts b/MyOffice.SPA/src/app/config/config.service.ts new file mode 100644 index 0000000..01aa1b5 --- /dev/null +++ b/MyOffice.SPA/src/app/config/config.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { InConfiguration } from '../core/models/config.interface'; + +@Injectable({ + providedIn: 'root', +}) +export class ConfigService { + configData!: InConfiguration; + + constructor() { + this.setConfigData(); + } + + setConfigData() { + this.configData = { + layout: { + rtl: false, // options: true & false + variant: 'light', // options: light & dark + theme_color: 'white', // options: white, black, purple, blue, cyan, green, orange + logo_bg_color: 'white', // options: white, black, purple, blue, cyan, green, orange + sidebar: { + collapsed: false, // options: true & false + backgroundColor: 'light', // options: light & dark + }, + }, + }; + } +} diff --git a/MyOffice.SPA/src/app/core/core.module.ts b/MyOffice.SPA/src/app/core/core.module.ts new file mode 100644 index 0000000..42aa9d8 --- /dev/null +++ b/MyOffice.SPA/src/app/core/core.module.ts @@ -0,0 +1,55 @@ +// angular +import { NgModule, Optional, SkipSelf, CUSTOM_ELEMENTS_SCHEMA, APP_INITIALIZER } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +// libs +import { OAuthModule, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc'; +import { AuthConfig } from 'angular-oauth2-oidc'; +import { AuthModule } from '@auth0/auth0-angular'; +import { SocialLoginModule } from '@abacritt/angularx-social-login'; + +// app +import { AuthGuard } from './guard/auth.guard'; +import { RightSidebarService } from './service/rightsidebar.service'; +import { AuthService, authAppInitializerFactory } from './service/auth.service'; +import { DirectionService } from './service/direction.service'; +import { throwIfAlreadyLoaded } from './guard/module-import.guard'; +import { OidcHelperService } from './service/oidc-helper.service'; +import { AuthCodeFlowConfig, AuthModuleConfig } from '../config.oidc'; +import { SubjectExtensions } from './extensions/general.extensions'; +import { ExternalLoginConfig } from '../config.external-login'; + +export function storageFactory(): OAuthStorage { + return localStorage; +} + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + SocialLoginModule, + OAuthModule.forRoot(), + AuthModule.forRoot(ExternalLoginConfig.getAuth0Config()), + ], + providers: [ + { provide: APP_INITIALIZER, useFactory: authAppInitializerFactory, deps: [AuthService], multi: true }, + { provide: AuthConfig, useValue: AuthCodeFlowConfig }, + { provide: OAuthModuleConfig, useValue: AuthModuleConfig }, + { provide: OAuthStorage, useFactory: storageFactory }, + { provide: 'SocialAuthServiceConfig', useValue: ExternalLoginConfig.getSocialConfig() }, + RightSidebarService, + AuthGuard, + AuthService, + DirectionService, + OidcHelperService, + SubjectExtensions, + ], + schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] +}) +export class CoreModule { + constructor(@Optional() @SkipSelf() parentModule: CoreModule) { + throwIfAlreadyLoaded(parentModule, 'CoreModule'); + } +} diff --git a/MyOffice.SPA/src/app/core/extensions/general.extensions.ts b/MyOffice.SPA/src/app/core/extensions/general.extensions.ts new file mode 100644 index 0000000..614a35c --- /dev/null +++ b/MyOffice.SPA/src/app/core/extensions/general.extensions.ts @@ -0,0 +1,41 @@ +// angular +import { ActivatedRoute } from '@angular/router'; + +// libs +import { BehaviorSubject, Observable, Subject, of, throwError, from, combineLatest } from 'rxjs'; + +export { } + +declare global { + interface RouterExtensions { + addDays(days: number): Date; + } + } + +export class ExActivatedRoute extends ActivatedRoute { + + getCurrentRoute(): string { + var redirectUrl = this.snapshot.queryParams['r']; + redirectUrl = redirectUrl ? decodeURIComponent(redirectUrl) : undefined; + return redirectUrl; + } +} + +interface Action { + (item: T): void; +} + +interface Func { + (item: T): TResult; +} + +export class SubjectExtensions { + + static start(start: Action>): Subject { + var result = new Subject(); + + start(result); + + return result; + } +} diff --git a/MyOffice.SPA/src/app/core/extensions/router.extensions.ts b/MyOffice.SPA/src/app/core/extensions/router.extensions.ts new file mode 100644 index 0000000..7d1fa12 --- /dev/null +++ b/MyOffice.SPA/src/app/core/extensions/router.extensions.ts @@ -0,0 +1,18 @@ +import { ActivatedRoute } from '@angular/router'; + +export { } + +declare global { + interface RouterExtensions { + addDays(days: number): Date; + } + } + +export class ExActivatedRoute extends ActivatedRoute { + + getCurrentRoute(): string { + var redirectUrl = this.snapshot.queryParams['r']; + redirectUrl = redirectUrl ? decodeURIComponent(redirectUrl) : undefined; + return redirectUrl; + } +} diff --git a/MyOffice.SPA/src/app/core/guard/auth.guard.ts b/MyOffice.SPA/src/app/core/guard/auth.guard.ts new file mode 100644 index 0000000..6f9f714 --- /dev/null +++ b/MyOffice.SPA/src/app/core/guard/auth.guard.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; + +import { AuthService } from '../service/auth.service'; + +@Injectable({ + providedIn: 'root', +}) +export class AuthGuard implements CanActivate { + constructor( + private authService: AuthService, + private router: Router + ) { + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + if (this.authService.isAuthenticated) { + return true; + } + this.router.navigate(['/authentication/signin'], { queryParams: { r: encodeURIComponent(state.url) } }); + return false; + } +} diff --git a/MyOffice.SPA/src/app/core/guard/module-import.guard.ts b/MyOffice.SPA/src/app/core/guard/module-import.guard.ts new file mode 100644 index 0000000..3526a01 --- /dev/null +++ b/MyOffice.SPA/src/app/core/guard/module-import.guard.ts @@ -0,0 +1,12 @@ +import { CoreModule } from '../core.module'; + +export function throwIfAlreadyLoaded( + parentModule: CoreModule, + moduleName: string +) { + if (parentModule) { + throw new Error( + `${moduleName} has already been loaded. Import ${moduleName} modules in the AppModule only.` + ); + } +} diff --git a/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts b/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts new file mode 100644 index 0000000..af197b7 --- /dev/null +++ b/MyOffice.SPA/src/app/core/interceptor/error.interceptor.ts @@ -0,0 +1,34 @@ +import { AuthService } from '../service/auth.service'; +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor, +} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +@Injectable() +export class ErrorInterceptor implements HttpInterceptor { + constructor(private authenticationService: AuthService) {} + + intercept( + request: HttpRequest, + next: HttpHandler + ): Observable> { + return next.handle(request).pipe( + catchError((err) => { + if (err.status === 401) { + // auto logout if 401 response returned from api + this.authenticationService.logout(); + location.reload(); + } + + const error = err.error.message || err.statusText; + //return throwError(error); + return throwError(err.error || err); + }) + ); + } +} diff --git a/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts b/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts new file mode 100644 index 0000000..9b64489 --- /dev/null +++ b/MyOffice.SPA/src/app/core/interceptor/fake-backend.ts @@ -0,0 +1,101 @@ +/*import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpResponse, + HttpHandler, + HttpEvent, + HttpInterceptor, + HTTP_INTERCEPTORS, +} from '@angular/common/http'; +import { Observable, of, throwError } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; +import { UserModel } from '../models/user.model'; + +const users: UserModel[] = [ + { + id: 'fake-user', + img: 'assets/images/user/admin.jpg', + username: 'admin@software.com', + //password: 'admin@123', + firstName: 'Sarah', + lastName: 'Smith', + token: 'admin-token', + }, +]; + +@Injectable() +export class FakeBackendInterceptor implements HttpInterceptor { + intercept( + request: HttpRequest, + next: HttpHandler + ): Observable> { + const { url, method, headers, body } = request; + // wrap in delayed observable to simulate server api call + return of(null).pipe(mergeMap(handleRoute)); + + function handleRoute() { + switch (true) { + case url.endsWith('/authenticate') && method === 'POST': + return authenticate(); + default: + // pass through any requests not handled above + return next.handle(request); + } + } + + // route functions + + function authenticate() { + const { username, password } = body; + const user = users.find( + (x) => x.username === username && x.password === password + ); + if (!user) { + return error('Username or password is incorrect'); + } + return ok({ + id: user.id, + username: user.username, + img: user.img, + firstName: user.firstName, + lastName: user.lastName, + token: user.token, + }); + } + + // helper functions + + function ok(body?: { + id: string; + username: string; + img?: string; + firstName?: string; + lastName?: string; + token?: string; + }) { + return of(new HttpResponse({ status: 200, body })); + } + + function error(message: string) { + return throwError({ error: { message } }); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function unauthorized() { + return throwError({ status: 401, error: { message: 'Unauthorised' } }); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function isLoggedIn() { + return headers.get('Authorization') === 'Bearer fake-jwt-token'; + } + } +} + +export const fakeBackendProvider = { + // use fake backend in place of Http service for backend-less development + provide: HTTP_INTERCEPTORS, + useClass: FakeBackendInterceptor, + multi: true, +}; +*/ diff --git a/MyOffice.SPA/src/app/core/interceptor/jwt.interceptor.ts b/MyOffice.SPA/src/app/core/interceptor/jwt.interceptor.ts new file mode 100644 index 0000000..590d076 --- /dev/null +++ b/MyOffice.SPA/src/app/core/interceptor/jwt.interceptor.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor, +} from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { AuthService } from '../service/auth.service'; + +@Injectable() +export class JwtInterceptor implements HttpInterceptor { + constructor(private authenticationService: AuthService) {} + + intercept( + request: HttpRequest, + next: HttpHandler + ): Observable> { + if (this.authenticationService.isAuthenticated) { + request = request.clone({ + setHeaders: { + Authorization: `Bearer ${this.authenticationService.getAccessToken()}`, + }, + }); + } + + return next.handle(request); + } +} diff --git a/MyOffice.SPA/src/app/core/models/config.interface.ts b/MyOffice.SPA/src/app/core/models/config.interface.ts new file mode 100644 index 0000000..fea99e3 --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/config.interface.ts @@ -0,0 +1,12 @@ +export interface InConfiguration { + layout: { + rtl: boolean; + variant: string; + theme_color: string; + logo_bg_color: string; + sidebar: { + collapsed: boolean; + backgroundColor: string; + }; + }; +} diff --git a/MyOffice.SPA/src/app/core/models/general-error.model.ts b/MyOffice.SPA/src/app/core/models/general-error.model.ts new file mode 100644 index 0000000..2cbcb47 --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/general-error.model.ts @@ -0,0 +1,6 @@ +export interface GeneralErrorModel { + //succeeded?: boolean; + code?: string; + description?: string; + errors?: GeneralErrorModel[]; +} diff --git a/MyOffice.SPA/src/app/core/models/general-result.model.ts b/MyOffice.SPA/src/app/core/models/general-result.model.ts new file mode 100644 index 0000000..5f3950d --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/general-result.model.ts @@ -0,0 +1,7 @@ +import { GeneralErrorModel } from './general-error.model'; + +export interface GeneralResultModel { + success: boolean; + error?: GeneralErrorModel; + data?: any; +} diff --git a/MyOffice.SPA/src/app/core/models/login.model.ts b/MyOffice.SPA/src/app/core/models/login.model.ts new file mode 100644 index 0000000..2de9c3c --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/login.model.ts @@ -0,0 +1,4 @@ +export interface LoginModel { + username: string; + password: string; +} diff --git a/MyOffice.SPA/src/app/core/models/register.model.ts b/MyOffice.SPA/src/app/core/models/register.model.ts new file mode 100644 index 0000000..ab84657 --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/register.model.ts @@ -0,0 +1,5 @@ +export interface RegisterModel { + username: string; + password: string; + confirmPassword: string; +} diff --git a/MyOffice.SPA/src/app/core/models/user-profile.model.ts b/MyOffice.SPA/src/app/core/models/user-profile.model.ts new file mode 100644 index 0000000..c1f81f1 --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/user-profile.model.ts @@ -0,0 +1,8 @@ +export interface UserProfileModel { + id: string; + email?: string; + phone?: string; + firstName?: string; + lastName?: string; + fullName?: string; +} diff --git a/MyOffice.SPA/src/app/core/models/user.model.ts b/MyOffice.SPA/src/app/core/models/user.model.ts new file mode 100644 index 0000000..ec1372d --- /dev/null +++ b/MyOffice.SPA/src/app/core/models/user.model.ts @@ -0,0 +1,8 @@ +export interface UserModel { + id: string; + username: string; + img?: string; + firstName?: string; + lastName?: string; + //token?: string; +} diff --git a/MyOffice.SPA/src/app/core/service/auth.service.spec.ts b/MyOffice.SPA/src/app/core/service/auth.service.spec.ts new file mode 100644 index 0000000..9b6666e --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthService } from './auth.service'; + +describe('AuthService', + () => { + let service: AuthService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthService); + }); + + it('should be created', + () => { + expect(service).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/core/service/auth.service.ts b/MyOffice.SPA/src/app/core/service/auth.service.ts new file mode 100644 index 0000000..851179b --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/auth.service.ts @@ -0,0 +1,279 @@ +// angular +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { HttpHeaders } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; + +// libs +import { BehaviorSubject } from 'rxjs'; +import { Observable } from 'rxjs'; +import { Subject } from 'rxjs'; +import { of } from 'rxjs'; +import { throwError } from 'rxjs'; +import { from } from 'rxjs'; +import { combineLatest } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { catchError } from 'rxjs/operators'; +import { AuthService as Auth0Service } from '@auth0/auth0-angular'; + +import { SocialAuthService } from '@abacritt/angularx-social-login'; +import { GoogleLoginProvider } from '@abacritt/angularx-social-login'; + +// app +import { OidcHelperService } from './oidc-helper.service'; +import { UserModel } from '../models/user.model'; +import { ApiRoutes } from '../../api-routes'; +import { RegisterModel } from '../models/register.model'; +import { LoginModel } from '../models/login.model'; +import { UserProfileModel } from '../models/user-profile.model'; +import { GeneralResultModel } from '../models/general-result.model'; +import { SubjectExtensions } from '../extensions/general.extensions'; + +export function authAppInitializerFactory(authService: AuthService): () => Promise { + if (window.location.href.indexOf('/silent-refresh.html') !== -1) { + return () => Promise.resolve(); + } + return () => authService.runInitialLoginSequence(); +} + +@Injectable({ + providedIn: 'root', +}) +export class AuthService { + private currentUserSubject: BehaviorSubject; + currentUser$: Observable; + + private isAuthenticatedSubject$ = new BehaviorSubject(false); + isAuthenticated$ = this.isAuthenticatedSubject$.asObservable(); + + constructor( + private http: HttpClient, + private router: Router, + private route: ActivatedRoute, + private oidcHelperService: OidcHelperService, + private auth0Service: Auth0Service, + private externalAuthService: SocialAuthService, + ) { + this.currentUserSubject = new BehaviorSubject({} as UserModel); + this.currentUser$ = this.currentUserSubject.asObservable(); + + // on external social login + this.externalAuthService.authState.subscribe((user) => { + oidcHelperService.loginByExternalLogin('google', user.idToken); + }); + + this.oidcHelperService.isDoneLoading$.subscribe(isDone => { + if (!isDone) { + return; + } + + this.oidcHelperService.isAuthenticated$.subscribe(authState => { + let redirectUrl = this.getRedirect(); + if (authState.isAuthenticated) { + this.oidcHelperService.loadUserProfile().then(e => { + let resp = (e as any).info; + let userProfile = { + id: resp.id, + email: resp.email, + phone: resp.phone, + firstName: resp.firstName, + lastName: resp.lastName, + fullName: resp.fullName, + }; + + this.setCurrentUserValue(userProfile.id, userProfile); + + if (authState.action === AuthenticatedActionEnum.loggedIn) { + this.router.navigate([redirectUrl || '/dashboard/dashboard1']); + } + }); + } + }); + }); + } + + setCurrentUserValue(id: string, profile?: UserProfileModel) { + this.currentUserSubject.next({ + id: id, + img: 'assets/images/user/admin.jpg', + username: profile?.email || '', + firstName: profile?.firstName || '', + lastName: profile?.lastName || '', + }); + } + + get currentUserValue(): UserModel { + return this.currentUserSubject.value; + } + + login(loginModel: LoginModel): Subject { + return SubjectExtensions.start(subject => { + this.oidcHelperService + .login(loginModel.username, loginModel.password) + .subscribe(resp => { + if (resp.access_token) { + this.isAuthenticatedSubject$.next(true); + } + subject.next({ success: !!(resp.access_token) }); + }, + err => { + subject.next({ success: false, error: err.error }); + }); + }); + } + + logout() { + this.currentUserSubject.next({} as UserModel); + this.isAuthenticatedSubject$.next(false); + this.oidcHelperService.logout(); + + return of({ success: false }); + } + + register(registerModel: RegisterModel): Observable { + return this.http + .post(ApiRoutes.UserRegister, registerModel) + .pipe( + map(resp => resp), + catchError(error => { + return throwError(error); + }) + ); + } + + runInitialLoginSequence() { + return this.oidcHelperService.runInitialLoginSequence(); + } + + get isAuthenticated(): boolean { + return this.oidcHelperService.hasValidAccessToken(); + } + + getAccessToken() { + return this.oidcHelperService.getAccessToken(); + } + + loginGoogle(redirectUrl?: string): Observable { + return from(this.externalAuthService.signIn(GoogleLoginProvider.PROVIDER_ID)); + } + + attachGoogle(): Observable { + var result = new Subject(); + + /*this.externalAuthService.signIn(GoogleLoginProvider.PROVIDER_ID).then(function (resp) { + //console.log('attachGoogle', resp); + //return result.next(resp); + //this.attach(idToken.__raw, result); + });*/ + + return result; + } + + loginAuth0(): Observable { + return SubjectExtensions.start((subject) => { + var subs = this.auth0Service.idTokenClaims$.subscribe(token => { + if (token && token?.__raw) { + subs.unsubscribe(); + + this.oidcHelperService.loginByExternalLogin('auth0', token.__raw).subscribe(login => { + if (login.success) { + this.isAuthenticatedSubject$.next(true); + } + subject.next({ success: login.success, error: login.error }); + }); + } else { + //subject.next({ success: false, error: { description: 'Login failed' } }); + } + }); + + this.auth0Service.getAccessTokenWithPopup().subscribe(popupToken => { + if (!popupToken) { + this.auth0Service.getAccessTokenSilently().subscribe(silently => { + }); + } + }); + }); + } + + attachAuth0(): Observable { + return SubjectExtensions.start((subject) => { + var subs = this.auth0Service.idTokenClaims$.subscribe(token => { + if (token && token?.__raw) { + subs.unsubscribe(); + + this.attach(token?.__raw).subscribe( + (resp) => subject.next({ success: true, data: token?.__raw }), + (err) => subject.next({ success: false, data: err }) + ); + } else { + subject.next({ success: false, data: 'Failed' }); + } + }); + + this.auth0Service.getAccessTokenWithPopup().subscribe(popupToken => { + if (!popupToken) { + this.auth0Service.getAccessTokenSilently().subscribe(silently => { + }); + } + }); + }); + } + + deattach(provider: string): Observable { + var result = new Subject(); + + var headers = new HttpHeaders({ + 'Content-Type': 'application/json', + Accept: 'application/json, text/plain, */*', + 'Authorization': 'Bearer ' + this.getAccessToken() + }); + this.http + .post(ApiRoutes.UserDeattach, { provider: provider }, { headers }) + .pipe( + map(resp => resp), + catchError(error => { + return throwError(error); + })) + .subscribe((resp) => result.next(resp)); + + return result; + } + + private attach(token: string): Observable { + var data = { provider: 'auth0', token: token }; + var headers = new HttpHeaders({ + 'Content-Type': 'application/json', + Accept: 'application/json, text/plain, */*', + 'Authorization': 'Bearer ' + this.getAccessToken() + }); + return this.http + .post(ApiRoutes.UserAttach, data, { headers }); + } + + private getRedirect(): string | undefined { + var redirectUrl = this.route.snapshot.queryParams['r']; + redirectUrl = redirectUrl ? decodeURIComponent(redirectUrl) : undefined; + return redirectUrl; + } +} + +export enum AuthenticatedActionEnum { + init, + update, + loggedIn, + loggedOff, +} + +export interface IAuthenticatedState { + isAuthenticated: boolean, + action: AuthenticatedActionEnum, + redirectUrl?: string, +} + +export enum StateEnum { + undefined, + inited, + completed, + failed, +} diff --git a/MyOffice.SPA/src/app/core/service/direction.service.ts b/MyOffice.SPA/src/app/core/service/direction.service.ts new file mode 100644 index 0000000..9acd559 --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/direction.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable() +export class DirectionService { + private data = new BehaviorSubject(''); + currentData = this.data.asObservable(); + + constructor() { + //constructor + } + + updateDirection(item: string) { + this.data.next(item); + } +} diff --git a/MyOffice.SPA/src/app/core/service/language.service.ts b/MyOffice.SPA/src/app/core/service/language.service.ts new file mode 100644 index 0000000..20643b5 --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/language.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; + +@Injectable({ + providedIn: 'root', +}) +export class LanguageService { + languages: string[] = ['en', 'es', 'de']; + + constructor(public translate: TranslateService) { + let browserLang: string; + translate.addLangs(this.languages); + + if (localStorage.getItem('lang')) { + browserLang = localStorage.getItem('lang') as string; + } else { + browserLang = translate.getBrowserLang() as string; + } + translate.use(browserLang.match(/en|es|de/) ? browserLang : 'en'); + } + + setLanguage(lang: string) { + this.translate.use(lang); + localStorage.setItem('lang', lang); + } +} diff --git a/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts b/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts new file mode 100644 index 0000000..1aa7d2d --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/oidc-helper.service.ts @@ -0,0 +1,258 @@ +// angular +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { OAuthErrorEvent } from 'angular-oauth2-oidc'; + +// libs +import { filter, map } from 'rxjs/operators'; +import { Subject, Observable, BehaviorSubject, from } from 'rxjs'; + +// app +import { GeneralResultModel } from '../models/general-result.model'; + +@Injectable() +export class OidcHelperService { + private isAuthenticatedSubject$ = new BehaviorSubject({ + isAuthenticated: false, + action: AuthenticatedActionEnum.init + }); + isAuthenticated$ = this.isAuthenticatedSubject$.asObservable(); + + private isDoneLoadingFailed = false; + private isDoneLoadingSubject$ = new BehaviorSubject(false); + isDoneLoading$ = this.isDoneLoadingSubject$.asObservable(); + + constructor( + private oauthService: OAuthService, + private router: Router, + ) { + this.oauthService.oidc = false; + + // all events handler + this.oauthService.events.subscribe(event => { + if (event instanceof OAuthErrorEvent) { + console.error('OAuthErrorEvent Object:', event); + if (event.type === 'discovery_document_validation_error') { + this.isDoneLoadingFailed = true; + this.setIsAuthenticatedSubject$(false, AuthenticatedActionEnum.update); + } + } else { + var hasValidAccessToken = this.hasValidAccessToken(); + var isAuthenticated = this.isAuthenticatedSubject$.getValue().isAuthenticated; + if (isAuthenticated !== hasValidAccessToken) { + this.setIsAuthenticatedSubject$(hasValidAccessToken, AuthenticatedActionEnum.update); + } + } + }); + + // This is tricky, as it might cause race conditions (where access_token is set in another + // tab before everything is said and done there. + // TODO: Improve this setup. See: https://github.com/jeroenheijmans/sample-angular-oauth2-oidc-with-auth-guards/issues/2 + window.addEventListener('storage', + (event) => { + // The `key` is `null` if the event was caused by `.clear()` + if (event.key !== 'access_token' && event.key !== null) { + return; + } + + console.warn( + 'Noticed changes to access_token (most likely from another tab), updating isAuthenticated'); + this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.update); + + if (!this.hasValidAccessToken()) { + console.log('storage access_token updated !this.hasValidAccessToken()'); + this.logout(); + this.navigateToLoginPage(); + } + }); + + // init login stata + this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.update); + + // TODO: some time receive 'message' with data 'error' == 'session_error'' + /*window.addEventListener('message', e => { + console.log('message', e);; + if (e.origin === 'https://dev-w08xm0pi.us.auth0.com') { + console.log('message stopPropagation');; + e.stopPropagation(); + } + }); + this.oauthService.events.subscribe(x => { + console.log('events', x); + });*/ + this.oauthService.events + .pipe(filter(e => ['session_terminated', 'session_error'].includes(e.type))) + .subscribe(e => { + console.log('events session_terminated', e, this.hasValidAccessToken()); + this.navigateToLoginPage(); + }); + + this.oauthService.setupAutomaticSilentRefresh(); + } + + private setIsAuthenticatedSubject$( + isAuthenticated: boolean, + action: AuthenticatedActionEnum + ) { + var state = this.isAuthenticatedSubject$.getValue(); + if (state.isAuthenticated !== isAuthenticated || state.action !== action + ) { + this.isAuthenticatedSubject$.next({ isAuthenticated, action }); + } + } + + private navigateToLoginPage() { + this.router.navigateByUrl('/authentication/signin'); + } + + logout() { + this.oauthService.logOut(true); + } + + refresh() { + this.oauthService.silentRefresh(); + } + + hasValidAccessToken() { + return this.oauthService.hasValidAccessToken(); + } + + getAccessToken() { + return this.oauthService.getAccessToken(); + } + + login(username: string, password: string) { + //return this.oauthService.fetchTokenUsingPasswordFlow(username, password); + return from(this.oauthService.fetchTokenUsingPasswordFlow(username, password)); + } + + loginByExternalLogin( + provider: string, + token: string, + redirectUrl?: string + ): Observable { + var result = new Subject(); + + let params = { + token: token, + provider: provider, + }; + this.oauthService + .fetchTokenUsingGrant('external', params) + .then(x => { + this.setIsAuthenticatedSubject$(this.hasValidAccessToken(), AuthenticatedActionEnum.loggedIn); + result.next({ success: true }); + }) + .catch(err => { + result.next({ success: false, error: { code: err, description: err } }); + }); + + return result; + } + + loadUserProfile(): Promise { + return this.oauthService.loadUserProfile(); + } + + runInitialLoginSequence(): Promise { + if (location.hash) { + //console.log('Encountered hash fragment, plotting as table...'); + //console.table(location.hash.substr(1).split('&').map(kvp => kvp.split('='))); + } + if (this.isDoneLoadingFailed) { + return new Promise(resolve => setTimeout(() => resolve(), 1500)); + } + // 0. LOAD CONFIG: + // First we have to check to see how the IdServer is + // currently configured: + return this.oauthService.loadDiscoveryDocument() + + // For demo purposes, we pretend the previous call was very slow + .then(() => { + new Promise(resolve => setTimeout(() => resolve(), 1500)); + }) + + // 1. HASH LOGIN: + // Try to log in via hash fragment after redirect back + // from IdServer from initImplicitFlow: + .then(() => { + this.oauthService.tryLogin(); + }) + .then(() => { + if (this.hasValidAccessToken()) { + return Promise.resolve(); + } + + // 2. SILENT LOGIN: + // Try to log in via a refresh because then we can prevent + // needing to redirect the user: + return this.oauthService.silentRefresh() + .then(() => Promise.resolve()) + .catch(result => { + // Subset of situations from https://openid.net/specs/openid-connect-core-1_0.html#AuthError + // Only the ones where it's reasonably sure that sending the + // user to the IdServer will help. + const errorResponsesRequiringUserInteraction = [ + 'interaction_required', + 'login_required', + 'account_selection_required', + 'consent_required', + ]; + + if (result && + result.reason && + errorResponsesRequiringUserInteraction.indexOf(result.reason.error) >= 0) { + + // 3. ASK FOR LOGIN: + // At this point we know for sure that we have to ask the + // user to log in, so we redirect them to the IdServer to + // enter credentials. + // + // Enable this to ALWAYS force a user to login. + // this.login(); + // + // Instead, we'll now do this: + console.warn( + 'User interaction is needed to log in, we will wait for the user to manually log in.'); + return Promise.resolve(); + } + + // We can't handle the truth, just pass on the problem to the + // next handler. + return Promise.reject(result); + }); + }) + .then(() => { + this.isDoneLoadingSubject$.next(true); + + // Check for the strings 'undefined' and 'null' just to be sure. Our current + // login(...) should never have this, but in case someone ever calls + // initImplicitFlow(undefined | null) this could happen. + if (this.oauthService.state && + this.oauthService.state !== 'undefined' && + this.oauthService.state !== 'null') { + let stateUrl = this.oauthService.state; + if (stateUrl.startsWith('/') === false) { + stateUrl = decodeURIComponent(stateUrl); + } + console.log(`There was state of ${this.oauthService.state}, so we are sending you to: ${stateUrl}`); + this.router.navigateByUrl(stateUrl); + } + }) + .catch(() => this.isDoneLoadingSubject$.next(true)); + } +} + +export enum AuthenticatedActionEnum { + init, + update, + loggedIn, + loggedOff, +} + +export interface IAuthenticatedState { + isAuthenticated: boolean, + action: AuthenticatedActionEnum, + redirectUrl?: string, +} diff --git a/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts b/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts new file mode 100644 index 0000000..7b5d47b --- /dev/null +++ b/MyOffice.SPA/src/app/core/service/rightsidebar.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable() +export class RightSidebarService { + private sidebarSubject: BehaviorSubject = new BehaviorSubject(false); + sidebarState = this.sidebarSubject.asObservable(); + + setRightSidebar = (value: boolean) => { + this.sidebarSubject.next(value); + }; + + constructor() { + //constructor + } +} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts b/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts new file mode 100644 index 0000000..a363128 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard-routing.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { Page404Component } from '../authentication/page404/page404.component'; +import { Dashboard1Component } from './dashboard1/dashboard1.component'; +import { Dashboard2Component } from './dashboard2/dashboard2.component'; + +const routes: Routes = [ + { + path: '', + redirectTo: 'dashboard1', + pathMatch: 'full', + }, + { + path: 'dashboard1', + component: Dashboard1Component, + }, + { + path: 'dashboard2', + component: Dashboard2Component, + }, + { path: '**', component: Page404Component }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class DashboardRoutingModule { +} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard.module.ts b/MyOffice.SPA/src/app/dashboard/dashboard.module.ts new file mode 100644 index 0000000..51a6ba8 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard.module.ts @@ -0,0 +1,40 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { DashboardRoutingModule } from './dashboard-routing.module'; +import { Dashboard1Component } from './dashboard1/dashboard1.component'; +import { Dashboard2Component } from './dashboard2/dashboard2.component'; +import { NgScrollbarModule } from 'ngx-scrollbar'; +import { NgChartsModule } from 'ng2-charts'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { NgApexchartsModule } from 'ng-apexcharts'; +import { ComponentsModule } from 'src/app/shared/components/components.module'; +import { SharedModule } from '../shared/shared.module'; + +@NgModule({ + declarations: [Dashboard1Component, Dashboard2Component], + imports: [ + CommonModule, + DashboardRoutingModule, + NgChartsModule, + NgApexchartsModule, + NgScrollbarModule, + MatIconModule, + MatButtonModule, + MatMenuModule, + MatTooltipModule, + MatCheckboxModule, + DragDropModule, + MatProgressBarModule, + ComponentsModule, + SharedModule, + ], +}) +export class DashboardModule { +} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.html b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.html new file mode 100644 index 0000000..2823cab --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.html @@ -0,0 +1,976 @@ +
+
+
+ + +
+
+
+
+
+ shopping_cart +
Total Sales
+

258

+
+ trending_down +

10% Decrease +

+
+
+
+
+
+
+ people +
Customers
+

1,287

+
+ trending_up +

25% Increase +

+
+
+
+
+
+
+ local_activity +
New Tickets
+

128

+
+ trending_down +

12% Decrease +

+
+
+
+
+
+
+ attach_money +
Revenue
+

$48,697

+
+ trending_up +

08% Increase +

+
+
+
+
+
+
+
+
+

Earning Chart

+ + + + + + +
+
+
    +
  • + +
    $675
    +

    Weekly Earnings

    +
  • +
  • + + +
    $1,587
    +

    Monthly Earnings

    +
  • +
  • + +
    $45,965
    +

    Yearly Earnings

    +
  • +
+ + +
+
+
+
+
+
+

Transactions

+
+
+ +
    +
  • +
    + account_balance +
    +
    +
    + Bank Transfer +
    Send money
    +
    +
    +
    100.65
    attach_money +
    +
    +
  • +
  • +
    + account_balance_wallet +
    +
    +
    + Wallet +
    Wallet recharge
    +
    +
    +
    2000
    attach_money +
    +
    +
  • +
  • +
    + credit_card +
    +
    +
    + Credit Card +
    Ordered Food
    +
    +
    +
    25.69
    attach_money +
    +
    +
  • +
  • +
    + attach_money +
    +
    +
    + Cash Payment +
    Sell Stationery
    +
    +
    +
    148.47
    attach_money +
    +
    +
  • +
  • +
    + credit_card +
    +
    +
    + Debit Card +
    ATM Withdraw
    +
    +
    +
    100.65
    attach_money +
    +
    +
  • +
  • +
    + account_balance +
    +
    +
    + Bank Transfer +
    Send money
    +
    +
    +
    100.65
    attach_money +
    +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
Average Daily Bill
+
129 Dollar (Average)
+
+
+ + +
+
+
+
+
+
+
+

Invoices

+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Invoice NoClient NameDue DateStatusTotal
+ #IN7865 + + John Doe + 12/05/2016 +
Paid
+
+ $500 +
+ #IN2301 + + Sarah Smith + 31/03/2016 +
Unpaid
+
+ $372 +
+ #IN7239 + + Airi Satou + 14/04/2017 +
Partially Paid
+
+ $1038 +
+ #IN1482 + + Angelica + Ramos + 11/08/2017 +
Paid
+
+ $872 +
+ #IN8526 + + Ashton Cox + 15/02/2018 +
Unpaid
+
+ $2398 +
+ #IN2473 + + Cara Stevens + 28/01/2017 +
Paid
+
+ $834 +
+ #IN7366 + + Jacob Ryan + 11/03/2017 +
Partially Paid
+
+ $147 +
+
+
+
+
+
+
+
+
+
+

Project Status

+
+
+ +
+
+
+
Angular App
+
+
+
+ + +
+
+
+
+
+
+
+
Java Software
+
+
+
+ + +
+
+
+
+
+
+
+
Html Website
+
+
+
+ + +
+
+
+
+
+
+
+
IOS App
+
+
+
+ + +
+
+
+
+
+
+
+
Python Project
+
+
+
+ + +
+
+
+
+
+
+
+
Reactjs App
+
+
+
+ + +
+
+
+
+
+
+
+
Angular App
+
+
+
+ + +
+
+
+
+
+
+
+
Java Software
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+

Todo List

+
+
+ +
+
+
+
+ drag_indicator +
+
+ + +
+
+ {{task.title}} +
+
+ + arrow_downward + + + arrow_upward + + + remove + + {{task.priority}} +
+
+
+
+
+
+
+
+
+
+

Documents

+
+
+
+ +
    +
  • + + + + +
    +
    Aggrement Doc
    +

    .doc, 4.3 MB

    +
    +
    + + + + +
    +
  • +
  • + + + + +
    +
    Stock Details
    +

    .xls, 2.5 MB

    +
    +
    + + + + +
    +
  • +
  • + + + + +
    +
    Project Requi..
    +

    .pdf, 10.5 MB

    +
    +
    + + + + +
    +
  • +
  • + + + + +
    +
    Sample Code
    +

    .zip, 53.2 MB

    +
    +
    + + + + +
    +
  • +
  • + + + + +
    +
    Privacy Policy
    +

    .doc, 5.3 MB

    +
    +
    + + + + +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+

Client Survay

+ + + + + + +
+
+ + +
+
+
+
+
+
+

Support Tickets Survay

+ + + + + + +
+
+ + +
+
+
+
+
+
+
+
+

Projects Details

+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Project NameEmployees TeamTeam LeaderPriorityOpen TaskCompleted TaskStatusDocumentsActions
Angular App +
    +
  • + user +
  • +
  • + user +
  • +
  • + user +
  • +
  • + +4 +
  • +
+
John Doe +
Medium
+
1910 + + + + + + + +
Java ERP +
    +
  • + user +
  • +
  • + user +
  • +
  • + +3 +
  • +
+
Sarah Smith +
Low
+
2518 + + + + + + + +
Angular App +
    +
  • + user +
  • +
  • + user +
  • +
  • + user +
  • +
  • + +2 +
  • +
+
Airi Satou +
Medium
+
3321 + + + + + + + +
IOS App +
    +
  • + user +
  • +
  • + user +
  • +
  • + user +
  • +
  • + +4 +
  • +
+
Angelica Ramos +
High
+
2615 + + + + + + + +
Wordpress +
    +
  • + user +
  • +
  • + user +
  • +
  • + +3 +
  • +
+
Ashton Cox +
Low
+
1211 + + + + + + + +
Jasper report +
    +
  • + user +
  • +
  • + user +
  • +
  • + user +
  • +
  • + +2 +
  • +
+
Cara Stevens +
High
+
4322 + + + + + + + +
+
+
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.scss b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.spec.ts b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.spec.ts new file mode 100644 index 0000000..17719c5 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Dashboard1Component } from './dashboard1.component'; + +describe('Dashboard1Component', + () => { + let component: Dashboard1Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [Dashboard1Component] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(Dashboard1Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.ts b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.ts new file mode 100644 index 0000000..aafc599 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard1/dashboard1.component.ts @@ -0,0 +1,409 @@ +import { Component, OnInit } from '@angular/core'; +import { + ApexAxisChartSeries, + ApexChart, + ApexXAxis, + ApexDataLabels, + ApexTooltip, + ApexYAxis, + ApexPlotOptions, + ApexStroke, + ApexLegend, + ApexFill, + ApexMarkers, + ApexGrid, + ApexTitleSubtitle, + ApexResponsive, +} from 'ng-apexcharts'; +export type ChartOptions = { + series: ApexAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + yaxis: ApexYAxis; + stroke: ApexStroke; + tooltip: ApexTooltip; + dataLabels: ApexDataLabels; + legend: ApexLegend; + responsive: ApexResponsive[]; + plotOptions: ApexPlotOptions; + fill: ApexFill; + colors: string[]; + labels: string[]; + markers: ApexMarkers; + grid: ApexGrid; + title: ApexTitleSubtitle; +}; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; + +@Component({ + selector: 'app-dashboard1', + templateUrl: './dashboard1.component.html', + styleUrls: ['./dashboard1.component.scss'], +}) +export class Dashboard1Component implements OnInit { + areaChartOptions!: Partial; + barChartOptions!: Partial; + earningOptions!: Partial; + performanceRateChartOptions!: Partial; + + constructor() { + //constructor + } + + ngOnInit() { + this.chart1(); + this.chart3(); + this.chart2(); + this.chart4(); + } + + private chart1() { + this.areaChartOptions = { + series: [ + { + name: 'New Clients', + data: [31, 40, 28, 51, 42, 85, 77], + }, + { + name: 'Old Clients', + data: [11, 32, 45, 32, 34, 52, 41], + }, + ], + chart: { + height: 350, + type: 'area', + toolbar: { + show: false, + }, + foreColor: '#9aa0ac', + }, + colors: ['#4FC3F7', '#7460EE'], + dataLabels: { + enabled: false, + }, + stroke: { + curve: 'smooth', + }, + grid: { + show: true, + borderColor: '#9aa0ac', + strokeDashArray: 1, + }, + xaxis: { + type: 'datetime', + categories: [ + '2018-09-19', + '2018-09-20', + '2018-09-21', + '2018-09-22', + '2018-09-23', + '2018-09-24', + '2018-09-25', + ], + }, + legend: { + show: true, + position: 'top', + horizontalAlign: 'center', + offsetX: 0, + offsetY: 0, + }, + + tooltip: { + theme: 'dark', + marker: { + show: true, + }, + x: { + show: true, + }, + }, + }; + } + + private chart2() { + this.barChartOptions = { + series: [ + { + name: 'New Errors', + data: [44, 55, 41, 67, 22, 43], + }, + { + name: 'Bugs', + data: [13, 23, 20, 8, 13, 27], + }, + { + name: 'Development', + data: [11, 17, 15, 15, 21, 14], + }, + { + name: 'Payment', + data: [21, 7, 25, 13, 22, 8], + }, + ], + chart: { + type: 'bar', + height: 350, + foreColor: '#9aa0ac', + stacked: true, + toolbar: { + show: false, + }, + }, + responsive: [ + { + breakpoint: 480, + options: { + legend: { + position: 'bottom', + offsetX: -10, + offsetY: 0, + }, + }, + }, + ], + plotOptions: { + bar: { + horizontal: false, + columnWidth: '30%', + }, + }, + dataLabels: { + enabled: false, + }, + xaxis: { + type: 'category', + categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + }, + legend: { + show: false, + }, + grid: { + show: true, + borderColor: '#9aa0ac', + strokeDashArray: 1, + }, + fill: { + opacity: 0.8, + colors: ['#E82742', '#2F3149', '#929DB0', '#CED6D3'], + }, + tooltip: { + theme: 'dark', + marker: { + show: true, + }, + x: { + show: true, + }, + }, + }; + } + + private chart3() { + this.earningOptions = { + series: [ + { + name: '2019', + data: [15, 48, 36, 20, 40, 60, 35, 20, 16, 31, 22, 11], + }, + { + name: '2018', + data: [8, 22, 60, 35, 17, 24, 48, 37, 56, 22, 32, 38], + }, + ], + chart: { + height: 240, + type: 'line', + zoom: { + enabled: false, + }, + toolbar: { + show: false, + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + width: 3, + curve: 'smooth', + dashArray: [0, 8], + }, + colors: ['#8793ea', '#4caf50'], + fill: { + opacity: [1, 0.5], + }, + markers: { + size: 0, + hover: { + sizeOffset: 6, + }, + }, + xaxis: { + categories: [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ], + labels: { + style: { + colors: '#8e8da4', + }, + }, + }, + yaxis: { + labels: { + style: { + colors: '#8e8da4', + }, + }, + }, + grid: { + show: true, + borderColor: '#9aa0ac', + strokeDashArray: 1, + }, + tooltip: { + theme: 'dark', + }, + }; + } + + private chart4() { + this.performanceRateChartOptions = { + series: [ + { + name: 'Bill Amount', + data: [113, 120, 130, 120, 125, 119, 126], + }, + ], + chart: { + height: 380, + type: 'line', + dropShadow: { + enabled: true, + color: '#000', + top: 18, + left: 7, + blur: 10, + opacity: 0.2, + }, + foreColor: '#9aa0ac', + toolbar: { + show: false, + }, + }, + colors: ['#6777EF'], + dataLabels: { + enabled: true, + }, + stroke: { + curve: 'smooth', + }, + markers: { + size: 1, + }, + xaxis: { + categories: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + title: { + text: 'Weekday', + }, + }, + yaxis: { + title: { + text: 'Bill Amount($)', + }, + }, + grid: { + show: true, + borderColor: '#9aa0ac', + strokeDashArray: 1, + }, + tooltip: { + theme: 'dark', + marker: { + show: true, + }, + x: { + show: true, + }, + }, + }; + } + + // TODO start + tasks = [ + { + id: '1', + title: 'Submit Science Homework', + done: true, + priority: 'High', + }, + { + id: '2', + title: 'Request for festivle holiday', + done: false, + priority: 'High', + }, + { + id: '3', + title: 'Order new java book', + done: false, + priority: 'Low', + }, + { + id: '4', + title: 'Remind for lunch in hotel', + done: true, + priority: 'Normal', + }, + { + id: '5', + title: 'Pay Hostel Fees', + done: false, + priority: 'High', + }, + { + id: '6', + title: 'Attend Seminar On Sunday', + done: false, + priority: 'Normal', + }, + { + id: '7', + title: 'Renew bus pass', + done: true, + priority: 'High', + }, + { + id: '8', + title: 'Issue book in library', + done: false, + priority: 'High', + }, + { + id: '9', + title: 'Project report submit', + done: false, + priority: 'Low', + }, + ]; + + drop(event: CdkDragDrop) { + moveItemInArray(this.tasks, event.previousIndex, event.currentIndex); + } + + toggle(task: { done: boolean }) { + task.done = !task.done; + } + // TODO end +} diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html new file mode 100644 index 0000000..e4e1783 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.html @@ -0,0 +1,642 @@ +
+
+
+ + +
+
+
+
+
+
+
+
Todays Income
+

Income For Today

+
+

$170

+
+
+
+
+
+
+
+
+

Change

+

75%

+
+
+
+
+
+
+
+
+
+
Total Revenue
+

Total Income

+
+

$120

+
+
+
+
+
+
+
+
+

Change

+

25%

+
+
+
+
+
+
+
+
+
+
New Orders
+

Fresh New Order

+
+

15

+
+
+
+
+
+
+
+
+

Change

+

50%

+
+
+
+
+
+
+
+
+
+
New Users
+

Joined New User

+
+

12

+
+
+
+
+
+
+
+
+

Change

+

25%

+
+
+
+
+
+
+ +
+
+
+

Products Performance

+ + + + + + +
+
+
+ + +
+
+
+
+
+
+
+

Country Wise Clients

+ + + + + + +
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
India23+32%
USA32+12%
Shrilanka12-12%
Australia32+3%
+
+
+
+
+
+
+
+
+
+

Notice Board

+ + + + + + +
+
+ +
+
+
+ ... +
+
+
Airi Satou
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+ 7 hours ago +
+
+
+
+ ... +
+
+
Sarah Smith
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+

1 hour ago

+
+
+
+
+ ... +
+
+
Cara Stevens
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+
Yesterday
+
+
+
+
+ ... +
+
+
Ashton Cox
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+
Yesterday
+
+
+
+
+ ... +
+
+
Mark Hay
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+

1 hour ago

+
+
+
+
+ ... +
+
+
Jay Pandya
+

Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.

+

3 hour ago

+
+
+
+
+
+
+
+
+
+
+

Project Status

+ + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Project NameProgressDuration
Project A + 30% + + + 2 Months
Project B + 55% + + + 3 Months
Project C + 67% + + + 1 Months
Project D + 70% + + + 2 Months
Project E + 24% + + + 3 Months
Project F + 77% + + + 4 Months
Project G + 41% + + + 2 Months
Project H + 41% + + + 2 Months
+
+
+
+
+
+
+
+
+

Earning Source

+ + + + + + +
+
+
+

$90,808

+
+
+
    +
  • +
    + envato.com + 17% +
    +
    +
    +
    +
    +
  • +
  • +
    + google.com + 27% +
    +
    +
    +
    +
    +
  • +
  • +
    + yahoo.com + 25% +
    +
    +
    +
    +
    +
  • +
  • +
    + store + 18% +
    +
    +
    +
    +
    +
  • +
  • +
    + Others + 13% +
    +
    +
    +
    +
    +
  • +
+
+
+
+
+
+
+
+
+
+

Recent Orders

+ + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Order IDCustomer NameItemOrder DateQuantityPaymentStatusInvoiceDetails
ID7865 + Jens + Brincker + iPhone X22/05/20212Credit Card +
Paid
+
+ + + +
ID9357 + Mark Harry + Pixel 212/06/20211COD +
Unpaid
+
+ + + +
ID3987 + Anthony + Davie + OnePlus02/02/20215Debit Card +
Pending
+
+ + + +
ID2483 + David Perry + Moto Z210/01/20212Credit Card +
Paid
+
+ + + +
ID2986 + John Doe + Samsung F6220/05/20213Net Banking +
Unpaid
+
+ + + +
ID1267 + Sarah Smith + iPhone 1210/07/20211COD +
Paid
+
+ + + +
ID3398 + Cara Stevens + Moto Gs511/04/20212UPI Payment +
Pending
+
+ + + +
ID9965 + Ashton Cox + Pixel 214/05/20214Credit Card +
Paid
+
+ + + +
+
+
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.scss b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts new file mode 100644 index 0000000..00dd7f9 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Dashboard2Component } from './dashboard2.component'; + +describe('Dashboard2Component', + () => { + let component: Dashboard2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [Dashboard2Component] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(Dashboard2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts new file mode 100644 index 0000000..0aad829 --- /dev/null +++ b/MyOffice.SPA/src/app/dashboard/dashboard2/dashboard2.component.ts @@ -0,0 +1,154 @@ +import { Component, OnInit } from '@angular/core'; +import { + ApexAxisChartSeries, + ApexChart, + ApexXAxis, + ApexDataLabels, + ApexStroke, + ApexMarkers, + ApexYAxis, + ApexGrid, + ApexTitleSubtitle, + ApexTooltip, + ApexLegend, + ApexFill, + ApexResponsive, + ApexNonAxisChartSeries, +} from 'ng-apexcharts'; + +export type ChartOptions = { + series: ApexAxisChartSeries; + series2: ApexNonAxisChartSeries; + chart: ApexChart; + xaxis: ApexXAxis; + stroke: ApexStroke; + dataLabels: ApexDataLabels; + markers: ApexMarkers; + colors: string[]; + yaxis: ApexYAxis; + grid: ApexGrid; + legend: ApexLegend; + tooltip: ApexTooltip; + fill: ApexFill; + title: ApexTitleSubtitle; + responsive: ApexResponsive[]; + labels: string[]; +}; + +@Component({ + selector: 'app-dashboard2', + templateUrl: './dashboard2.component.html', + styleUrls: ['./dashboard2.component.scss'], +}) +export class Dashboard2Component implements OnInit { + lineChartOptions!: Partial; + pieChartOptions!: Partial; + + // color: ["#3FA7DC", "#F6A025", "#9BC311"], + constructor() { + //constructor + } + + ngOnInit() { + this.chart1(); + this.chart2(); + } + + private chart1() { + this.lineChartOptions = { + series: [ + { + name: 'Product 1', + data: [70, 200, 80, 180, 170, 105, 210], + }, + { + name: 'Product 2', + data: [80, 250, 30, 120, 260, 100, 180], + }, + { + name: 'Product 3', + data: [85, 130, 85, 225, 80, 190, 120], + }, + ], + chart: { + height: 350, + type: 'line', + foreColor: '#9aa0ac', + dropShadow: { + enabled: true, + color: '#000', + top: 18, + left: 7, + blur: 10, + opacity: 0.2, + }, + toolbar: { + show: false, + }, + }, + colors: ['#00E396', '#775DD0', '#FEB019'], + stroke: { + curve: 'smooth', + }, + grid: { + show: true, + borderColor: '#9aa0ac', + strokeDashArray: 1, + }, + markers: { + size: 3, + }, + xaxis: { + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'], + title: { + text: 'Month', + }, + }, + yaxis: { + // opposite: true, + title: { + text: 'Sales', + }, + }, + legend: { + position: 'top', + horizontalAlign: 'right', + floating: true, + offsetY: -25, + offsetX: -5, + }, + tooltip: { + theme: 'dark', + marker: { + show: true, + }, + x: { + show: true, + }, + }, + }; + } + + private chart2() { + this.pieChartOptions = { + series2: [44, 55, 13, 43, 22], + chart: { + type: 'donut', + width: 225, + }, + legend: { + show: false, + }, + dataLabels: { + enabled: false, + }, + labels: ['Science', 'Mathes', 'Economics', 'History', 'Music'], + responsive: [ + { + breakpoint: 480, + options: {}, + }, + ], + }; + } +} diff --git a/MyOffice.SPA/src/app/extra-pages/blank/blank.component.html b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.html new file mode 100644 index 0000000..43e75ad --- /dev/null +++ b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

Blank Page

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/extra-pages/blank/blank.component.scss b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/extra-pages/blank/blank.component.spec.ts b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.spec.ts new file mode 100644 index 0000000..632547e --- /dev/null +++ b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { BlankComponent } from './blank.component'; +describe('BlankComponent', + () => { + let component: BlankComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [BlankComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(BlankComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/extra-pages/blank/blank.component.ts b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.ts new file mode 100644 index 0000000..2d18303 --- /dev/null +++ b/MyOffice.SPA/src/app/extra-pages/blank/blank.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-blank', + templateUrl: './blank.component.html', + styleUrls: ['./blank.component.scss'], +}) +export class BlankComponent { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/extra-pages/extra-pages-routing.module.ts b/MyOffice.SPA/src/app/extra-pages/extra-pages-routing.module.ts new file mode 100644 index 0000000..d8490fb --- /dev/null +++ b/MyOffice.SPA/src/app/extra-pages/extra-pages-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { BlankComponent } from './blank/blank.component'; +const routes: Routes = [ + { + path: 'blank', + component: BlankComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ExtraPagesRoutingModule { +} diff --git a/MyOffice.SPA/src/app/extra-pages/extra-pages.module.ts b/MyOffice.SPA/src/app/extra-pages/extra-pages.module.ts new file mode 100644 index 0000000..17df98a --- /dev/null +++ b/MyOffice.SPA/src/app/extra-pages/extra-pages.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ExtraPagesRoutingModule } from './extra-pages-routing.module'; +import { BlankComponent } from './blank/blank.component'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatTabsModule } from '@angular/material/tabs'; +import { ComponentsModule } from '../shared/components/components.module'; + +@NgModule({ + declarations: [BlankComponent], + imports: [ + CommonModule, + ExtraPagesRoutingModule, + FormsModule, + ReactiveFormsModule, + MatExpansionModule, + MatFormFieldModule, + MatInputModule, + MatIconModule, + MatButtonModule, + MatCheckboxModule, + MatTabsModule, + ComponentsModule, + ], +}) +export class ExtraPagesModule { +} diff --git a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html new file mode 100644 index 0000000..d1c5fa2 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts new file mode 100644 index 0000000..a752639 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/app-layout/auth-layout/auth-layout.component.ts @@ -0,0 +1,59 @@ +import { Direction } from '@angular/cdk/bidi'; +import { Component, Inject, Renderer2 } from '@angular/core'; +import { InConfiguration } from 'src/app/core/models/config.interface'; +import { DirectionService } from 'src/app/core/service/direction.service'; +import { ConfigService } from 'src/app/config/config.service'; +import { DOCUMENT } from '@angular/common'; + +@Component({ + selector: 'app-auth-layout', + templateUrl: './auth-layout.component.html', + styleUrls: [], +}) +export class AuthLayoutComponent { + direction!: Direction; + config!: InConfiguration; + + constructor( + @Inject(DOCUMENT) private document: Document, + private directoryService: DirectionService, + private configService: ConfigService, + private renderer: Renderer2 + ) { + this.config = this.configService.configData; + this.directoryService.currentData.subscribe((currentData) => { + if (currentData) { + this.direction = currentData === 'ltr' ? 'ltr' : 'rtl'; + } else { + if (localStorage.getItem('isRtl')) { + if (localStorage.getItem('isRtl') === 'true') { + this.direction = 'rtl'; + } else if (localStorage.getItem('isRtl') === 'false') { + this.direction = 'ltr'; + } + } else { + if (this.config) { + if (this.config.layout.rtl === true) { + this.direction = 'rtl'; + localStorage.setItem('isRtl', 'true'); + } else { + this.direction = 'ltr'; + localStorage.setItem('isRtl', 'false'); + } + } + } + } + }); + + // set theme on startup + if (localStorage.getItem('theme')) { + this.renderer.removeClass(this.document.body, this.config.layout.variant); + this.renderer.addClass( + this.document.body, + localStorage.getItem('theme') as string + ); + } else { + this.renderer.addClass(this.document.body, this.config.layout.variant); + } + } +} diff --git a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html new file mode 100644 index 0000000..74b91bd --- /dev/null +++ b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.html @@ -0,0 +1,6 @@ + + + +
+ +
diff --git a/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts new file mode 100644 index 0000000..de47929 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/app-layout/main-layout/main-layout.component.ts @@ -0,0 +1,45 @@ +import { Direction } from '@angular/cdk/bidi'; +import { Component } from '@angular/core'; +import { InConfiguration } from 'src/app/core/models/config.interface'; +import { DirectionService } from 'src/app/core/service/direction.service'; +import { ConfigService } from 'src/app/config/config.service'; + +@Component({ + selector: 'app-main-layout', + templateUrl: './main-layout.component.html', + styleUrls: [], +}) +export class MainLayoutComponent { + direction!: Direction; + config!: InConfiguration; + + constructor( + private directoryService: DirectionService, + private configService: ConfigService + ) { + this.config = this.configService.configData; + this.directoryService.currentData.subscribe((currentData) => { + if (currentData) { + this.direction = currentData === 'ltr' ? 'ltr' : 'rtl'; + } else { + if (localStorage.getItem('isRtl')) { + if (localStorage.getItem('isRtl') === 'true') { + this.direction = 'rtl'; + } else if (localStorage.getItem('isRtl') === 'false') { + this.direction = 'ltr'; + } + } else { + if (this.config) { + if (this.config.layout.rtl === true) { + this.direction = 'rtl'; + localStorage.setItem('isRtl', 'true'); + } else { + this.direction = 'ltr'; + localStorage.setItem('isRtl', 'false'); + } + } + } + } + }); + } +} diff --git a/MyOffice.SPA/src/app/layout/header/header.component.html b/MyOffice.SPA/src/app/layout/header/header.component.html new file mode 100644 index 0000000..d381862 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/header/header.component.html @@ -0,0 +1,179 @@ + diff --git a/MyOffice.SPA/src/app/layout/header/header.component.scss b/MyOffice.SPA/src/app/layout/header/header.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/header/header.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/layout/header/header.component.spec.ts b/MyOffice.SPA/src/app/layout/header/header.component.spec.ts new file mode 100644 index 0000000..4cff7eb --- /dev/null +++ b/MyOffice.SPA/src/app/layout/header/header.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { HeaderComponent } from './header.component'; +describe('HeaderComponent', + () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HeaderComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/layout/header/header.component.ts b/MyOffice.SPA/src/app/layout/header/header.component.ts new file mode 100644 index 0000000..9afdea3 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/header/header.component.ts @@ -0,0 +1,259 @@ +// angular +import { DOCUMENT } from '@angular/common'; +import { Component } from '@angular/core'; +import { Inject } from '@angular/core'; +import { ElementRef } from '@angular/core'; +import { OnInit } from '@angular/core'; +import { Renderer2 } from '@angular/core'; +import { AfterViewInit } from '@angular/core'; +import { Router } from '@angular/router'; + +// libs + +// app +import { ConfigService } from 'src/app/config/config.service'; +import { InConfiguration } from 'src/app/core/models/config.interface'; +import { AuthService } from 'src/app/core/service/auth.service'; +import { LanguageService } from 'src/app/core/service/language.service'; +import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; + +interface Notifications { + message: string; + time: string; + icon: string; + color: string; + status: string; +} + +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.scss'], +}) +export class HeaderComponent extends UnsubscribeOnDestroyAdapter implements OnInit, AfterViewInit { + + config!: InConfiguration; + + userImg?: string; + userName?: string; + + homePage?: string; + isNavbarCollapsed = true; + flagvalue: string | string[] | undefined; + countryName: string | string[] = []; + langStoreValue?: string; + defaultFlag?: string; + isOpenSidebar?: boolean; + docElement: HTMLElement | undefined; + isFullScreen = false; + + constructor( + @Inject(DOCUMENT) private document: Document, + private renderer: Renderer2, + public elementRef: ElementRef, + private configService: ConfigService, + private authService: AuthService, + private router: Router, + public languageService: LanguageService + ) { + super(); + + this.authService.currentUser$.subscribe(user => { + this.setUser(); + }); + } + + listLang = [ + { text: 'English', flag: 'assets/images/flags/us.jpg', lang: 'en' }, + { text: 'Spanish', flag: 'assets/images/flags/spain.jpg', lang: 'es' }, + { text: 'German', flag: 'assets/images/flags/germany.jpg', lang: 'de' }, + ]; + notifications: Notifications[] = [ + { + message: 'Please check your mail', + time: '14 mins ago', + icon: 'mail', + color: 'nfc-green', + status: 'msg-unread', + }, + { + message: 'New Employee Added..', + time: '22 mins ago', + icon: 'person_add', + color: 'nfc-blue', + status: 'msg-read', + }, + { + message: 'Your leave is approved!! ', + time: '3 hours ago', + icon: 'event_available', + color: 'nfc-orange', + status: 'msg-read', + }, + { + message: 'Lets break for lunch...', + time: '5 hours ago', + icon: 'lunch_dining', + color: 'nfc-blue', + status: 'msg-read', + }, + { + message: 'Employee report generated', + time: '14 mins ago', + icon: 'description', + color: 'nfc-green', + status: 'msg-read', + }, + { + message: 'Please check your mail', + time: '22 mins ago', + icon: 'mail', + color: 'nfc-red', + status: 'msg-read', + }, + { + message: 'Salary credited...', + time: '3 hours ago', + icon: 'paid', + color: 'nfc-purple', + status: 'msg-read', + }, + ]; + + ngOnInit() { + this.config = this.configService.configData; + + this.setUser(); + + this.homePage = 'dashboard/dashboard1'; + + this.langStoreValue = localStorage.getItem('lang') as string; + const val = this.listLang.filter((x) => x.lang === this.langStoreValue); + this.countryName = val.map((element) => element.text); + if (val.length === 0) { + if (this.flagvalue === undefined) { + this.defaultFlag = 'assets/images/flags/us.jpg'; + } + } else { + this.flagvalue = val.map((element) => element.flag); + } + } + + ngAfterViewInit() { + // set theme on startup + if (localStorage.getItem('theme')) { + this.renderer.removeClass(this.document.body, this.config.layout.variant); + this.renderer.addClass( + this.document.body, + localStorage.getItem('theme') as string + ); + } else { + this.renderer.addClass(this.document.body, this.config.layout.variant); + } + + if (localStorage.getItem('menuOption')) { + this.renderer.addClass( + this.document.body, + localStorage.getItem('menuOption') as string + ); + } else { + this.renderer.addClass( + this.document.body, + 'menu_' + this.config.layout.sidebar.backgroundColor + ); + } + + if (localStorage.getItem('choose_logoheader')) { + this.renderer.addClass( + this.document.body, + localStorage.getItem('choose_logoheader') as string + ); + } else { + this.renderer.addClass( + this.document.body, + 'logo-' + this.config.layout.logo_bg_color + ); + } + + if (localStorage.getItem('sidebar_status')) { + if (localStorage.getItem('sidebar_status') === 'close') { + this.renderer.addClass(this.document.body, 'side-closed'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + } else { + this.renderer.removeClass(this.document.body, 'side-closed'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + } + } else { + if (this.config.layout.sidebar.collapsed === true) { + this.renderer.addClass(this.document.body, 'side-closed'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + } + } + } + + callFullscreen() { + if (!this.isFullScreen) { + this.docElement?.requestFullscreen(); + } else { + document.exitFullscreen(); + } + this.isFullScreen = !this.isFullScreen; + } + + setLanguage(text: string, lang: string, flag: string) { + this.countryName = text; + this.flagvalue = flag; + this.langStoreValue = lang; + this.languageService.setLanguage(lang); + } + + mobileMenuSidebarOpen(event: Event, className: string) { + const hasClass = (event.target as HTMLInputElement).classList.contains( + className + ); + if (hasClass) { + this.renderer.removeClass(this.document.body, className); + } else { + this.renderer.addClass(this.document.body, className); + } + + const hasClass2 = this.document.body.classList.contains('side-closed'); + if (hasClass2) { + // this.renderer.removeClass(this.document.body, "side-closed"); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + } else { + // this.renderer.addClass(this.document.body, "side-closed"); + this.renderer.addClass(this.document.body, 'submenu-closed'); + } + } + + callSidemenuCollapse() { + const hasClass = this.document.body.classList.contains('side-closed'); + if (hasClass) { + this.renderer.removeClass(this.document.body, 'side-closed'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + } else { + this.renderer.addClass(this.document.body, 'side-closed'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + } + } + + logout() { + this.subs.sink = this.authService.logout().subscribe((res) => { + if (!res.success) { + this.router.navigate(['/authentication/signin']); + } + }); + } + + private setUser() { + this.userImg = this.authService.currentUserValue.img; + + this.userName = [ + this.authService.currentUserValue.firstName, + this.authService.currentUserValue.lastName + ].join(' ').trim(); + + this.userName = this.userName || this.authService.currentUserValue.username; + } +} diff --git a/MyOffice.SPA/src/app/layout/layout.module.ts b/MyOffice.SPA/src/app/layout/layout.module.ts new file mode 100644 index 0000000..50cf3f0 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/layout.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatButtonModule } from '@angular/material/button'; +import { MatInputModule } from '@angular/material/input'; +import { MatBadgeModule } from '@angular/material/badge'; + +@NgModule({ + imports: [ + CommonModule, + MatTabsModule, + MatMenuModule, + MatIconModule, + MatButtonModule, + MatInputModule, + MatBadgeModule, + ], + declarations: [], +}) +export class LayoutModule { +} diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html new file mode 100644 index 0000000..c0c959c --- /dev/null +++ b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.html @@ -0,0 +1,2 @@ + + diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts new file mode 100644 index 0000000..d2479a5 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { PageLoaderComponent } from './page-loader.component'; +describe('PageLoaderComponent', + () => { + let component: PageLoaderComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PageLoaderComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(PageLoaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts new file mode 100644 index 0000000..4fe3be4 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/page-loader/page-loader.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-page-loader', + templateUrl: './page-loader.component.html', + styleUrls: ['./page-loader.component.scss'], +}) +export class PageLoaderComponent { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html new file mode 100644 index 0000000..572cf75 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.html @@ -0,0 +1,76 @@ +
+ + + + +
+
+
+ Setting Panel +
+
+
Select Layout
+
+
+ +
Light
+
+
+ +
Dark
+
+
+
+
+
Sidebar Menu Color
+ + Light + Dark + +
+
+
Color Theme
+
+
    +
  • +
    +
  • +
  • +
    +
  • +
  • +
    +
  • +
  • +
    +
  • +
  • +
    +
  • +
  • +
    +
  • +
  • +
    +
  • +
+
+
+
+
RTL Layout
+ +
+
+
+
+
diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts new file mode 100644 index 0000000..2528b67 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { RightSidebarComponent } from './right-sidebar.component'; +describe('RightSidebarComponent', + () => { + let component: RightSidebarComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [RightSidebarComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(RightSidebarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts new file mode 100644 index 0000000..ea0f354 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/right-sidebar/right-sidebar.component.ts @@ -0,0 +1,269 @@ +import { DOCUMENT } from '@angular/common'; +import { + Component, + Inject, + ElementRef, + OnInit, + AfterViewInit, + Renderer2, + ChangeDetectionStrategy, +} from '@angular/core'; +import { ConfigService } from 'src/app/config/config.service'; +import { RightSidebarService } from 'src/app/core/service/rightsidebar.service'; +import { MatSlideToggleChange } from '@angular/material/slide-toggle'; +import { UnsubscribeOnDestroyAdapter } from 'src/app/shared/UnsubscribeOnDestroyAdapter'; +import { DirectionService } from 'src/app/core/service/direction.service'; +import { InConfiguration } from 'src/app/core/models/config.interface'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'app-right-sidebar', + templateUrl: './right-sidebar.component.html', + styleUrls: ['./right-sidebar.component.scss'], +}) +export class RightSidebarComponent +extends UnsubscribeOnDestroyAdapter +implements OnInit, AfterViewInit { + selectedBgColor = 'white'; + maxHeight!: string; + maxWidth!: string; + showpanel = false; + isOpenSidebar!: boolean; + isDarkSidebar = false; + isDarTheme = false; + innerHeight?: number; + headerHeight = 60; + isRtl = false; + config!: InConfiguration; + + constructor( + @Inject(DOCUMENT) private document: Document, + private renderer: Renderer2, + public elementRef: ElementRef, + private rightSidebarService: RightSidebarService, + private configService: ConfigService, + private directionService: DirectionService + ) { + super(); + } + + ngOnInit() { + this.config = this.configService.configData; + this.subs.sink = this.rightSidebarService.sidebarState.subscribe( + (isRunning) => { + this.isOpenSidebar = isRunning; + } + ); + this.setRightSidebarWindowHeight(); + } + + ngAfterViewInit() { + // set header color on startup + if (localStorage.getItem('choose_skin')) { + this.renderer.addClass( + this.document.body, + localStorage.getItem('choose_skin') as string + ); + this.selectedBgColor = localStorage.getItem( + 'choose_skin_active' + ) as string; + } else { + this.renderer.addClass( + this.document.body, + 'theme-' + this.config.layout.theme_color + ); + this.selectedBgColor = this.config.layout.theme_color; + } + + if (localStorage.getItem('menuOption')) { + if (localStorage.getItem('menuOption') === 'menu_dark') { + this.isDarkSidebar = true; + } else if (localStorage.getItem('menuOption') === 'menu_light') { + this.isDarkSidebar = false; + } else { + this.isDarkSidebar = + this.config.layout.sidebar.backgroundColor === 'dark' ? true : false; + } + } else { + this.isDarkSidebar = + this.config.layout.sidebar.backgroundColor === 'dark' ? true : false; + } + + if (localStorage.getItem('theme')) { + if (localStorage.getItem('theme') === 'dark') { + this.isDarTheme = true; + } else if (localStorage.getItem('theme') === 'light') { + this.isDarTheme = false; + } else { + this.isDarTheme = this.config.layout.variant === 'dark' ? true : false; + } + } else { + this.isDarTheme = this.config.layout.variant === 'dark' ? true : false; + } + + if (localStorage.getItem('isRtl')) { + if (localStorage.getItem('isRtl') === 'true') { + this.setRTLSettings(); + } else if (localStorage.getItem('isRtl') === 'false') { + this.setLTRSettings(); + } + } else { + if (this.config.layout.rtl == true) { + this.setRTLSettings(); + } else { + this.setLTRSettings(); + } + } + } + + selectTheme(e: string) { + this.selectedBgColor = e; + const prevTheme = this.elementRef.nativeElement + .querySelector('.settingSidebar .choose-theme li.active') + .getAttribute('data-theme'); + this.renderer.removeClass(this.document.body, 'theme-' + prevTheme); + this.renderer.addClass(this.document.body, 'theme-' + this.selectedBgColor); + localStorage.setItem('choose_skin', 'theme-' + this.selectedBgColor); + localStorage.setItem('choose_skin_active', this.selectedBgColor); + } + + lightSidebarBtnClick() { + this.renderer.removeClass(this.document.body, 'menu_dark'); + this.renderer.removeClass(this.document.body, 'logo-black'); + this.renderer.addClass(this.document.body, 'menu_light'); + this.renderer.addClass(this.document.body, 'logo-white'); + const menuOption = 'menu_light'; + localStorage.setItem('choose_logoheader', 'logo-white'); + localStorage.setItem('menuOption', menuOption); + } + + darkSidebarBtnClick() { + this.renderer.removeClass(this.document.body, 'menu_light'); + this.renderer.removeClass(this.document.body, 'logo-white'); + this.renderer.addClass(this.document.body, 'menu_dark'); + this.renderer.addClass(this.document.body, 'logo-black'); + const menuOption = 'menu_dark'; + localStorage.setItem('choose_logoheader', 'logo-black'); + localStorage.setItem('menuOption', menuOption); + } + + lightThemeBtnClick() { + this.renderer.removeClass(this.document.body, 'dark'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + this.renderer.removeClass(this.document.body, 'menu_dark'); + this.renderer.removeClass(this.document.body, 'logo-black'); + if (localStorage.getItem('choose_skin')) { + this.renderer.removeClass( + this.document.body, + localStorage.getItem('choose_skin') as string + ); + } else { + this.renderer.removeClass( + this.document.body, + 'theme-' + this.config.layout.theme_color + ); + } + + this.renderer.addClass(this.document.body, 'light'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + this.renderer.addClass(this.document.body, 'menu_light'); + this.renderer.addClass(this.document.body, 'logo-white'); + this.renderer.addClass(this.document.body, 'theme-white'); + const theme = 'light'; + const menuOption = 'menu_light'; + this.selectedBgColor = 'white'; + this.isDarkSidebar = false; + localStorage.setItem('choose_logoheader', 'logo-white'); + localStorage.setItem('choose_skin', 'theme-white'); + localStorage.setItem('theme', theme); + localStorage.setItem('menuOption', menuOption); + } + + darkThemeBtnClick() { + this.renderer.removeClass(this.document.body, 'light'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + this.renderer.removeClass(this.document.body, 'menu_light'); + this.renderer.removeClass(this.document.body, 'logo-white'); + if (localStorage.getItem('choose_skin')) { + this.renderer.removeClass( + this.document.body, + localStorage.getItem('choose_skin') as string + ); + } else { + this.renderer.removeClass( + this.document.body, + 'theme-' + this.config.layout.theme_color + ); + } + this.renderer.addClass(this.document.body, 'dark'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + this.renderer.addClass(this.document.body, 'menu_dark'); + this.renderer.addClass(this.document.body, 'logo-black'); + this.renderer.addClass(this.document.body, 'theme-black'); + const theme = 'dark'; + const menuOption = 'menu_dark'; + this.selectedBgColor = 'black'; + this.isDarkSidebar = true; + localStorage.setItem('choose_logoheader', 'logo-black'); + localStorage.setItem('choose_skin', 'theme-black'); + localStorage.setItem('theme', theme); + localStorage.setItem('menuOption', menuOption); + } + + setRightSidebarWindowHeight() { + this.innerHeight = window.innerHeight; + const height = this.innerHeight - this.headerHeight; + this.maxHeight = height + ''; + this.maxWidth = '500px'; + } + + onClickedOutside(event: Event) { + const button = event.target as HTMLButtonElement; + if (button.id !== 'settingBtn') { + if (this.isOpenSidebar === true) { + this.toggleRightSidebar(); + } + } + } + + toggleRightSidebar(): void { + this.rightSidebarService.setRightSidebar( + (this.isOpenSidebar = !this.isOpenSidebar) + ); + } + + switchDirection(event: MatSlideToggleChange) { + const isrtl = String(event.checked); + if ( + isrtl === 'false' && + document.getElementsByTagName('html')[0].hasAttribute('dir') + ) { + document.getElementsByTagName('html')[0].removeAttribute('dir'); + this.renderer.removeClass(this.document.body, 'rtl'); + this.directionService.updateDirection('ltr'); + } else if ( + isrtl === 'true' && + !document.getElementsByTagName('html')[0].hasAttribute('dir') + ) { + document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl'); + this.renderer.addClass(this.document.body, 'rtl'); + this.directionService.updateDirection('rtl'); + } + localStorage.setItem('isRtl', isrtl); + this.isRtl = event.checked; + } + + setRTLSettings() { + document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl'); + this.renderer.addClass(this.document.body, 'rtl'); + this.isRtl = true; + localStorage.setItem('isRtl', 'true'); + } + + setLTRSettings() { + document.getElementsByTagName('html')[0].removeAttribute('dir'); + this.renderer.removeClass(this.document.body, 'rtl'); + this.isRtl = false; + localStorage.setItem('isRtl', 'false'); + } +} diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts new file mode 100644 index 0000000..8371171 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar-items.ts @@ -0,0 +1,209 @@ +import { RouteInfo } from './sidebar.metadata'; +export const ROUTES: RouteInfo[] = [ + { + path: '', + title: 'MENUITEMS.MAIN.TEXT', + iconType: '', + icon: '', + class: '', + groupTitle: true, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '', + title: 'MENUITEMS.DASHBOARD.TEXT', + iconType: 'feather', + icon: 'home', + class: 'menu-toggle', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: 'dashboard/dashboard1', + title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD1', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: 'dashboard/dashboard2', + title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD2', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + ], + }, + + // Common Modules + { + path: '', + title: 'Authentication', + iconType: 'feather', + icon: 'user-check', + class: 'menu-toggle', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: '/authentication/forgot-password', + title: 'Forgot Password', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '/authentication/locked', + title: 'Locked', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '/authentication/page404', + title: '404 - Not Found', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '/authentication/page500', + title: '500 - Server Error', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + ], + }, + { + path: '', + title: 'Extra Pages', + iconType: 'feather', + icon: 'anchor', + class: 'menu-toggle', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: '/extra-pages/blank', + title: 'Blank Page', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + ], + }, + { + path: '', + title: 'Multi level Menu', + iconType: 'feather', + icon: 'chevrons-down', + class: 'menu-toggle', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: '/multilevel/first1', + title: 'First', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '/', + title: 'Second', + iconType: '', + icon: '', + class: 'ml-sub-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: '/multilevel/secondlevel/second1', + title: 'Second 1', + iconType: '', + icon: '', + class: 'ml-menu2', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + { + path: '/', + title: 'Second 2', + iconType: '', + icon: '', + class: 'ml-sub-menu2', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [ + { + path: '/multilevel/thirdlevel/third1', + title: 'third 1', + iconType: '', + icon: '', + class: 'ml-menu3', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + ], + }, + ], + }, + { + path: '/multilevel/first3', + title: 'Third', + iconType: '', + icon: '', + class: 'ml-menu', + groupTitle: false, + badge: '', + badgeClass: '', + submenu: [], + }, + ], + }, +]; diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html new file mode 100644 index 0000000..f1ff34d --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.html @@ -0,0 +1,75 @@ + diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts new file mode 100644 index 0000000..5d604f1 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SidebarComponent } from './sidebar.component'; +describe('SidebarComponent', + () => { + let component: SidebarComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SidebarComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(SidebarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts new file mode 100644 index 0000000..e13a406 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar.component.ts @@ -0,0 +1,174 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +// angular +import { Router, NavigationEnd } from '@angular/router'; +import { DOCUMENT } from '@angular/common'; +import { Component, Inject, ElementRef, OnInit, Renderer2, HostListener, OnDestroy } from '@angular/core'; + +// app +import { ROUTES } from './sidebar-items'; +import { AuthService } from 'src/app/core/service/auth.service'; +import { RouteInfo } from './sidebar.metadata'; + +@Component({ + selector: 'app-sidebar', + templateUrl: './sidebar.component.html', + styleUrls: ['./sidebar.component.scss'], +}) +export class SidebarComponent implements OnInit, OnDestroy { + sidebarItems!: RouteInfo[]; + innerHeight?: number; + bodyTag!: HTMLElement; + listMaxHeight?: string; + listMaxWidth?: string; + userFullName?: string; + userImg?: string; + userType?: string; + headerHeight = 60; + currentRoute?: string; + routerObj; + menuIcon = 'radio_button_checked'; + + constructor( + @Inject(DOCUMENT) private document: Document, + private renderer: Renderer2, + public elementRef: ElementRef, + private authService: AuthService, + private router: Router + ) { + this.elementRef.nativeElement.closest('body'); + this.routerObj = this.router.events.subscribe((event) => { + if (event instanceof NavigationEnd) { + // close sidebar on mobile screen after menu select + this.renderer.removeClass(this.document.body, 'overlay-open'); + } + }); + } + + @HostListener('window:resize', ['$event']) + windowResizecall() { + this.setMenuHeight(); + this.checkStatuForResize(false); + } + + @HostListener('document:mousedown', ['$event']) + onGlobalClick(event: Event): void { + if (!this.elementRef.nativeElement.contains(event.target)) { + this.renderer.removeClass(this.document.body, 'overlay-open'); + } + } + + callToggleMenu(event: Event, length: number) { + if (length > 0) { + const parentElement = (event.target as HTMLInputElement).closest('li'); + const activeClass = parentElement?.classList.contains('active'); + + if (activeClass) { + this.renderer.removeClass(parentElement, 'active'); + } else { + this.renderer.addClass(parentElement, 'active'); + } + } + } + + ngOnInit() { + if (this.authService.currentUserValue) { + this.userFullName = + this.authService.currentUserValue.firstName + + ' ' + + this.authService.currentUserValue.lastName; + this.userImg = this.authService.currentUserValue.img; + this.userType = 'Admin'; + this.sidebarItems = ROUTES.filter((sidebarItem) => sidebarItem); + } + + // this.sidebarItems = ROUTES.filter((sidebarItem) => sidebarItem); + this.initLeftSidebar(); + this.bodyTag = this.document.body; + } + + ngOnDestroy() { + this.routerObj.unsubscribe(); + } + + initLeftSidebar() { + // eslint-disable-next-line @typescript-eslint/no-this-alias + const _this = this; + // Set menu height + _this.setMenuHeight(); + _this.checkStatuForResize(true); + } + + setMenuHeight() { + this.innerHeight = window.innerHeight; + const height = this.innerHeight - this.headerHeight; + this.listMaxHeight = height + ''; + this.listMaxWidth = '500px'; + } + + isOpen() { + return this.bodyTag.classList.contains('overlay-open'); + } + + checkStatuForResize(firstTime: boolean) { + if (window.innerWidth < 1170) { + this.renderer.addClass(this.document.body, 'ls-closed'); + } else { + this.renderer.removeClass(this.document.body, 'ls-closed'); + } + } + + mouseHover() { + const body = this.elementRef.nativeElement.closest('body'); + if (body.classList.contains('submenu-closed')) { + this.renderer.addClass(this.document.body, 'side-closed-hover'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + } + } + + mouseOut() { + const body = this.elementRef.nativeElement.closest('body'); + if (body.classList.contains('side-closed-hover')) { + this.renderer.removeClass(this.document.body, 'side-closed-hover'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + } + } + + mobileMenuSidebarOpen(event: Event, className: string) { + const hasClass = (event.target as HTMLInputElement).classList.contains( + className + ); + if (hasClass) { + this.renderer.removeClass(this.document.body, className); + } else { + this.renderer.addClass(this.document.body, className); + } + } + + callSidemenuCollapse() { + const hasClass = this.document.body.classList.contains('side-closed'); + if (hasClass) { + this.renderer.removeClass(this.document.body, 'side-closed'); + this.renderer.removeClass(this.document.body, 'submenu-closed'); + this.menuIcon = 'radio_button_checked'; + } else { + this.renderer.addClass(this.document.body, 'side-closed'); + this.renderer.addClass(this.document.body, 'submenu-closed'); + this.menuIcon = 'radio_button_unchecked'; + } + + const sideClosedHover = + this.document.body.classList.contains('side-closed'); + if (sideClosedHover) { + this.renderer.removeClass(this.document.body, 'side-closed-hover'); + } + } + + logout() { + this.authService.logout().subscribe((res) => { + if (!res.success) { + console.log('sidebar.logout'); + this.router.navigate(['/authentication/signin']); + } + }); + } +} diff --git a/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts b/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts new file mode 100644 index 0000000..c9a4181 --- /dev/null +++ b/MyOffice.SPA/src/app/layout/sidebar/sidebar.metadata.ts @@ -0,0 +1,12 @@ +// Sidebar route metadata +export interface RouteInfo { + path: string; + title: string; + iconType: string; + icon: string; + class: string; + groupTitle: boolean; + badge: string; + badgeClass: string; + submenu: RouteInfo[]; +} diff --git a/MyOffice.SPA/src/app/multilevel/first1/first1.component.html b/MyOffice.SPA/src/app/multilevel/first1/first1.component.html new file mode 100644 index 0000000..593f45e --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first1/first1.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

First Level

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/first1/first1.component.scss b/MyOffice.SPA/src/app/multilevel/first1/first1.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first1/first1.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/multilevel/first1/first1.component.spec.ts b/MyOffice.SPA/src/app/multilevel/first1/first1.component.spec.ts new file mode 100644 index 0000000..66f88a0 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first1/first1.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { First1Component } from './first1.component'; + +describe('First1Component', + () => { + let component: First1Component; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [First1Component], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(First1Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/first1/first1.component.ts b/MyOffice.SPA/src/app/multilevel/first1/first1.component.ts new file mode 100644 index 0000000..6f4565e --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first1/first1.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-first1', + templateUrl: './first1.component.html', + styleUrls: ['./first1.component.scss'], +}) +export class First1Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/first2/first2.component.html b/MyOffice.SPA/src/app/multilevel/first2/first2.component.html new file mode 100644 index 0000000..d316756 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first2/first2.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

First Level 2

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/first2/first2.component.scss b/MyOffice.SPA/src/app/multilevel/first2/first2.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first2/first2.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/multilevel/first2/first2.component.spec.ts b/MyOffice.SPA/src/app/multilevel/first2/first2.component.spec.ts new file mode 100644 index 0000000..c502d55 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first2/first2.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { First2Component } from './first2.component'; + +describe('First2Component', + () => { + let component: First2Component; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [First2Component], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(First2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/first2/first2.component.ts b/MyOffice.SPA/src/app/multilevel/first2/first2.component.ts new file mode 100644 index 0000000..80bd74c --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first2/first2.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-first2', + templateUrl: './first2.component.html', + styleUrls: ['./first2.component.scss'], +}) +export class First2Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/first3/first3.component.html b/MyOffice.SPA/src/app/multilevel/first3/first3.component.html new file mode 100644 index 0000000..8c66436 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first3/first3.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

First Level 3

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/first3/first3.component.scss b/MyOffice.SPA/src/app/multilevel/first3/first3.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first3/first3.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/multilevel/first3/first3.component.spec.ts b/MyOffice.SPA/src/app/multilevel/first3/first3.component.spec.ts new file mode 100644 index 0000000..b647942 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first3/first3.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { First3Component } from './first3.component'; + +describe('First3Component', + () => { + let component: First3Component; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [First3Component], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(First3Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/first3/first3.component.ts b/MyOffice.SPA/src/app/multilevel/first3/first3.component.ts new file mode 100644 index 0000000..30520b9 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/first3/first3.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-first3', + templateUrl: './first3.component.html', + styleUrls: ['./first3.component.scss'], +}) +export class First3Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/multilevel-routing.module.ts b/MyOffice.SPA/src/app/multilevel/multilevel-routing.module.ts new file mode 100644 index 0000000..16b47a3 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/multilevel-routing.module.ts @@ -0,0 +1,39 @@ +import { First3Component } from './first3/first3.component'; +import { First2Component } from './first2/first2.component'; +import { First1Component } from './first1/first1.component'; +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = [ + { + path: 'first1', + component: First1Component, + }, + { + path: 'first2', + component: First2Component, + }, + { + path: 'first3', + component: First3Component, + }, + { + path: 'secondlevel', + loadChildren: () => + import('./secondlevel/secondlevel.module').then( + (m) => m.SecondLevelModule + ), + }, + { + path: 'thirdlevel', + loadChildren: () => + import('./thirdlevel/thirdlevel.module').then((m) => m.ThirdlevelModule), + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class MultilevelRoutingModule { +} diff --git a/MyOffice.SPA/src/app/multilevel/multilevel.module.ts b/MyOffice.SPA/src/app/multilevel/multilevel.module.ts new file mode 100644 index 0000000..62287cd --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/multilevel.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { MultilevelRoutingModule } from './multilevel-routing.module'; +import { First1Component } from './first1/first1.component'; +import { First2Component } from './first2/first2.component'; +import { First3Component } from './first3/first3.component'; +import { ComponentsModule } from '../shared/components/components.module'; + +@NgModule({ + declarations: [First1Component, First2Component, First3Component], + imports: [CommonModule, MultilevelRoutingModule, ComponentsModule], +}) +export class MultilevelModule { +} diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.html b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.html new file mode 100644 index 0000000..e80b3e6 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

Second Level

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.scss b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.spec.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.spec.ts new file mode 100644 index 0000000..580bf65 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { Second1Component } from './second1.component'; + +describe('Second1Component', + () => { + let component: Second1Component; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [Second1Component], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(Second1Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.ts new file mode 100644 index 0000000..9405dff --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second1/second1.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-second1', + templateUrl: './second1.component.html', + styleUrls: ['./second1.component.scss'], +}) +export class Second1Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.html b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.html new file mode 100644 index 0000000..d561c39 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

Second Level 2

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.scss b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.scss @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.spec.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.spec.ts new file mode 100644 index 0000000..1e2fe36 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.spec.ts @@ -0,0 +1,28 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { Second2Component } from './second2.component'; + +describe('Second2Component', + () => { + let component: Second2Component; + let fixture: ComponentFixture; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [Second2Component], + }).compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(Second2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.ts new file mode 100644 index 0000000..4d25ccf --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/second2/second2.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-second2', + templateUrl: './second2.component.html', + styleUrls: ['./second2.component.scss'], +}) +export class Second2Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel-routing.module.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel-routing.module.ts new file mode 100644 index 0000000..f459040 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel-routing.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { Second1Component } from './second1/second1.component'; +import { Second2Component } from './second2/second2.component'; + +const routes: Routes = [ + { + path: 'second1', + component: Second1Component, + }, + { + path: 'second2', + component: Second2Component, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class SecondLevelRoutingModule { +} diff --git a/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel.module.ts b/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel.module.ts new file mode 100644 index 0000000..edb92fd --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/secondlevel/secondlevel.module.ts @@ -0,0 +1,20 @@ +import { Second1Component } from './second1/second1.component'; +import { Second2Component } from './second2/second2.component'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { SecondLevelRoutingModule } from './secondlevel-routing.module'; +import { ComponentsModule } from 'src/app/shared/components/components.module'; + +@NgModule({ + declarations: [Second1Component, Second2Component], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + SecondLevelRoutingModule, + ComponentsModule, + ], +}) +export class SecondLevelModule { +} diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.html b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.html new file mode 100644 index 0000000..24747de --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.html @@ -0,0 +1,21 @@ +
+
+
+ + + +
+
+
+
+
+

Third Level

+
+
+ +
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.scss b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.spec.ts b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.spec.ts new file mode 100644 index 0000000..ff9a71d --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Third1Component } from './third1.component'; + +describe('Third1Component', + () => { + let component: Third1Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [Third1Component] + }) + .compileComponents(); + + fixture = TestBed.createComponent(Third1Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.ts b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.ts new file mode 100644 index 0000000..250206d --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/thirdlevel/third1/third1.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-third1', + templateUrl: './third1.component.html', + styleUrls: ['./third1.component.scss'], +}) +export class Third1Component { + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel-routing.module.ts b/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel-routing.module.ts new file mode 100644 index 0000000..7cc6084 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { Third1Component } from './third1/third1.component'; + +const routes: Routes = [ + { + path: 'third1', + component: Third1Component, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ThirdlevelRoutingModule { +} diff --git a/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel.module.ts b/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel.module.ts new file mode 100644 index 0000000..6384dc6 --- /dev/null +++ b/MyOffice.SPA/src/app/multilevel/thirdlevel/thirdlevel.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ThirdlevelRoutingModule } from './thirdlevel-routing.module'; +import { Third1Component } from './third1/third1.component'; +import { ComponentsModule } from './../../shared/components/components.module'; + +@NgModule({ + declarations: [Third1Component], + imports: [CommonModule, ThirdlevelRoutingModule, ComponentsModule], +}) +export class ThirdlevelModule { +} diff --git a/MyOffice.SPA/src/app/pages/pages-routing.module.ts b/MyOffice.SPA/src/app/pages/pages-routing.module.ts new file mode 100644 index 0000000..fdcf39b --- /dev/null +++ b/MyOffice.SPA/src/app/pages/pages-routing.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { UserProfileComponent } from './user-profile/user-profile.component'; + +const routes: Routes = [ + { + path: '', + redirectTo: 'signin', + pathMatch: 'full', + }, + { + path: 'user/profile', + component: UserProfileComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class PagesRoutingModule { +} diff --git a/MyOffice.SPA/src/app/pages/pages.module.ts b/MyOffice.SPA/src/app/pages/pages.module.ts new file mode 100644 index 0000000..447e903 --- /dev/null +++ b/MyOffice.SPA/src/app/pages/pages.module.ts @@ -0,0 +1,30 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { PagesRoutingModule } from './pages-routing.module'; +import { UserProfileComponent } from './user-profile/user-profile.component'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { ComponentsModule } from '../shared/components/components.module'; + +@NgModule({ + declarations: [ + UserProfileComponent, + ], + imports: [ + CommonModule, + ComponentsModule, + FormsModule, + ReactiveFormsModule, + PagesRoutingModule, + MatFormFieldModule, + MatInputModule, + MatIconModule, + MatButtonModule, + ], +}) +export class PagesModule { +} diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html new file mode 100644 index 0000000..1c771ab --- /dev/null +++ b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.html @@ -0,0 +1,116 @@ +
+
+
+ + + +
+
+
+
+
+

User Profile

+
+
+
+
+
+ + Email + + email + +
+
+
+
+ + First name + + face + + Only characters or numbers allowed + + +
+
+ + Last name + + face + + Only characters or numbers allowed + + +
+
+
+
+ + Full name + + face + + Full name is empty + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+

+ Providers +

+
+
+
+
+ link + email + mark_email_read +
+
+ {{provider.name}} +
+
+ + + + + + +
+
+
+
+
+
+
+
diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.scss b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts new file mode 100644 index 0000000..bc71b08 --- /dev/null +++ b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { UserProfileComponent } from './user-profile.component'; + +describe('UserProfileComponent', + () => { + let component: UserProfileComponent; + let fixture: ComponentFixture; + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UserProfileComponent], + }).compileComponents(); + }) + ); + beforeEach(() => { + fixture = TestBed.createComponent(UserProfileComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts new file mode 100644 index 0000000..d8e8038 --- /dev/null +++ b/MyOffice.SPA/src/app/pages/user-profile/user-profile.component.ts @@ -0,0 +1,139 @@ +// angular +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { UntypedFormBuilder } from '@angular/forms'; +import { UntypedFormGroup } from '@angular/forms'; +import { Validators } from '@angular/forms'; +import { FormControl } from '@angular/forms'; + +// libs +import Swal from 'sweetalert2'; + +// app +import { ApiRoutes } from '../../api-routes'; +import { ExternalLoginConfig } from '../../config.external-login'; +import { AuthService } from '../../core/service/auth.service'; + +@Component({ + selector: 'app-blank', + templateUrl: './user-profile.component.html', + styleUrls: ['./user-profile.component.scss'], +}) +export class UserProfileComponent { + form: UntypedFormGroup; + providers?: ProviderModel[]; + + constructor( + private fb: UntypedFormBuilder, + private httpClient: HttpClient, + private authService: AuthService, + ) { + this.form = this.fb.group({ + firstName: ['', [Validators.pattern('[a-zA-Z0-9]+')]], + lastName: ['', [Validators.pattern('[a-zA-Z0-9]+')]], + fullName: ['', [Validators.pattern('[a-zA-Z0-9 ]+')]], + email: [{ value: '', disabled: true }, []], + }); + + this.providers = ExternalLoginConfig + .getConfiguredProviders() + .map(x => { + provider: x.provider, + name: x.name, + isConnected: false, + isEmailConfirmed: false + }); + } + + ngOnInit(): void { + this.load(); + } + + private updateForm(data: ProfileModel) { + this.form.patchValue(data); + } + + private load() { + this.httpClient.get(ApiRoutes.UserProfile).subscribe(data => { + this.updateForm(data); + + this.providers?.map((provider) => { + var attached = data.providers?.find(x => x.provider === provider.provider); + provider.isConnected = false; + provider.isEmailConfirmed = false; + if (attached) { + provider.isConnected = true; + provider.isEmailConfirmed = attached.isEmailConfirmed; + } + }); + }); + } + + onSubmit() { + if (this.form.invalid) { + return; + } + + this.httpClient.post(ApiRoutes.UserProfile, this.form.value).subscribe(data => { + this.updateForm(data); + console.log(this.form); + }); + } + + connect(provider: ProviderModel) { + provider.error = undefined; + provider.isLoading = true; + + if (provider.provider === ExternalLoginConfig.GOOGLE) { + this.authService.attachGoogle().subscribe(r => { + this.load(); + provider.isLoading = false; + }); + } + if (provider.provider === ExternalLoginConfig.AUTH0) { + this.authService.attachAuth0().subscribe(resp => { + provider.error = ''; + if (!resp.success) { + provider.error = resp.data || 'Connect failed'; + } + this.load(); + provider.isLoading = false; + }); + } + } + + disconnect(provider: string) { + Swal.fire({ + title: 'Are you sure to disconnect ' + provider + ' ?', + text: 'Some providers can be connected only with login!', + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Yes, disconnect it!', + }).then((result) => { + if (result.value) { + this.authService.deattach(provider).subscribe(x => { + this.load(); + }); + } + }); + } +} + +interface ProviderModel { + provider: string; + name: string; + isConnected: boolean; + isEmailConfirmed: boolean; + error?: string; + isLoading: boolean; +} + +interface ProfileModel { + firstName?: string, + lastName?: string, + fullName?: string, + isEmailConfirmed?: boolean, + providers?: ProviderModel[], +} diff --git a/MyOffice.SPA/src/app/shared/TableElement.ts b/MyOffice.SPA/src/app/shared/TableElement.ts new file mode 100644 index 0000000..ad7a93a --- /dev/null +++ b/MyOffice.SPA/src/app/shared/TableElement.ts @@ -0,0 +1,3 @@ +export interface TableElement { + [key: string]: string | number; +} diff --git a/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts b/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts new file mode 100644 index 0000000..8fcd939 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/UnsubscribeOnDestroyAdapter.ts @@ -0,0 +1,20 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { SubSink } from './sub-sink'; + +/** + * A class that automatically unsubscribes all observables when the object gets destroyed + */ +@Injectable() +export class UnsubscribeOnDestroyAdapter implements OnDestroy { + /** + * The subscription sink object that stores all subscriptions + */ + subs = new SubSink(); + + /** + * The lifecycle hook that unsubscribes all subscriptions when the component / object gets destroyed + */ + ngOnDestroy(): void { + this.subs.unsubscribe(); + } +} diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html new file mode 100644 index 0000000..01d8897 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.html @@ -0,0 +1,20 @@ + diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.scss b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts new file mode 100644 index 0000000..e8f9133 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BreadcrumbComponent } from './breadcrumb.component'; + +describe('BreadcrumbComponent', + () => { + let component: BreadcrumbComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [BreadcrumbComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(BreadcrumbComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts new file mode 100644 index 0000000..5e67931 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/breadcrumb/breadcrumb.component.ts @@ -0,0 +1,19 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-breadcrumb', + templateUrl: './breadcrumb.component.html', + styleUrls: ['./breadcrumb.component.scss'], +}) +export class BreadcrumbComponent { + @Input() + title!: string; + @Input() + items!: string[]; + @Input() + active_item!: string; + + constructor() { + //constructor + } +} diff --git a/MyOffice.SPA/src/app/shared/components/components.module.ts b/MyOffice.SPA/src/app/shared/components/components.module.ts new file mode 100644 index 0000000..30ceb7e --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/components.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { FileUploadComponent } from './file-upload/file-upload.component'; +import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component'; +import { SharedModule } from '../shared.module'; + +@NgModule({ + declarations: [FileUploadComponent, BreadcrumbComponent], + imports: [SharedModule], + exports: [FileUploadComponent, BreadcrumbComponent], +}) +export class ComponentsModule { +} diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html new file mode 100644 index 0000000..1e97cd1 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.html @@ -0,0 +1 @@ + diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.scss b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts new file mode 100644 index 0000000..c1e8bbf --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FeatherIconsComponent } from './feather-icons.component'; + +describe('FeatherIconsComponent', + () => { + let component: FeatherIconsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [FeatherIconsComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FeatherIconsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts new file mode 100644 index 0000000..5f97c19 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.component.ts @@ -0,0 +1,17 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-feather-icons', + templateUrl: './feather-icons.component.html', + styleUrls: ['./feather-icons.component.scss'], +}) +export class FeatherIconsComponent { + @Input() + icon?: string; + @Input() + class?: string; + + constructor() { + // constructor + } +} diff --git a/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts new file mode 100644 index 0000000..0b3bbb2 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/feather-icons/feather-icons.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FeatherIconsComponent } from './feather-icons.component'; + +import { FeatherModule } from 'angular-feather'; +import { allIcons } from 'angular-feather/icons'; + +@NgModule({ + imports: [CommonModule, FeatherModule.pick(allIcons)], + exports: [FeatherIconsComponent, FeatherModule], + declarations: [FeatherIconsComponent], +}) +export class FeatherIconsModule { +} diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html new file mode 100644 index 0000000..8fb6747 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.html @@ -0,0 +1,5 @@ +
+ + {{file ? file.name : ' or drag and drop file here' }} + +
diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss new file mode 100644 index 0000000..d3cb0d4 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.scss @@ -0,0 +1,27 @@ +.file-drop-area { + border: 1px dashed #7c7db3; + border-radius: 3px; + position: relative; + max-width: 100%; + margin-top: 5px; + padding: 26px 20px 30px; + transition: 0.2s; +} + +.file-input { + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 100%; + cursor: pointer; + opacity: 0; +} + +.file-msg { + display: inline-block; + margin-left: 5px; + font-size: 12px; + font-weight: 500; + color: #5b5bff; +} diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts new file mode 100644 index 0000000..622f59d --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.spec.ts @@ -0,0 +1,26 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FileUploadComponent } from './file-upload.component'; + +describe('FileUploadComponent', + () => { + let component: FileUploadComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [FileUploadComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FileUploadComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', + () => { + expect(component).toBeTruthy(); + }); + }); diff --git a/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts new file mode 100644 index 0000000..9dfd503 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/components/file-upload/file-upload.component.ts @@ -0,0 +1,44 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/ban-types */ +import { Component, ElementRef, HostListener, Input } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; + +@Component({ + selector: 'app-file-upload', + templateUrl: './file-upload.component.html', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: FileUploadComponent, + multi: true, + }, + ], + styleUrls: ['./file-upload.component.scss'], +}) +export class FileUploadComponent implements ControlValueAccessor { + onChange!: Function; + file: File | null = null; + + @HostListener('change', ['$event.target.files']) + emitFiles(event: FileList) { + const file = event && event.item(0); + this.onChange(file); + this.file = file; + } + + constructor(private host: ElementRef) {} + + writeValue(value: null) { + // clear file input + this.host.nativeElement.value = ''; + this.file = null; + } + + registerOnChange(fn: Function) { + this.onChange = fn; + } + + registerOnTouched(fn: Function) { + // add code here + } +} diff --git a/MyOffice.SPA/src/app/shared/feather-icons.module.ts b/MyOffice.SPA/src/app/shared/feather-icons.module.ts new file mode 100644 index 0000000..d3e4d0c --- /dev/null +++ b/MyOffice.SPA/src/app/shared/feather-icons.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; + +import { FeatherModule } from 'angular-feather'; +import { allIcons } from 'angular-feather/icons'; + +// Select some icons (use an object, not an array) + +@NgModule({ + imports: [FeatherModule.pick(allIcons)], + exports: [FeatherModule], +}) +export class FeatherIconsModule { +} diff --git a/MyOffice.SPA/src/app/shared/material.module.ts b/MyOffice.SPA/src/app/shared/material.module.ts new file mode 100644 index 0000000..687e39a --- /dev/null +++ b/MyOffice.SPA/src/app/shared/material.module.ts @@ -0,0 +1,36 @@ +import { NgModule } from '@angular/core'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatNativeDateModule } from '@angular/material/core'; +import { NgxMaskModule } from 'ngx-mask'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatListModule } from '@angular/material/list'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; + +const materialModules = [ + MatButtonModule, + MatInputModule, + MatListModule, + MatIconModule, + MatTooltipModule, + MatDatepickerModule, + MatNativeDateModule, + NgxMaskModule.forRoot(), + MatButtonToggleModule, + MatFormFieldModule, + MatMenuModule, + MatSlideToggleModule, +]; + +@NgModule({ + declarations: [], + imports: [materialModules], + exports: [materialModules], +}) +export class MaterialModule { +} diff --git a/MyOffice.SPA/src/app/shared/shared.module.ts b/MyOffice.SPA/src/app/shared/shared.module.ts new file mode 100644 index 0000000..4f1da2e --- /dev/null +++ b/MyOffice.SPA/src/app/shared/shared.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { MaterialModule } from './material.module'; +import { FeatherIconsModule } from './components/feather-icons/feather-icons.module'; + +@NgModule({ + declarations: [], + imports: [CommonModule, FormsModule, ReactiveFormsModule, RouterModule], + exports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + RouterModule, + MaterialModule, + FeatherIconsModule, + ], +}) +export class SharedModule { +} diff --git a/MyOffice.SPA/src/app/shared/sub-sink.ts b/MyOffice.SPA/src/app/shared/sub-sink.ts new file mode 100644 index 0000000..afb3d23 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/sub-sink.ts @@ -0,0 +1,61 @@ +import { SubscriptionLike } from 'rxjs'; + +// TODO: SubSink -> SubSync +/** + * Subscription sink that holds Observable subscriptions + * until you call unsubscribe on it in ngOnDestroy. + */ +export class SubSink { + protected _subs: SubscriptionLike[] = []; + + /** + * Subscription sink that holds Observable subscriptions + * until you call unsubscribe on it in ngOnDestroy. + * + * @example + * In Angular: + * ``` + * private subs = new SubSink(); + * ... + * this.subs.sink = observable$.subscribe( + * this.subs.add(observable$.subscribe(...)); + * ... + * ngOnDestroy() { + * this.subs.unsubscribe(); + * } + * ``` + */ + constructor() { + // constructor + } + + /** + * Add subscriptions to the tracked subscriptions + * @example + * this.subs.add(observable$.subscribe(...)); + */ + add(...subscriptions: SubscriptionLike[]) { + this._subs = this._subs.concat(subscriptions); + } + + /** + * Assign subscription to this sink to add it to the tracked subscriptions + * @example + * this.subs.sink = observable$.subscribe(...); + */ + set sink(subscription: SubscriptionLike) { + this._subs.push(subscription); + } + + /** + * Unsubscribe to all subscriptions in ngOnDestroy() + * @example + * ngOnDestroy() { + * this.subs.unsubscribe(); + * } + */ + unsubscribe() { + this._subs.forEach((sub) => sub && sub.unsubscribe()); + this._subs = []; + } +} diff --git a/MyOffice.SPA/src/app/shared/tableExportUtil.ts b/MyOffice.SPA/src/app/shared/tableExportUtil.ts new file mode 100644 index 0000000..e22b342 --- /dev/null +++ b/MyOffice.SPA/src/app/shared/tableExportUtil.ts @@ -0,0 +1,42 @@ +import * as XLSX from 'xlsx'; +import { TableElement } from './TableElement'; + +const getFileName = (name: string) => { + const timeSpan = new Date().toISOString(); + const sheetName = name || 'ExportResult'; + const fileName = `${sheetName}-${timeSpan}`; + return { + sheetName, + fileName, + }; +}; + +export class TableExportUtil { + static exportToExcel(arr: Partial[], name: string) { + const { sheetName, fileName } = getFileName(name); + + const wb = XLSX.utils.book_new(); + const ws = XLSX.utils.json_to_sheet(arr); + XLSX.utils.book_append_sheet(wb, ws, sheetName); + XLSX.writeFile(wb, `${fileName}.xlsx`); + } + + // static exportToPDF(exportData: any[]) { + // const doc = new jsPDF(); + // const dataValue: any = Object.keys(exportData).map(function ( + // personNamedIndex: any + // ) { + // return Object.values(exportData[personNamedIndex]); + // }); + // const keys: any = Object.keys(exportData[0]); + + // autoTable(doc, { + // head: [keys], + // body: dataValue, + // }); + + // const { fileName } = getFileName('pdf'); + + // doc.save(`${fileName}.pdf`); + // } +} diff --git a/MyOffice.SPA/src/assets/.gitkeep b/MyOffice.SPA/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot new file mode 100644 index 0000000..f5c1fd4 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg new file mode 100644 index 0000000..e29de15 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.svg @@ -0,0 +1,1181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf new file mode 100644 index 0000000..218ff47 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff new file mode 100644 index 0000000..d24c3a9 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 new file mode 100644 index 0000000..372c314 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-brands-400.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot new file mode 100644 index 0000000..5999593 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg new file mode 100644 index 0000000..0085843 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.svg @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf new file mode 100644 index 0000000..4adbd66 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff new file mode 100644 index 0000000..94d86d1 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 new file mode 100644 index 0000000..cff972c Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-regular-400.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot new file mode 100644 index 0000000..9def162 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg new file mode 100644 index 0000000..a229433 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.svg @@ -0,0 +1,2567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf new file mode 100644 index 0000000..c681849 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff new file mode 100644 index 0000000..891a580 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 new file mode 100644 index 0000000..00d15c4 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/fontawesome/fa-solid-900.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.eot b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.eot new file mode 100644 index 0000000..70508eb Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ijmap b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ijmap new file mode 100644 index 0000000..d9f1d25 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ijmap @@ -0,0 +1 @@ +{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.svg b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.svg new file mode 100644 index 0000000..a449327 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.svg @@ -0,0 +1,2373 @@ + + + + + +Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 + By shyndman +Copyright 2015 Google, Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ttf b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ttf new file mode 100644 index 0000000..7015564 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff new file mode 100644 index 0000000..b648a3e Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff2 b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff2 new file mode 100644 index 0000000..9fa2112 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/iconfont/MaterialIcons-Regular.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/README.md b/MyOffice.SPA/src/assets/fonts/iconfont/README.md new file mode 100644 index 0000000..ce4141e --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/iconfont/README.md @@ -0,0 +1,9 @@ +The recommended way to use the Material Icons font is by linking to the web font hosted on Google Fonts: + +```html + +``` + +Read more in our full usage guide: +http://google.github.io/material-design-icons/#icon-font-for-the-web diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/codepoints b/MyOffice.SPA/src/assets/fonts/iconfont/codepoints new file mode 100644 index 0000000..3c8b075 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/iconfont/codepoints @@ -0,0 +1,932 @@ +3d_rotation e84d +ac_unit eb3b +access_alarm e190 +access_alarms e191 +access_time e192 +accessibility e84e +accessible e914 +account_balance e84f +account_balance_wallet e850 +account_box e851 +account_circle e853 +adb e60e +add e145 +add_a_photo e439 +add_alarm e193 +add_alert e003 +add_box e146 +add_circle e147 +add_circle_outline e148 +add_location e567 +add_shopping_cart e854 +add_to_photos e39d +add_to_queue e05c +adjust e39e +airline_seat_flat e630 +airline_seat_flat_angled e631 +airline_seat_individual_suite e632 +airline_seat_legroom_extra e633 +airline_seat_legroom_normal e634 +airline_seat_legroom_reduced e635 +airline_seat_recline_extra e636 +airline_seat_recline_normal e637 +airplanemode_active e195 +airplanemode_inactive e194 +airplay e055 +airport_shuttle eb3c +alarm e855 +alarm_add e856 +alarm_off e857 +alarm_on e858 +album e019 +all_inclusive eb3d +all_out e90b +android e859 +announcement e85a +apps e5c3 +archive e149 +arrow_back e5c4 +arrow_downward e5db +arrow_drop_down e5c5 +arrow_drop_down_circle e5c6 +arrow_drop_up e5c7 +arrow_forward e5c8 +arrow_upward e5d8 +art_track e060 +aspect_ratio e85b +assessment e85c +assignment e85d +assignment_ind e85e +assignment_late e85f +assignment_return e860 +assignment_returned e861 +assignment_turned_in e862 +assistant e39f +assistant_photo e3a0 +attach_file e226 +attach_money e227 +attachment e2bc +audiotrack e3a1 +autorenew e863 +av_timer e01b +backspace e14a +backup e864 +battery_alert e19c +battery_charging_full e1a3 +battery_full e1a4 +battery_std e1a5 +battery_unknown e1a6 +beach_access eb3e +beenhere e52d +block e14b +bluetooth e1a7 +bluetooth_audio e60f +bluetooth_connected e1a8 +bluetooth_disabled e1a9 +bluetooth_searching e1aa +blur_circular e3a2 +blur_linear e3a3 +blur_off e3a4 +blur_on e3a5 +book e865 +bookmark e866 +bookmark_border e867 +border_all e228 +border_bottom e229 +border_clear e22a +border_color e22b +border_horizontal e22c +border_inner e22d +border_left e22e +border_outer e22f +border_right e230 +border_style e231 +border_top e232 +border_vertical e233 +branding_watermark e06b +brightness_1 e3a6 +brightness_2 e3a7 +brightness_3 e3a8 +brightness_4 e3a9 +brightness_5 e3aa +brightness_6 e3ab +brightness_7 e3ac +brightness_auto e1ab +brightness_high e1ac +brightness_low e1ad +brightness_medium e1ae +broken_image e3ad +brush e3ae +bubble_chart e6dd +bug_report e868 +build e869 +burst_mode e43c +business e0af +business_center eb3f +cached e86a +cake e7e9 +call e0b0 +call_end e0b1 +call_made e0b2 +call_merge e0b3 +call_missed e0b4 +call_missed_outgoing e0e4 +call_received e0b5 +call_split e0b6 +call_to_action e06c +camera e3af +camera_alt e3b0 +camera_enhance e8fc +camera_front e3b1 +camera_rear e3b2 +camera_roll e3b3 +cancel e5c9 +card_giftcard e8f6 +card_membership e8f7 +card_travel e8f8 +casino eb40 +cast e307 +cast_connected e308 +center_focus_strong e3b4 +center_focus_weak e3b5 +change_history e86b +chat e0b7 +chat_bubble e0ca +chat_bubble_outline e0cb +check e5ca +check_box e834 +check_box_outline_blank e835 +check_circle e86c +chevron_left e5cb +chevron_right e5cc +child_care eb41 +child_friendly eb42 +chrome_reader_mode e86d +class e86e +clear e14c +clear_all e0b8 +close e5cd +closed_caption e01c +cloud e2bd +cloud_circle e2be +cloud_done e2bf +cloud_download e2c0 +cloud_off e2c1 +cloud_queue e2c2 +cloud_upload e2c3 +code e86f +collections e3b6 +collections_bookmark e431 +color_lens e3b7 +colorize e3b8 +comment e0b9 +compare e3b9 +compare_arrows e915 +computer e30a +confirmation_number e638 +contact_mail e0d0 +contact_phone e0cf +contacts e0ba +content_copy e14d +content_cut e14e +content_paste e14f +control_point e3ba +control_point_duplicate e3bb +copyright e90c +create e150 +create_new_folder e2cc +credit_card e870 +crop e3be +crop_16_9 e3bc +crop_3_2 e3bd +crop_5_4 e3bf +crop_7_5 e3c0 +crop_din e3c1 +crop_free e3c2 +crop_landscape e3c3 +crop_original e3c4 +crop_portrait e3c5 +crop_rotate e437 +crop_square e3c6 +dashboard e871 +data_usage e1af +date_range e916 +dehaze e3c7 +delete e872 +delete_forever e92b +delete_sweep e16c +description e873 +desktop_mac e30b +desktop_windows e30c +details e3c8 +developer_board e30d +developer_mode e1b0 +device_hub e335 +devices e1b1 +devices_other e337 +dialer_sip e0bb +dialpad e0bc +directions e52e +directions_bike e52f +directions_boat e532 +directions_bus e530 +directions_car e531 +directions_railway e534 +directions_run e566 +directions_subway e533 +directions_transit e535 +directions_walk e536 +disc_full e610 +dns e875 +do_not_disturb e612 +do_not_disturb_alt e611 +do_not_disturb_off e643 +do_not_disturb_on e644 +dock e30e +domain e7ee +done e876 +done_all e877 +donut_large e917 +donut_small e918 +drafts e151 +drag_handle e25d +drive_eta e613 +dvr e1b2 +edit e3c9 +edit_location e568 +eject e8fb +email e0be +enhanced_encryption e63f +equalizer e01d +error e000 +error_outline e001 +euro_symbol e926 +ev_station e56d +event e878 +event_available e614 +event_busy e615 +event_note e616 +event_seat e903 +exit_to_app e879 +expand_less e5ce +expand_more e5cf +explicit e01e +explore e87a +exposure e3ca +exposure_neg_1 e3cb +exposure_neg_2 e3cc +exposure_plus_1 e3cd +exposure_plus_2 e3ce +exposure_zero e3cf +extension e87b +face e87c +fast_forward e01f +fast_rewind e020 +favorite e87d +favorite_border e87e +featured_play_list e06d +featured_video e06e +feedback e87f +fiber_dvr e05d +fiber_manual_record e061 +fiber_new e05e +fiber_pin e06a +fiber_smart_record e062 +file_download e2c4 +file_upload e2c6 +filter e3d3 +filter_1 e3d0 +filter_2 e3d1 +filter_3 e3d2 +filter_4 e3d4 +filter_5 e3d5 +filter_6 e3d6 +filter_7 e3d7 +filter_8 e3d8 +filter_9 e3d9 +filter_9_plus e3da +filter_b_and_w e3db +filter_center_focus e3dc +filter_drama e3dd +filter_frames e3de +filter_hdr e3df +filter_list e152 +filter_none e3e0 +filter_tilt_shift e3e2 +filter_vintage e3e3 +find_in_page e880 +find_replace e881 +fingerprint e90d +first_page e5dc +fitness_center eb43 +flag e153 +flare e3e4 +flash_auto e3e5 +flash_off e3e6 +flash_on e3e7 +flight e539 +flight_land e904 +flight_takeoff e905 +flip e3e8 +flip_to_back e882 +flip_to_front e883 +folder e2c7 +folder_open e2c8 +folder_shared e2c9 +folder_special e617 +font_download e167 +format_align_center e234 +format_align_justify e235 +format_align_left e236 +format_align_right e237 +format_bold e238 +format_clear e239 +format_color_fill e23a +format_color_reset e23b +format_color_text e23c +format_indent_decrease e23d +format_indent_increase e23e +format_italic e23f +format_line_spacing e240 +format_list_bulleted e241 +format_list_numbered e242 +format_paint e243 +format_quote e244 +format_shapes e25e +format_size e245 +format_strikethrough e246 +format_textdirection_l_to_r e247 +format_textdirection_r_to_l e248 +format_underlined e249 +forum e0bf +forward e154 +forward_10 e056 +forward_30 e057 +forward_5 e058 +free_breakfast eb44 +fullscreen e5d0 +fullscreen_exit e5d1 +functions e24a +g_translate e927 +gamepad e30f +games e021 +gavel e90e +gesture e155 +get_app e884 +gif e908 +golf_course eb45 +gps_fixed e1b3 +gps_not_fixed e1b4 +gps_off e1b5 +grade e885 +gradient e3e9 +grain e3ea +graphic_eq e1b8 +grid_off e3eb +grid_on e3ec +group e7ef +group_add e7f0 +group_work e886 +hd e052 +hdr_off e3ed +hdr_on e3ee +hdr_strong e3f1 +hdr_weak e3f2 +headset e310 +headset_mic e311 +healing e3f3 +hearing e023 +help e887 +help_outline e8fd +high_quality e024 +highlight e25f +highlight_off e888 +history e889 +home e88a +hot_tub eb46 +hotel e53a +hourglass_empty e88b +hourglass_full e88c +http e902 +https e88d +image e3f4 +image_aspect_ratio e3f5 +import_contacts e0e0 +import_export e0c3 +important_devices e912 +inbox e156 +indeterminate_check_box e909 +info e88e +info_outline e88f +input e890 +insert_chart e24b +insert_comment e24c +insert_drive_file e24d +insert_emoticon e24e +insert_invitation e24f +insert_link e250 +insert_photo e251 +invert_colors e891 +invert_colors_off e0c4 +iso e3f6 +keyboard e312 +keyboard_arrow_down e313 +keyboard_arrow_left e314 +keyboard_arrow_right e315 +keyboard_arrow_up e316 +keyboard_backspace e317 +keyboard_capslock e318 +keyboard_hide e31a +keyboard_return e31b +keyboard_tab e31c +keyboard_voice e31d +kitchen eb47 +label e892 +label_outline e893 +landscape e3f7 +language e894 +laptop e31e +laptop_chromebook e31f +laptop_mac e320 +laptop_windows e321 +last_page e5dd +launch e895 +layers e53b +layers_clear e53c +leak_add e3f8 +leak_remove e3f9 +lens e3fa +library_add e02e +library_books e02f +library_music e030 +lightbulb_outline e90f +line_style e919 +line_weight e91a +linear_scale e260 +link e157 +linked_camera e438 +list e896 +live_help e0c6 +live_tv e639 +local_activity e53f +local_airport e53d +local_atm e53e +local_bar e540 +local_cafe e541 +local_car_wash e542 +local_convenience_store e543 +local_dining e556 +local_drink e544 +local_florist e545 +local_gas_station e546 +local_grocery_store e547 +local_hospital e548 +local_hotel e549 +local_laundry_service e54a +local_library e54b +local_mall e54c +local_movies e54d +local_offer e54e +local_parking e54f +local_pharmacy e550 +local_phone e551 +local_pizza e552 +local_play e553 +local_post_office e554 +local_printshop e555 +local_see e557 +local_shipping e558 +local_taxi e559 +location_city e7f1 +location_disabled e1b6 +location_off e0c7 +location_on e0c8 +location_searching e1b7 +lock e897 +lock_open e898 +lock_outline e899 +looks e3fc +looks_3 e3fb +looks_4 e3fd +looks_5 e3fe +looks_6 e3ff +looks_one e400 +looks_two e401 +loop e028 +loupe e402 +low_priority e16d +loyalty e89a +mail e158 +mail_outline e0e1 +map e55b +markunread e159 +markunread_mailbox e89b +memory e322 +menu e5d2 +merge_type e252 +message e0c9 +mic e029 +mic_none e02a +mic_off e02b +mms e618 +mode_comment e253 +mode_edit e254 +monetization_on e263 +money_off e25c +monochrome_photos e403 +mood e7f2 +mood_bad e7f3 +more e619 +more_horiz e5d3 +more_vert e5d4 +motorcycle e91b +mouse e323 +move_to_inbox e168 +movie e02c +movie_creation e404 +movie_filter e43a +multiline_chart e6df +music_note e405 +music_video e063 +my_location e55c +nature e406 +nature_people e407 +navigate_before e408 +navigate_next e409 +navigation e55d +near_me e569 +network_cell e1b9 +network_check e640 +network_locked e61a +network_wifi e1ba +new_releases e031 +next_week e16a +nfc e1bb +no_encryption e641 +no_sim e0cc +not_interested e033 +note e06f +note_add e89c +notifications e7f4 +notifications_active e7f7 +notifications_none e7f5 +notifications_off e7f6 +notifications_paused e7f8 +offline_pin e90a +ondemand_video e63a +opacity e91c +open_in_browser e89d +open_in_new e89e +open_with e89f +pages e7f9 +pageview e8a0 +palette e40a +pan_tool e925 +panorama e40b +panorama_fish_eye e40c +panorama_horizontal e40d +panorama_vertical e40e +panorama_wide_angle e40f +party_mode e7fa +pause e034 +pause_circle_filled e035 +pause_circle_outline e036 +payment e8a1 +people e7fb +people_outline e7fc +perm_camera_mic e8a2 +perm_contact_calendar e8a3 +perm_data_setting e8a4 +perm_device_information e8a5 +perm_identity e8a6 +perm_media e8a7 +perm_phone_msg e8a8 +perm_scan_wifi e8a9 +person e7fd +person_add e7fe +person_outline e7ff +person_pin e55a +person_pin_circle e56a +personal_video e63b +pets e91d +phone e0cd +phone_android e324 +phone_bluetooth_speaker e61b +phone_forwarded e61c +phone_in_talk e61d +phone_iphone e325 +phone_locked e61e +phone_missed e61f +phone_paused e620 +phonelink e326 +phonelink_erase e0db +phonelink_lock e0dc +phonelink_off e327 +phonelink_ring e0dd +phonelink_setup e0de +photo e410 +photo_album e411 +photo_camera e412 +photo_filter e43b +photo_library e413 +photo_size_select_actual e432 +photo_size_select_large e433 +photo_size_select_small e434 +picture_as_pdf e415 +picture_in_picture e8aa +picture_in_picture_alt e911 +pie_chart e6c4 +pie_chart_outlined e6c5 +pin_drop e55e +place e55f +play_arrow e037 +play_circle_filled e038 +play_circle_outline e039 +play_for_work e906 +playlist_add e03b +playlist_add_check e065 +playlist_play e05f +plus_one e800 +poll e801 +polymer e8ab +pool eb48 +portable_wifi_off e0ce +portrait e416 +power e63c +power_input e336 +power_settings_new e8ac +pregnant_woman e91e +present_to_all e0df +print e8ad +priority_high e645 +public e80b +publish e255 +query_builder e8ae +question_answer e8af +queue e03c +queue_music e03d +queue_play_next e066 +radio e03e +radio_button_checked e837 +radio_button_unchecked e836 +rate_review e560 +receipt e8b0 +recent_actors e03f +record_voice_over e91f +redeem e8b1 +redo e15a +refresh e5d5 +remove e15b +remove_circle e15c +remove_circle_outline e15d +remove_from_queue e067 +remove_red_eye e417 +remove_shopping_cart e928 +reorder e8fe +repeat e040 +repeat_one e041 +replay e042 +replay_10 e059 +replay_30 e05a +replay_5 e05b +reply e15e +reply_all e15f +report e160 +report_problem e8b2 +restaurant e56c +restaurant_menu e561 +restore e8b3 +restore_page e929 +ring_volume e0d1 +room e8b4 +room_service eb49 +rotate_90_degrees_ccw e418 +rotate_left e419 +rotate_right e41a +rounded_corner e920 +router e328 +rowing e921 +rss_feed e0e5 +rv_hookup e642 +satellite e562 +save e161 +scanner e329 +schedule e8b5 +school e80c +screen_lock_landscape e1be +screen_lock_portrait e1bf +screen_lock_rotation e1c0 +screen_rotation e1c1 +screen_share e0e2 +sd_card e623 +sd_storage e1c2 +search e8b6 +security e32a +select_all e162 +send e163 +sentiment_dissatisfied e811 +sentiment_neutral e812 +sentiment_satisfied e813 +sentiment_very_dissatisfied e814 +sentiment_very_satisfied e815 +settings e8b8 +settings_applications e8b9 +settings_backup_restore e8ba +settings_bluetooth e8bb +settings_brightness e8bd +settings_cell e8bc +settings_ethernet e8be +settings_input_antenna e8bf +settings_input_component e8c0 +settings_input_composite e8c1 +settings_input_hdmi e8c2 +settings_input_svideo e8c3 +settings_overscan e8c4 +settings_phone e8c5 +settings_power e8c6 +settings_remote e8c7 +settings_system_daydream e1c3 +settings_voice e8c8 +share e80d +shop e8c9 +shop_two e8ca +shopping_basket e8cb +shopping_cart e8cc +short_text e261 +show_chart e6e1 +shuffle e043 +signal_cellular_4_bar e1c8 +signal_cellular_connected_no_internet_4_bar e1cd +signal_cellular_no_sim e1ce +signal_cellular_null e1cf +signal_cellular_off e1d0 +signal_wifi_4_bar e1d8 +signal_wifi_4_bar_lock e1d9 +signal_wifi_off e1da +sim_card e32b +sim_card_alert e624 +skip_next e044 +skip_previous e045 +slideshow e41b +slow_motion_video e068 +smartphone e32c +smoke_free eb4a +smoking_rooms eb4b +sms e625 +sms_failed e626 +snooze e046 +sort e164 +sort_by_alpha e053 +spa eb4c +space_bar e256 +speaker e32d +speaker_group e32e +speaker_notes e8cd +speaker_notes_off e92a +speaker_phone e0d2 +spellcheck e8ce +star e838 +star_border e83a +star_half e839 +stars e8d0 +stay_current_landscape e0d3 +stay_current_portrait e0d4 +stay_primary_landscape e0d5 +stay_primary_portrait e0d6 +stop e047 +stop_screen_share e0e3 +storage e1db +store e8d1 +store_mall_directory e563 +straighten e41c +streetview e56e +strikethrough_s e257 +style e41d +subdirectory_arrow_left e5d9 +subdirectory_arrow_right e5da +subject e8d2 +subscriptions e064 +subtitles e048 +subway e56f +supervisor_account e8d3 +surround_sound e049 +swap_calls e0d7 +swap_horiz e8d4 +swap_vert e8d5 +swap_vertical_circle e8d6 +switch_camera e41e +switch_video e41f +sync e627 +sync_disabled e628 +sync_problem e629 +system_update e62a +system_update_alt e8d7 +tab e8d8 +tab_unselected e8d9 +tablet e32f +tablet_android e330 +tablet_mac e331 +tag_faces e420 +tap_and_play e62b +terrain e564 +text_fields e262 +text_format e165 +textsms e0d8 +texture e421 +theaters e8da +thumb_down e8db +thumb_up e8dc +thumbs_up_down e8dd +time_to_leave e62c +timelapse e422 +timeline e922 +timer e425 +timer_10 e423 +timer_3 e424 +timer_off e426 +title e264 +toc e8de +today e8df +toll e8e0 +tonality e427 +touch_app e913 +toys e332 +track_changes e8e1 +traffic e565 +train e570 +tram e571 +transfer_within_a_station e572 +transform e428 +translate e8e2 +trending_down e8e3 +trending_flat e8e4 +trending_up e8e5 +tune e429 +turned_in e8e6 +turned_in_not e8e7 +tv e333 +unarchive e169 +undo e166 +unfold_less e5d6 +unfold_more e5d7 +update e923 +usb e1e0 +verified_user e8e8 +vertical_align_bottom e258 +vertical_align_center e259 +vertical_align_top e25a +vibration e62d +video_call e070 +video_label e071 +video_library e04a +videocam e04b +videocam_off e04c +videogame_asset e338 +view_agenda e8e9 +view_array e8ea +view_carousel e8eb +view_column e8ec +view_comfy e42a +view_compact e42b +view_day e8ed +view_headline e8ee +view_list e8ef +view_module e8f0 +view_quilt e8f1 +view_stream e8f2 +view_week e8f3 +vignette e435 +visibility e8f4 +visibility_off e8f5 +voice_chat e62e +voicemail e0d9 +volume_down e04d +volume_mute e04e +volume_off e04f +volume_up e050 +vpn_key e0da +vpn_lock e62f +wallpaper e1bc +warning e002 +watch e334 +watch_later e924 +wb_auto e42c +wb_cloudy e42d +wb_incandescent e42e +wb_iridescent e436 +wb_sunny e430 +wc e63d +web e051 +web_asset e069 +weekend e16b +whatshot e80e +widgets e1bd +wifi e63e +wifi_lock e1e1 +wifi_tethering e1e2 +work e8f9 +wrap_text e25b +youtube_searched_for e8fa +zoom_in e8ff +zoom_out e900 +zoom_out_map e56b diff --git a/MyOffice.SPA/src/assets/fonts/iconfont/material-icons.css b/MyOffice.SPA/src/assets/fonts/iconfont/material-icons.css new file mode 100644 index 0000000..83889eb --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/iconfont/material-icons.css @@ -0,0 +1,36 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local('Material Icons'), + local('MaterialIcons-Regular'), + url(MaterialIcons-Regular.woff2) format('woff2'), + url(MaterialIcons-Regular.woff) format('woff'), + url(MaterialIcons-Regular.ttf) format('truetype'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; /* Preferred icon size */ + display: inline-block; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + + /* Support for IE. */ + font-feature-settings: 'liga'; +} diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot new file mode 100644 index 0000000..ff32634 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg new file mode 100644 index 0000000..c3d485c --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf new file mode 100644 index 0000000..5f2caab Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff new file mode 100644 index 0000000..cfb9c3d Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 new file mode 100644 index 0000000..19f70c6 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/poppins/poppins-v5-latin-regular.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/css/simple-line-icons.css b/MyOffice.SPA/src/assets/fonts/simple-line-icons/css/simple-line-icons.css new file mode 100644 index 0000000..770bb99 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/simple-line-icons/css/simple-line-icons.css @@ -0,0 +1,573 @@ +@font-face { + font-family: 'simple-line-icons'; + src: url('../fonts/Simple-Line-Icons4c82.eot?-i3a2kk'); + src: url('../fonts/Simple-Line-Iconsd41d.eot?#iefix-i3a2kk') format('embedded-opentype'), url('../fonts/Simple-Line-Icons4c82.ttf?-i3a2kk') format('truetype'), url('../fonts/Simple-Line-Icons4c82.woff2?-i3a2kk') format('woff2'), url('../fonts/Simple-Line-Icons4c82.woff?-i3a2kk') format('woff'), url('../fonts/Simple-Line-Icons4c82.svg?-i3a2kk#simple-line-icons') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* + Use the following CSS code if you want to have a class per icon. + Instead of a list of all class selectors, you can use the generic [class*="icon-"] selector, but it's slower: +*/ + +.icon-user, +.icon-people, +.icon-user-female, +.icon-user-follow, +.icon-user-following, +.icon-user-unfollow, +.icon-login, +.icon-logout, +.icon-emotsmile, +.icon-phone, +.icon-call-end, +.icon-call-in, +.icon-call-out, +.icon-map, +.icon-location-pin, +.icon-direction, +.icon-directions, +.icon-compass, +.icon-layers, +.icon-menu, +.icon-list, +.icon-options-vertical, +.icon-options, +.icon-arrow-down, +.icon-arrow-left, +.icon-arrow-right, +.icon-arrow-up, +.icon-arrow-up-circle, +.icon-arrow-left-circle, +.icon-arrow-right-circle, +.icon-arrow-down-circle, +.icon-check, +.icon-clock, +.icon-plus, +.icon-close, +.icon-trophy, +.icon-screen-smartphone, +.icon-screen-desktop, +.icon-plane, +.icon-notebook, +.icon-mustache, +.icon-mouse, +.icon-magnet, +.icon-energy, +.icon-disc, +.icon-cursor, +.icon-cursor-move, +.icon-crop, +.icon-chemistry, +.icon-speedometer, +.icon-shield, +.icon-screen-tablet, +.icon-magic-wand, +.icon-hourglass, +.icon-graduation, +.icon-ghost, +.icon-game-controller, +.icon-fire, +.icon-eyeglass, +.icon-envelope-open, +.icon-envelope-letter, +.icon-bell, +.icon-badge, +.icon-anchor, +.icon-wallet, +.icon-vector, +.icon-speech, +.icon-puzzle, +.icon-printer, +.icon-present, +.icon-playlist, +.icon-pin, +.icon-picture, +.icon-handbag, +.icon-globe-alt, +.icon-globe, +.icon-folder-alt, +.icon-folder, +.icon-film, +.icon-feed, +.icon-drop, +.icon-drawar, +.icon-docs, +.icon-doc, +.icon-diamond, +.icon-cup, +.icon-calculator, +.icon-bubbles, +.icon-briefcase, +.icon-book-open, +.icon-basket-loaded, +.icon-basket, +.icon-bag, +.icon-action-undo, +.icon-action-redo, +.icon-wrench, +.icon-umbrella, +.icon-trash, +.icon-tag, +.icon-support, +.icon-frame, +.icon-size-fullscreen, +.icon-size-actual, +.icon-shuffle, +.icon-share-alt, +.icon-share, +.icon-rocket, +.icon-question, +.icon-pie-chart, +.icon-pencil, +.icon-note, +.icon-loop, +.icon-home, +.icon-grid, +.icon-graph, +.icon-microphone, +.icon-music-tone-alt, +.icon-music-tone, +.icon-earphones-alt, +.icon-earphones, +.icon-equalizer, +.icon-like, +.icon-dislike, +.icon-control-start, +.icon-control-rewind, +.icon-control-play, +.icon-control-pause, +.icon-control-forward, +.icon-control-end, +.icon-volume-1, +.icon-volume-2, +.icon-volume-off, +.icon-calender, +.icon-bulb, +.icon-chart, +.icon-ban, +.icon-bubble, +.icon-camrecorder, +.icon-camera, +.icon-cloud-download, +.icon-cloud-upload, +.icon-envelope, +.icon-eye, +.icon-flag, +.icon-heart, +.icon-info, +.icon-key, +.icon-link, +.icon-lock, +.icon-lock-open, +.icon-magnifier, +.icon-magnifier-add, +.icon-magnifier-remove, +.icon-paper-clip, +.icon-paper-plane, +.icon-power, +.icon-refresh, +.icon-reload, +.icon-settings, +.icon-star, +.icon-symble-female, +.icon-symbol-male, +.icon-target, +.icon-credit-card, +.icon-paypal, +.icon-social-tumblr, +.icon-social-twitter, +.icon-social-facebook, +.icon-social-instagram, +.icon-social-linkedin, +.icon-social-pintarest, +.icon-social-github, +.icon-social-gplus, +.icon-social-reddit, +.icon-social-skype, +.icon-social-dribbble, +.icon-social-behance, +.icon-social-foursqare, +.icon-social-soundcloud, +.icon-social-spotify, +.icon-social-stumbleupon, +.icon-social-youtube, +.icon-social-dropbox { + font-family: 'simple-line-icons'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-user:before { content: "\e005"; } + +.icon-people:before { content: "\e001"; } + +.icon-user-female:before { content: "\e000"; } + +.icon-user-follow:before { content: "\e002"; } + +.icon-user-following:before { content: "\e003"; } + +.icon-user-unfollow:before { content: "\e004"; } + +.icon-login:before { content: "\e066"; } + +.icon-logout:before { content: "\e065"; } + +.icon-emotsmile:before { content: "\e021"; } + +.icon-phone:before { content: "\e600"; } + +.icon-call-end:before { content: "\e048"; } + +.icon-call-in:before { content: "\e047"; } + +.icon-call-out:before { content: "\e046"; } + +.icon-map:before { content: "\e033"; } + +.icon-location-pin:before { content: "\e096"; } + +.icon-direction:before { content: "\e042"; } + +.icon-directions:before { content: "\e041"; } + +.icon-compass:before { content: "\e045"; } + +.icon-layers:before { content: "\e034"; } + +.icon-menu:before { content: "\e601"; } + +.icon-list:before { content: "\e067"; } + +.icon-options-vertical:before { content: "\e602"; } + +.icon-options:before { content: "\e603"; } + +.icon-arrow-down:before { content: "\e604"; } + +.icon-arrow-left:before { content: "\e605"; } + +.icon-arrow-right:before { content: "\e606"; } + +.icon-arrow-up:before { content: "\e607"; } + +.icon-arrow-up-circle:before { content: "\e078"; } + +.icon-arrow-left-circle:before { content: "\e07a"; } + +.icon-arrow-right-circle:before { content: "\e079"; } + +.icon-arrow-down-circle:before { content: "\e07b"; } + +.icon-check:before { content: "\e080"; } + +.icon-clock:before { content: "\e081"; } + +.icon-plus:before { content: "\e095"; } + +.icon-close:before { content: "\e082"; } + +.icon-trophy:before { content: "\e006"; } + +.icon-screen-smartphone:before { content: "\e010"; } + +.icon-screen-desktop:before { content: "\e011"; } + +.icon-plane:before { content: "\e012"; } + +.icon-notebook:before { content: "\e013"; } + +.icon-mustache:before { content: "\e014"; } + +.icon-mouse:before { content: "\e015"; } + +.icon-magnet:before { content: "\e016"; } + +.icon-energy:before { content: "\e020"; } + +.icon-disc:before { content: "\e022"; } + +.icon-cursor:before { content: "\e06e"; } + +.icon-cursor-move:before { content: "\e023"; } + +.icon-crop:before { content: "\e024"; } + +.icon-chemistry:before { content: "\e026"; } + +.icon-speedometer:before { content: "\e007"; } + +.icon-shield:before { content: "\e00e"; } + +.icon-screen-tablet:before { content: "\e00f"; } + +.icon-magic-wand:before { content: "\e017"; } + +.icon-hourglass:before { content: "\e018"; } + +.icon-graduation:before { content: "\e019"; } + +.icon-ghost:before { content: "\e01a"; } + +.icon-game-controller:before { content: "\e01b"; } + +.icon-fire:before { content: "\e01c"; } + +.icon-eyeglass:before { content: "\e01d"; } + +.icon-envelope-open:before { content: "\e01e"; } + +.icon-envelope-letter:before { content: "\e01f"; } + +.icon-bell:before { content: "\e027"; } + +.icon-badge:before { content: "\e028"; } + +.icon-anchor:before { content: "\e029"; } + +.icon-wallet:before { content: "\e02a"; } + +.icon-vector:before { content: "\e02b"; } + +.icon-speech:before { content: "\e02c"; } + +.icon-puzzle:before { content: "\e02d"; } + +.icon-printer:before { content: "\e02e"; } + +.icon-present:before { content: "\e02f"; } + +.icon-playlist:before { content: "\e030"; } + +.icon-pin:before { content: "\e031"; } + +.icon-picture:before { content: "\e032"; } + +.icon-handbag:before { content: "\e035"; } + +.icon-globe-alt:before { content: "\e036"; } + +.icon-globe:before { content: "\e037"; } + +.icon-folder-alt:before { content: "\e039"; } + +.icon-folder:before { content: "\e089"; } + +.icon-film:before { content: "\e03a"; } + +.icon-feed:before { content: "\e03b"; } + +.icon-drop:before { content: "\e03e"; } + +.icon-drawar:before { content: "\e03f"; } + +.icon-docs:before { content: "\e040"; } + +.icon-doc:before { content: "\e085"; } + +.icon-diamond:before { content: "\e043"; } + +.icon-cup:before { content: "\e044"; } + +.icon-calculator:before { content: "\e049"; } + +.icon-bubbles:before { content: "\e04a"; } + +.icon-briefcase:before { content: "\e04b"; } + +.icon-book-open:before { content: "\e04c"; } + +.icon-basket-loaded:before { content: "\e04d"; } + +.icon-basket:before { content: "\e04e"; } + +.icon-bag:before { content: "\e04f"; } + +.icon-action-undo:before { content: "\e050"; } + +.icon-action-redo:before { content: "\e051"; } + +.icon-wrench:before { content: "\e052"; } + +.icon-umbrella:before { content: "\e053"; } + +.icon-trash:before { content: "\e054"; } + +.icon-tag:before { content: "\e055"; } + +.icon-support:before { content: "\e056"; } + +.icon-frame:before { content: "\e038"; } + +.icon-size-fullscreen:before { content: "\e057"; } + +.icon-size-actual:before { content: "\e058"; } + +.icon-shuffle:before { content: "\e059"; } + +.icon-share-alt:before { content: "\e05a"; } + +.icon-share:before { content: "\e05b"; } + +.icon-rocket:before { content: "\e05c"; } + +.icon-question:before { content: "\e05d"; } + +.icon-pie-chart:before { content: "\e05e"; } + +.icon-pencil:before { content: "\e05f"; } + +.icon-note:before { content: "\e060"; } + +.icon-loop:before { content: "\e064"; } + +.icon-home:before { content: "\e069"; } + +.icon-grid:before { content: "\e06a"; } + +.icon-graph:before { content: "\e06b"; } + +.icon-microphone:before { content: "\e063"; } + +.icon-music-tone-alt:before { content: "\e061"; } + +.icon-music-tone:before { content: "\e062"; } + +.icon-earphones-alt:before { content: "\e03c"; } + +.icon-earphones:before { content: "\e03d"; } + +.icon-equalizer:before { content: "\e06c"; } + +.icon-like:before { content: "\e068"; } + +.icon-dislike:before { content: "\e06d"; } + +.icon-control-start:before { content: "\e06f"; } + +.icon-control-rewind:before { content: "\e070"; } + +.icon-control-play:before { content: "\e071"; } + +.icon-control-pause:before { content: "\e072"; } + +.icon-control-forward:before { content: "\e073"; } + +.icon-control-end:before { content: "\e074"; } + +.icon-volume-1:before { content: "\e09f"; } + +.icon-volume-2:before { content: "\e0a0"; } + +.icon-volume-off:before { content: "\e0a1"; } + +.icon-calender:before { content: "\e075"; } + +.icon-bulb:before { content: "\e076"; } + +.icon-chart:before { content: "\e077"; } + +.icon-ban:before { content: "\e07c"; } + +.icon-bubble:before { content: "\e07d"; } + +.icon-camrecorder:before { content: "\e07e"; } + +.icon-camera:before { content: "\e07f"; } + +.icon-cloud-download:before { content: "\e083"; } + +.icon-cloud-upload:before { content: "\e084"; } + +.icon-envelope:before { content: "\e086"; } + +.icon-eye:before { content: "\e087"; } + +.icon-flag:before { content: "\e088"; } + +.icon-heart:before { content: "\e08a"; } + +.icon-info:before { content: "\e08b"; } + +.icon-key:before { content: "\e08c"; } + +.icon-link:before { content: "\e08d"; } + +.icon-lock:before { content: "\e08e"; } + +.icon-lock-open:before { content: "\e08f"; } + +.icon-magnifier:before { content: "\e090"; } + +.icon-magnifier-add:before { content: "\e091"; } + +.icon-magnifier-remove:before { content: "\e092"; } + +.icon-paper-clip:before { content: "\e093"; } + +.icon-paper-plane:before { content: "\e094"; } + +.icon-power:before { content: "\e097"; } + +.icon-refresh:before { content: "\e098"; } + +.icon-reload:before { content: "\e099"; } + +.icon-settings:before { content: "\e09a"; } + +.icon-star:before { content: "\e09b"; } + +.icon-symble-female:before { content: "\e09c"; } + +.icon-symbol-male:before { content: "\e09d"; } + +.icon-target:before { content: "\e09e"; } + +.icon-credit-card:before { content: "\e025"; } + +.icon-paypal:before { content: "\e608"; } + +.icon-social-tumblr:before { content: "\e00a"; } + +.icon-social-twitter:before { content: "\e009"; } + +.icon-social-facebook:before { content: "\e00b"; } + +.icon-social-instagram:before { content: "\e609"; } + +.icon-social-linkedin:before { content: "\e60a"; } + +.icon-social-pintarest:before { content: "\e60b"; } + +.icon-social-github:before { content: "\e60c"; } + +.icon-social-gplus:before { content: "\e60d"; } + +.icon-social-reddit:before { content: "\e60e"; } + +.icon-social-skype:before { content: "\e60f"; } + +.icon-social-dribbble:before { content: "\e00d"; } + +.icon-social-behance:before { content: "\e610"; } + +.icon-social-foursqare:before { content: "\e611"; } + +.icon-social-soundcloud:before { content: "\e612"; } + +.icon-social-spotify:before { content: "\e613"; } + +.icon-social-stumbleupon:before { content: "\e614"; } + +.icon-social-youtube:before { content: "\e008"; } + +.icon-social-dropbox:before { content: "\e00c"; } diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.eot b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.eot new file mode 100644 index 0000000..533fd7f Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.svg b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.svg new file mode 100644 index 0000000..bed0f14 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.svg @@ -0,0 +1,211 @@ + + + + + + +{ + "fontFamily": "simple-line-icons", + "majorVersion": 2, + "minorVersion": 0, + "license": "MIT", + "designer": "Jamal Jama, Ahmad Firoz", + "version": "Version 2.0", + "fontId": "simple-line-icons", + "psName": "simple-line-icons", + "subFamily": "Regular", + "fullName": "simple-line-icons", + "description": "Font generated by IcoMoon." +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.ttf b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.ttf new file mode 100644 index 0000000..ecf85a4 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff new file mode 100644 index 0000000..b38250d Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff2 b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff2 new file mode 100644 index 0000000..ec9373a Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Icons4c82.woff2 differ diff --git a/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Iconsd41d.eot b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Iconsd41d.eot new file mode 100644 index 0000000..533fd7f Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/simple-line-icons/fonts/Simple-Line-Iconsd41d.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.ttf b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.ttf new file mode 100644 index 0000000..5d627e7 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.ttf differ diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.woff b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.woff new file mode 100644 index 0000000..847ebd1 Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify.woff differ diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.eot b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.eot new file mode 100644 index 0000000..9ec298b Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.svg b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.svg new file mode 100644 index 0000000..3d53854 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themify9f24.svg @@ -0,0 +1,362 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themifyd41d.eot b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themifyd41d.eot new file mode 100644 index 0000000..9ec298b Binary files /dev/null and b/MyOffice.SPA/src/assets/fonts/themify-icons/fonts/themifyd41d.eot differ diff --git a/MyOffice.SPA/src/assets/fonts/themify-icons/themify-icons.css b/MyOffice.SPA/src/assets/fonts/themify-icons/themify-icons.css new file mode 100644 index 0000000..fbaf606 --- /dev/null +++ b/MyOffice.SPA/src/assets/fonts/themify-icons/themify-icons.css @@ -0,0 +1,728 @@ +@font-face { + font-family: 'themify'; + src: url('fonts/themify9f24.eot?-fvbane'); + src: url('fonts/themifyd41d.eot?#iefix-fvbane') format('embedded-opentype'), + url('fonts/themify.woff') format('woff'), + url('fonts/themify.ttf') format('truetype'), + url('fonts/themify9f24.svg?-fvbane#themify') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="ti-"], [class*=" ti-"] { + font-family: 'themify'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.ti-wand:before { content: "\e600"; } + +.ti-volume:before { content: "\e601"; } + +.ti-user:before { content: "\e602"; } + +.ti-unlock:before { content: "\e603"; } + +.ti-unlink:before { content: "\e604"; } + +.ti-trash:before { content: "\e605"; } + +.ti-thought:before { content: "\e606"; } + +.ti-target:before { content: "\e607"; } + +.ti-tag:before { content: "\e608"; } + +.ti-tablet:before { content: "\e609"; } + +.ti-star:before { content: "\e60a"; } + +.ti-spray:before { content: "\e60b"; } + +.ti-signal:before { content: "\e60c"; } + +.ti-shopping-cart:before { content: "\e60d"; } + +.ti-shopping-cart-full:before { content: "\e60e"; } + +.ti-settings:before { content: "\e60f"; } + +.ti-search:before { content: "\e610"; } + +.ti-zoom-in:before { content: "\e611"; } + +.ti-zoom-out:before { content: "\e612"; } + +.ti-cut:before { content: "\e613"; } + +.ti-ruler:before { content: "\e614"; } + +.ti-ruler-pencil:before { content: "\e615"; } + +.ti-ruler-alt:before { content: "\e616"; } + +.ti-bookmark:before { content: "\e617"; } + +.ti-bookmark-alt:before { content: "\e618"; } + +.ti-reload:before { content: "\e619"; } + +.ti-plus:before { content: "\e61a"; } + +.ti-pin:before { content: "\e61b"; } + +.ti-pencil:before { content: "\e61c"; } + +.ti-pencil-alt:before { content: "\e61d"; } + +.ti-paint-roller:before { content: "\e61e"; } + +.ti-paint-bucket:before { content: "\e61f"; } + +.ti-na:before { content: "\e620"; } + +.ti-mobile:before { content: "\e621"; } + +.ti-minus:before { content: "\e622"; } + +.ti-medall:before { content: "\e623"; } + +.ti-medall-alt:before { content: "\e624"; } + +.ti-marker:before { content: "\e625"; } + +.ti-marker-alt:before { content: "\e626"; } + +.ti-arrow-up:before { content: "\e627"; } + +.ti-arrow-right:before { content: "\e628"; } + +.ti-arrow-left:before { content: "\e629"; } + +.ti-arrow-down:before { content: "\e62a"; } + +.ti-lock:before { content: "\e62b"; } + +.ti-location-arrow:before { content: "\e62c"; } + +.ti-link:before { content: "\e62d"; } + +.ti-layout:before { content: "\e62e"; } + +.ti-layers:before { content: "\e62f"; } + +.ti-layers-alt:before { content: "\e630"; } + +.ti-key:before { content: "\e631"; } + +.ti-import:before { content: "\e632"; } + +.ti-image:before { content: "\e633"; } + +.ti-heart:before { content: "\e634"; } + +.ti-heart-broken:before { content: "\e635"; } + +.ti-hand-stop:before { content: "\e636"; } + +.ti-hand-open:before { content: "\e637"; } + +.ti-hand-drag:before { content: "\e638"; } + +.ti-folder:before { content: "\e639"; } + +.ti-flag:before { content: "\e63a"; } + +.ti-flag-alt:before { content: "\e63b"; } + +.ti-flag-alt-2:before { content: "\e63c"; } + +.ti-eye:before { content: "\e63d"; } + +.ti-export:before { content: "\e63e"; } + +.ti-exchange-vertical:before { content: "\e63f"; } + +.ti-desktop:before { content: "\e640"; } + +.ti-cup:before { content: "\e641"; } + +.ti-crown:before { content: "\e642"; } + +.ti-comments:before { content: "\e643"; } + +.ti-comment:before { content: "\e644"; } + +.ti-comment-alt:before { content: "\e645"; } + +.ti-close:before { content: "\e646"; } + +.ti-clip:before { content: "\e647"; } + +.ti-angle-up:before { content: "\e648"; } + +.ti-angle-right:before { content: "\e649"; } + +.ti-angle-left:before { content: "\e64a"; } + +.ti-angle-down:before { content: "\e64b"; } + +.ti-check:before { content: "\e64c"; } + +.ti-check-box:before { content: "\e64d"; } + +.ti-camera:before { content: "\e64e"; } + +.ti-announcement:before { content: "\e64f"; } + +.ti-brush:before { content: "\e650"; } + +.ti-briefcase:before { content: "\e651"; } + +.ti-bolt:before { content: "\e652"; } + +.ti-bolt-alt:before { content: "\e653"; } + +.ti-blackboard:before { content: "\e654"; } + +.ti-bag:before { content: "\e655"; } + +.ti-move:before { content: "\e656"; } + +.ti-arrows-vertical:before { content: "\e657"; } + +.ti-arrows-horizontal:before { content: "\e658"; } + +.ti-fullscreen:before { content: "\e659"; } + +.ti-arrow-top-right:before { content: "\e65a"; } + +.ti-arrow-top-left:before { content: "\e65b"; } + +.ti-arrow-circle-up:before { content: "\e65c"; } + +.ti-arrow-circle-right:before { content: "\e65d"; } + +.ti-arrow-circle-left:before { content: "\e65e"; } + +.ti-arrow-circle-down:before { content: "\e65f"; } + +.ti-angle-double-up:before { content: "\e660"; } + +.ti-angle-double-right:before { content: "\e661"; } + +.ti-angle-double-left:before { content: "\e662"; } + +.ti-angle-double-down:before { content: "\e663"; } + +.ti-zip:before { content: "\e664"; } + +.ti-world:before { content: "\e665"; } + +.ti-wheelchair:before { content: "\e666"; } + +.ti-view-list:before { content: "\e667"; } + +.ti-view-list-alt:before { content: "\e668"; } + +.ti-view-grid:before { content: "\e669"; } + +.ti-uppercase:before { content: "\e66a"; } + +.ti-upload:before { content: "\e66b"; } + +.ti-underline:before { content: "\e66c"; } + +.ti-truck:before { content: "\e66d"; } + +.ti-timer:before { content: "\e66e"; } + +.ti-ticket:before { content: "\e66f"; } + +.ti-thumb-up:before { content: "\e670"; } + +.ti-thumb-down:before { content: "\e671"; } + +.ti-text:before { content: "\e672"; } + +.ti-stats-up:before { content: "\e673"; } + +.ti-stats-down:before { content: "\e674"; } + +.ti-split-v:before { content: "\e675"; } + +.ti-split-h:before { content: "\e676"; } + +.ti-smallcap:before { content: "\e677"; } + +.ti-shine:before { content: "\e678"; } + +.ti-shift-right:before { content: "\e679"; } + +.ti-shift-left:before { content: "\e67a"; } + +.ti-shield:before { content: "\e67b"; } + +.ti-notepad:before { content: "\e67c"; } + +.ti-server:before { content: "\e67d"; } + +.ti-quote-right:before { content: "\e67e"; } + +.ti-quote-left:before { content: "\e67f"; } + +.ti-pulse:before { content: "\e680"; } + +.ti-printer:before { content: "\e681"; } + +.ti-power-off:before { content: "\e682"; } + +.ti-plug:before { content: "\e683"; } + +.ti-pie-chart:before { content: "\e684"; } + +.ti-paragraph:before { content: "\e685"; } + +.ti-panel:before { content: "\e686"; } + +.ti-package:before { content: "\e687"; } + +.ti-music:before { content: "\e688"; } + +.ti-music-alt:before { content: "\e689"; } + +.ti-mouse:before { content: "\e68a"; } + +.ti-mouse-alt:before { content: "\e68b"; } + +.ti-money:before { content: "\e68c"; } + +.ti-microphone:before { content: "\e68d"; } + +.ti-menu:before { content: "\e68e"; } + +.ti-menu-alt:before { content: "\e68f"; } + +.ti-map:before { content: "\e690"; } + +.ti-map-alt:before { content: "\e691"; } + +.ti-loop:before { content: "\e692"; } + +.ti-location-pin:before { content: "\e693"; } + +.ti-list:before { content: "\e694"; } + +.ti-light-bulb:before { content: "\e695"; } + +.ti-Italic:before { content: "\e696"; } + +.ti-info:before { content: "\e697"; } + +.ti-infinite:before { content: "\e698"; } + +.ti-id-badge:before { content: "\e699"; } + +.ti-hummer:before { content: "\e69a"; } + +.ti-home:before { content: "\e69b"; } + +.ti-help:before { content: "\e69c"; } + +.ti-headphone:before { content: "\e69d"; } + +.ti-harddrives:before { content: "\e69e"; } + +.ti-harddrive:before { content: "\e69f"; } + +.ti-gift:before { content: "\e6a0"; } + +.ti-game:before { content: "\e6a1"; } + +.ti-filter:before { content: "\e6a2"; } + +.ti-files:before { content: "\e6a3"; } + +.ti-file:before { content: "\e6a4"; } + +.ti-eraser:before { content: "\e6a5"; } + +.ti-envelope:before { content: "\e6a6"; } + +.ti-download:before { content: "\e6a7"; } + +.ti-direction:before { content: "\e6a8"; } + +.ti-direction-alt:before { content: "\e6a9"; } + +.ti-dashboard:before { content: "\e6aa"; } + +.ti-control-stop:before { content: "\e6ab"; } + +.ti-control-shuffle:before { content: "\e6ac"; } + +.ti-control-play:before { content: "\e6ad"; } + +.ti-control-pause:before { content: "\e6ae"; } + +.ti-control-forward:before { content: "\e6af"; } + +.ti-control-backward:before { content: "\e6b0"; } + +.ti-cloud:before { content: "\e6b1"; } + +.ti-cloud-up:before { content: "\e6b2"; } + +.ti-cloud-down:before { content: "\e6b3"; } + +.ti-clipboard:before { content: "\e6b4"; } + +.ti-car:before { content: "\e6b5"; } + +.ti-calendar:before { content: "\e6b6"; } + +.ti-book:before { content: "\e6b7"; } + +.ti-bell:before { content: "\e6b8"; } + +.ti-basketball:before { content: "\e6b9"; } + +.ti-bar-chart:before { content: "\e6ba"; } + +.ti-bar-chart-alt:before { content: "\e6bb"; } + +.ti-back-right:before { content: "\e6bc"; } + +.ti-back-left:before { content: "\e6bd"; } + +.ti-arrows-corner:before { content: "\e6be"; } + +.ti-archive:before { content: "\e6bf"; } + +.ti-anchor:before { content: "\e6c0"; } + +.ti-align-right:before { content: "\e6c1"; } + +.ti-align-left:before { content: "\e6c2"; } + +.ti-align-justify:before { content: "\e6c3"; } + +.ti-align-center:before { content: "\e6c4"; } + +.ti-alert:before { content: "\e6c5"; } + +.ti-alarm-clock:before { content: "\e6c6"; } + +.ti-agenda:before { content: "\e6c7"; } + +.ti-write:before { content: "\e6c8"; } + +.ti-window:before { content: "\e6c9"; } + +.ti-widgetized:before { content: "\e6ca"; } + +.ti-widget:before { content: "\e6cb"; } + +.ti-widget-alt:before { content: "\e6cc"; } + +.ti-wallet:before { content: "\e6cd"; } + +.ti-video-clapper:before { content: "\e6ce"; } + +.ti-video-camera:before { content: "\e6cf"; } + +.ti-vector:before { content: "\e6d0"; } + +.ti-themify-logo:before { content: "\e6d1"; } + +.ti-themify-favicon:before { content: "\e6d2"; } + +.ti-themify-favicon-alt:before { content: "\e6d3"; } + +.ti-support:before { content: "\e6d4"; } + +.ti-stamp:before { content: "\e6d5"; } + +.ti-split-v-alt:before { content: "\e6d6"; } + +.ti-slice:before { content: "\e6d7"; } + +.ti-shortcode:before { content: "\e6d8"; } + +.ti-shift-right-alt:before { content: "\e6d9"; } + +.ti-shift-left-alt:before { content: "\e6da"; } + +.ti-ruler-alt-2:before { content: "\e6db"; } + +.ti-receipt:before { content: "\e6dc"; } + +.ti-pin2:before { content: "\e6dd"; } + +.ti-pin-alt:before { content: "\e6de"; } + +.ti-pencil-alt2:before { content: "\e6df"; } + +.ti-palette:before { content: "\e6e0"; } + +.ti-more:before { content: "\e6e1"; } + +.ti-more-alt:before { content: "\e6e2"; } + +.ti-microphone-alt:before { content: "\e6e3"; } + +.ti-magnet:before { content: "\e6e4"; } + +.ti-line-double:before { content: "\e6e5"; } + +.ti-line-dotted:before { content: "\e6e6"; } + +.ti-line-dashed:before { content: "\e6e7"; } + +.ti-layout-width-full:before { content: "\e6e8"; } + +.ti-layout-width-default:before { content: "\e6e9"; } + +.ti-layout-width-default-alt:before { content: "\e6ea"; } + +.ti-layout-tab:before { content: "\e6eb"; } + +.ti-layout-tab-window:before { content: "\e6ec"; } + +.ti-layout-tab-v:before { content: "\e6ed"; } + +.ti-layout-tab-min:before { content: "\e6ee"; } + +.ti-layout-slider:before { content: "\e6ef"; } + +.ti-layout-slider-alt:before { content: "\e6f0"; } + +.ti-layout-sidebar-right:before { content: "\e6f1"; } + +.ti-layout-sidebar-none:before { content: "\e6f2"; } + +.ti-layout-sidebar-left:before { content: "\e6f3"; } + +.ti-layout-placeholder:before { content: "\e6f4"; } + +.ti-layout-menu:before { content: "\e6f5"; } + +.ti-layout-menu-v:before { content: "\e6f6"; } + +.ti-layout-menu-separated:before { content: "\e6f7"; } + +.ti-layout-menu-full:before { content: "\e6f8"; } + +.ti-layout-media-right-alt:before { content: "\e6f9"; } + +.ti-layout-media-right:before { content: "\e6fa"; } + +.ti-layout-media-overlay:before { content: "\e6fb"; } + +.ti-layout-media-overlay-alt:before { content: "\e6fc"; } + +.ti-layout-media-overlay-alt-2:before { content: "\e6fd"; } + +.ti-layout-media-left-alt:before { content: "\e6fe"; } + +.ti-layout-media-left:before { content: "\e6ff"; } + +.ti-layout-media-center-alt:before { content: "\e700"; } + +.ti-layout-media-center:before { content: "\e701"; } + +.ti-layout-list-thumb:before { content: "\e702"; } + +.ti-layout-list-thumb-alt:before { content: "\e703"; } + +.ti-layout-list-post:before { content: "\e704"; } + +.ti-layout-list-large-image:before { content: "\e705"; } + +.ti-layout-line-solid:before { content: "\e706"; } + +.ti-layout-grid4:before { content: "\e707"; } + +.ti-layout-grid3:before { content: "\e708"; } + +.ti-layout-grid2:before { content: "\e709"; } + +.ti-layout-grid2-thumb:before { content: "\e70a"; } + +.ti-layout-cta-right:before { content: "\e70b"; } + +.ti-layout-cta-left:before { content: "\e70c"; } + +.ti-layout-cta-center:before { content: "\e70d"; } + +.ti-layout-cta-btn-right:before { content: "\e70e"; } + +.ti-layout-cta-btn-left:before { content: "\e70f"; } + +.ti-layout-column4:before { content: "\e710"; } + +.ti-layout-column3:before { content: "\e711"; } + +.ti-layout-column2:before { content: "\e712"; } + +.ti-layout-accordion-separated:before { content: "\e713"; } + +.ti-layout-accordion-merged:before { content: "\e714"; } + +.ti-layout-accordion-list:before { content: "\e715"; } + +.ti-ink-pen:before { content: "\e716"; } + +.ti-info-alt:before { content: "\e717"; } + +.ti-help-alt:before { content: "\e718"; } + +.ti-headphone-alt:before { content: "\e719"; } + +.ti-hand-point-up:before { content: "\e71a"; } + +.ti-hand-point-right:before { content: "\e71b"; } + +.ti-hand-point-left:before { content: "\e71c"; } + +.ti-hand-point-down:before { content: "\e71d"; } + +.ti-gallery:before { content: "\e71e"; } + +.ti-face-smile:before { content: "\e71f"; } + +.ti-face-sad:before { content: "\e720"; } + +.ti-credit-card:before { content: "\e721"; } + +.ti-control-skip-forward:before { content: "\e722"; } + +.ti-control-skip-backward:before { content: "\e723"; } + +.ti-control-record:before { content: "\e724"; } + +.ti-control-eject:before { content: "\e725"; } + +.ti-comments-smiley:before { content: "\e726"; } + +.ti-brush-alt:before { content: "\e727"; } + +.ti-youtube:before { content: "\e728"; } + +.ti-vimeo:before { content: "\e729"; } + +.ti-twitter:before { content: "\e72a"; } + +.ti-time:before { content: "\e72b"; } + +.ti-tumblr:before { content: "\e72c"; } + +.ti-skype:before { content: "\e72d"; } + +.ti-share:before { content: "\e72e"; } + +.ti-share-alt:before { content: "\e72f"; } + +.ti-rocket:before { content: "\e730"; } + +.ti-pinterest:before { content: "\e731"; } + +.ti-new-window:before { content: "\e732"; } + +.ti-microsoft:before { content: "\e733"; } + +.ti-list-ol:before { content: "\e734"; } + +.ti-linkedin:before { content: "\e735"; } + +.ti-layout-sidebar-2:before { content: "\e736"; } + +.ti-layout-grid4-alt:before { content: "\e737"; } + +.ti-layout-grid3-alt:before { content: "\e738"; } + +.ti-layout-grid2-alt:before { content: "\e739"; } + +.ti-layout-column4-alt:before { content: "\e73a"; } + +.ti-layout-column3-alt:before { content: "\e73b"; } + +.ti-layout-column2-alt:before { content: "\e73c"; } + +.ti-instagram:before { content: "\e73d"; } + +.ti-google:before { content: "\e73e"; } + +.ti-github:before { content: "\e73f"; } + +.ti-flickr:before { content: "\e740"; } + +.ti-facebook:before { content: "\e741"; } + +.ti-dropbox:before { content: "\e742"; } + +.ti-dribbble:before { content: "\e743"; } + +.ti-apple:before { content: "\e744"; } + +.ti-android:before { content: "\e745"; } + +.ti-save:before { content: "\e746"; } + +.ti-save-alt:before { content: "\e747"; } + +.ti-yahoo:before { content: "\e748"; } + +.ti-wordpress:before { content: "\e749"; } + +.ti-vimeo-alt:before { content: "\e74a"; } + +.ti-twitter-alt:before { content: "\e74b"; } + +.ti-tumblr-alt:before { content: "\e74c"; } + +.ti-trello:before { content: "\e74d"; } + +.ti-stack-overflow:before { content: "\e74e"; } + +.ti-soundcloud:before { content: "\e74f"; } + +.ti-sharethis:before { content: "\e750"; } + +.ti-sharethis-alt:before { content: "\e751"; } + +.ti-reddit:before { content: "\e752"; } + +.ti-pinterest-alt:before { content: "\e753"; } + +.ti-microsoft-alt:before { content: "\e754"; } + +.ti-linux:before { content: "\e755"; } + +.ti-jsfiddle:before { content: "\e756"; } + +.ti-joomla:before { content: "\e757"; } + +.ti-html5:before { content: "\e758"; } + +.ti-flickr-alt:before { content: "\e759"; } + +.ti-email:before { content: "\e75a"; } + +.ti-drupal:before { content: "\e75b"; } + +.ti-dropbox-alt:before { content: "\e75c"; } + +.ti-css3:before { content: "\e75d"; } + +.ti-rss:before { content: "\e75e"; } + +.ti-rss-alt:before { content: "\e75f"; } diff --git a/MyOffice.SPA/src/assets/i18n/de.json b/MyOffice.SPA/src/assets/i18n/de.json new file mode 100644 index 0000000..e828ce0 --- /dev/null +++ b/MyOffice.SPA/src/assets/i18n/de.json @@ -0,0 +1,84 @@ +{ + "HEADER": { + "SEARCH": { + "TEXT": "Suche.." + } + }, + "MENUITEMS": { + "USER": { + "POST": "Manager" + }, + "MAIN": { + "TEXT": "Main" + }, + "DASHBOARD": { + "TEXT": "Zuhause", + "LIST": { + "DASHBOARD1": "Dashboard 1", + "DASHBOARD2": "Dashboard 2", + "DASHBOARD3": "Dashboard 3" + } + }, + "ADVANCE-TABLE": { + "TEXT": "Vorab-Tabelle" + }, + "APPS": { + "TEXT": "Apps" + }, + "CALENDAR": { + "TEXT": "Kalender" + }, + "TASK": { + "TEXT": "Aufgabe" + }, + "CONTACTS": { + "TEXT": "Kontakte" + }, + "EMAIL": { + "TEXT": "Email", + "LIST": { + "INBOX": "Posteingang", + "COMPOSE": "Komponieren", + "READ": "E-Mail lesen" + } + }, + "MORE-APPS": { + "TEXT": "Mehr Apps", + "LIST": { + "CHAT": "Plaudern", + "SUPPORT": "Unterstützung", + "DRAG-DROP": "Ziehen und loslassen", + "CONTACT-GRID": "Kontakt Grid" + } + }, + "COMPONENTS": { + "TEXT": "Komponenten" + }, + "WIDGETS": { + "TEXT": "Widgets", + "LIST": { + "CHART-WIDGET": "Diagramm-Widget", + "DATA-WIDGET": "Daten-Widget" + } + }, + "FORMS": { + "TEXT": "Formen", + "LIST": { + "CONTROLS": "Form Controls", + "ADVANCE": "Advance Control", + "EXAMPLE": "Vorabkontrolle", + "VALIDATION": "Formularvalidierung", + "WIZARD": "Magier", + "EDITORS": "Redakteurinnen" + } + }, + "TABLES": { + "TEXT": "Tabellen", + "LIST": { + "BASIC": "Tablas básicas", + "MATERIAL": "Materialtabellen", + "NGX-DATATABLE": "NGX-datierbar" + } + } + } +} diff --git a/MyOffice.SPA/src/assets/i18n/en.json b/MyOffice.SPA/src/assets/i18n/en.json new file mode 100644 index 0000000..6312a93 --- /dev/null +++ b/MyOffice.SPA/src/assets/i18n/en.json @@ -0,0 +1,84 @@ +{ + "HEADER": { + "SEARCH": { + "TEXT": "Search.." + } + }, + "MENUITEMS": { + "USER": { + "POST": "Manager" + }, + "MAIN": { + "TEXT": "Main" + }, + "DASHBOARD": { + "TEXT": "Dashboard", + "LIST": { + "DASHBOARD1": "Dashboard 1", + "DASHBOARD2": "Dashboard 2", + "DASHBOARD3": "Dashboard 3" + } + }, + "ADVANCE-TABLE": { + "TEXT": "Advance Table" + }, + "APPS": { + "TEXT": "Apps" + }, + "CALENDAR": { + "TEXT": "Calendar" + }, + "TASK": { + "TEXT": "Task" + }, + "CONTACTS": { + "TEXT": "Contacts" + }, + "EMAIL": { + "TEXT": "Email", + "LIST": { + "INBOX": "Inbox", + "COMPOSE": "Compose", + "READ": "Read Email" + } + }, + "MORE-APPS": { + "TEXT": "More Apps", + "LIST": { + "CHAT": "Chat", + "SUPPORT": "Support", + "DRAG-DROP": "Drag & Drop", + "CONTACT-GRID": "Contact Grid" + } + }, + "COMPONENTS": { + "TEXT": "Components" + }, + "WIDGETS": { + "TEXT": "Widgets", + "LIST": { + "CHART-WIDGET": "Chart-Widget", + "DATA-WIDGET": "Data-Widget" + } + }, + "FORMS": { + "TEXT": "Forms", + "LIST": { + "CONTROLS": "Form Controls", + "ADVANCE": "Advance Control", + "EXAMPLE": "Form Examples", + "VALIDATION": "Form Validation", + "WIZARD": "Wizard", + "EDITORS": "Editors" + } + }, + "TABLES": { + "TEXT": "Tables", + "LIST": { + "BASIC": "Basic Tables", + "MATERIAL": "Material Tables", + "NGX-DATATABLE": "NGX-Datatable" + } + } + } +} diff --git a/MyOffice.SPA/src/assets/i18n/es.json b/MyOffice.SPA/src/assets/i18n/es.json new file mode 100644 index 0000000..13469d3 --- /dev/null +++ b/MyOffice.SPA/src/assets/i18n/es.json @@ -0,0 +1,84 @@ +{ + "HEADER": { + "SEARCH": { + "TEXT": "Buscar.." + } + }, + "MENUITEMS": { + "USER": { + "POST": "Gerente" + }, + "MAIN": { + "TEXT": "Principal" + }, + "DASHBOARD": { + "TEXT": "Casa", + "LIST": { + "DASHBOARD1": "Tablero 1", + "DASHBOARD2": "Tablero 2", + "DASHBOARD3": "Tablero 3" + } + }, + "ADVANCE-TABLE": { + "TEXT": "Tabla de avance" + }, + "APPS": { + "TEXT": "Aplicaciones" + }, + "CALENDAR": { + "TEXT": "Calendario" + }, + "TASK": { + "TEXT": "Tarea" + }, + "CONTACTS": { + "TEXT": "Contactos" + }, + "EMAIL": { + "TEXT": "Email", + "LIST": { + "INBOX": "Bandeja de entrada", + "COMPOSE": "Componer", + "READ": "Leer el correo electrónico" + } + }, + "MORE-APPS": { + "TEXT": "Más aplicaciones", + "LIST": { + "CHAT": "Charla", + "SUPPORT": "Apoyo", + "DRAG-DROP": "Arrastrar y soltar", + "CONTACT-GRID": "Cuadrícula de contacto" + } + }, + "COMPONENTS": { + "TEXT": "Componentes" + }, + "WIDGETS": { + "TEXT": "Widgets", + "LIST": { + "CHART-WIDGET": "Widget de gráfico", + "DATA-WIDGET": "Widget de datos" + } + }, + "FORMS": { + "TEXT": "Formularios", + "LIST": { + "CONTROLS": "Controles de formulario", + "ADVANCE": "Control avanzado", + "EXAMPLE": "Ejemplos de formularios", + "VALIDATION": "Validación de formulario", + "WIZARD": "Mago", + "EDITORS": "Editoras" + } + }, + "TABLES": { + "TEXT": "Tabellen", + "LIST": { + "BASIC": "Tablas básicas", + "MATERIAL": "Tablas de materiales", + "NGX-DATATABLE": "NGX-Datatable" + } + } + } +} diff --git a/MyOffice.SPA/src/assets/images/apps/calendar.png b/MyOffice.SPA/src/assets/images/apps/calendar.png new file mode 100644 index 0000000..2778d98 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/calendar.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/chat.png b/MyOffice.SPA/src/assets/images/apps/chat.png new file mode 100644 index 0000000..a67f315 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/chat.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/contact.png b/MyOffice.SPA/src/assets/images/apps/contact.png new file mode 100644 index 0000000..df66232 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/contact.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/gallery.png b/MyOffice.SPA/src/assets/images/apps/gallery.png new file mode 100644 index 0000000..7845170 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/gallery.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/mail.png b/MyOffice.SPA/src/assets/images/apps/mail.png new file mode 100644 index 0000000..dcdc777 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/mail.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/support.png b/MyOffice.SPA/src/assets/images/apps/support.png new file mode 100644 index 0000000..c5f5b76 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/support.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/table.png b/MyOffice.SPA/src/assets/images/apps/table.png new file mode 100644 index 0000000..b1d2feb Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/table.png differ diff --git a/MyOffice.SPA/src/assets/images/apps/task.png b/MyOffice.SPA/src/assets/images/apps/task.png new file mode 100644 index 0000000..bcbe59f Binary files /dev/null and b/MyOffice.SPA/src/assets/images/apps/task.png differ diff --git a/MyOffice.SPA/src/assets/images/banner/1.png b/MyOffice.SPA/src/assets/images/banner/1.png new file mode 100644 index 0000000..d90352c Binary files /dev/null and b/MyOffice.SPA/src/assets/images/banner/1.png differ diff --git a/MyOffice.SPA/src/assets/images/banner/2.png b/MyOffice.SPA/src/assets/images/banner/2.png new file mode 100644 index 0000000..d90352c Binary files /dev/null and b/MyOffice.SPA/src/assets/images/banner/2.png differ diff --git a/MyOffice.SPA/src/assets/images/banner/3.png b/MyOffice.SPA/src/assets/images/banner/3.png new file mode 100644 index 0000000..d90352c Binary files /dev/null and b/MyOffice.SPA/src/assets/images/banner/3.png differ diff --git a/MyOffice.SPA/src/assets/images/banner/4.png b/MyOffice.SPA/src/assets/images/banner/4.png new file mode 100644 index 0000000..d90352c Binary files /dev/null and b/MyOffice.SPA/src/assets/images/banner/4.png differ diff --git a/MyOffice.SPA/src/assets/images/dark.png b/MyOffice.SPA/src/assets/images/dark.png new file mode 100644 index 0000000..9698d4f Binary files /dev/null and b/MyOffice.SPA/src/assets/images/dark.png differ diff --git a/MyOffice.SPA/src/assets/images/details_close.png b/MyOffice.SPA/src/assets/images/details_close.png new file mode 100644 index 0000000..9c7d698 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/details_close.png differ diff --git a/MyOffice.SPA/src/assets/images/details_open.png b/MyOffice.SPA/src/assets/images/details_open.png new file mode 100644 index 0000000..c0edf44 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/details_open.png differ diff --git a/MyOffice.SPA/src/assets/images/favicon.ico b/MyOffice.SPA/src/assets/images/favicon.ico new file mode 100644 index 0000000..9ba9214 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/favicon.ico differ diff --git a/MyOffice.SPA/src/assets/images/flags/germany.jpg b/MyOffice.SPA/src/assets/images/flags/germany.jpg new file mode 100644 index 0000000..46147e4 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/flags/germany.jpg differ diff --git a/MyOffice.SPA/src/assets/images/flags/spain.jpg b/MyOffice.SPA/src/assets/images/flags/spain.jpg new file mode 100644 index 0000000..f81c83a Binary files /dev/null and b/MyOffice.SPA/src/assets/images/flags/spain.jpg differ diff --git a/MyOffice.SPA/src/assets/images/flags/us.jpg b/MyOffice.SPA/src/assets/images/flags/us.jpg new file mode 100644 index 0000000..851cd7b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/flags/us.jpg differ diff --git a/MyOffice.SPA/src/assets/images/icons/xlsx.png b/MyOffice.SPA/src/assets/images/icons/xlsx.png new file mode 100644 index 0000000..2362390 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/icons/xlsx.png differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/1.jpg b/MyOffice.SPA/src/assets/images/image-gallery/1.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/1.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/10.jpg b/MyOffice.SPA/src/assets/images/image-gallery/10.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/10.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/11.jpg b/MyOffice.SPA/src/assets/images/image-gallery/11.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/11.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/12.jpg b/MyOffice.SPA/src/assets/images/image-gallery/12.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/12.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/2.jpg b/MyOffice.SPA/src/assets/images/image-gallery/2.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/2.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/3.jpg b/MyOffice.SPA/src/assets/images/image-gallery/3.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/3.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/4.jpg b/MyOffice.SPA/src/assets/images/image-gallery/4.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/4.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/5.jpg b/MyOffice.SPA/src/assets/images/image-gallery/5.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/5.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/6.jpg b/MyOffice.SPA/src/assets/images/image-gallery/6.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/6.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/7.jpg b/MyOffice.SPA/src/assets/images/image-gallery/7.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/7.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/8.jpg b/MyOffice.SPA/src/assets/images/image-gallery/8.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/8.jpg differ diff --git a/MyOffice.SPA/src/assets/images/image-gallery/9.jpg b/MyOffice.SPA/src/assets/images/image-gallery/9.jpg new file mode 100644 index 0000000..25bdf2b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/image-gallery/9.jpg differ diff --git a/MyOffice.SPA/src/assets/images/invoice_logo.png b/MyOffice.SPA/src/assets/images/invoice_logo.png new file mode 100644 index 0000000..357b09e Binary files /dev/null and b/MyOffice.SPA/src/assets/images/invoice_logo.png differ diff --git a/MyOffice.SPA/src/assets/images/light.png b/MyOffice.SPA/src/assets/images/light.png new file mode 100644 index 0000000..46595db Binary files /dev/null and b/MyOffice.SPA/src/assets/images/light.png differ diff --git a/MyOffice.SPA/src/assets/images/logo.png b/MyOffice.SPA/src/assets/images/logo.png new file mode 100644 index 0000000..8396882 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/logo.png differ diff --git a/MyOffice.SPA/src/assets/images/media.png b/MyOffice.SPA/src/assets/images/media.png new file mode 100644 index 0000000..d889069 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/media.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-01.png b/MyOffice.SPA/src/assets/images/pages/bg-01.png new file mode 100644 index 0000000..2847236 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/bg-01.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-02.png b/MyOffice.SPA/src/assets/images/pages/bg-02.png new file mode 100644 index 0000000..2847236 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/bg-02.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-03.png b/MyOffice.SPA/src/assets/images/pages/bg-03.png new file mode 100644 index 0000000..2847236 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/bg-03.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-04.png b/MyOffice.SPA/src/assets/images/pages/bg-04.png new file mode 100644 index 0000000..2847236 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/bg-04.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/bg-05.png b/MyOffice.SPA/src/assets/images/pages/bg-05.png new file mode 100644 index 0000000..2847236 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/bg-05.png differ diff --git a/MyOffice.SPA/src/assets/images/pages/home-1.png b/MyOffice.SPA/src/assets/images/pages/home-1.png new file mode 100644 index 0000000..df6683d Binary files /dev/null and b/MyOffice.SPA/src/assets/images/pages/home-1.png differ diff --git a/MyOffice.SPA/src/assets/images/posts/post1.jpg b/MyOffice.SPA/src/assets/images/posts/post1.jpg new file mode 100644 index 0000000..d706d8b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post1.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post10.jpg b/MyOffice.SPA/src/assets/images/posts/post10.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post10.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post11.jpg b/MyOffice.SPA/src/assets/images/posts/post11.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post11.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post12.jpg b/MyOffice.SPA/src/assets/images/posts/post12.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post12.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post13.jpg b/MyOffice.SPA/src/assets/images/posts/post13.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post13.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post2.jpg b/MyOffice.SPA/src/assets/images/posts/post2.jpg new file mode 100644 index 0000000..d706d8b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post2.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post3.jpg b/MyOffice.SPA/src/assets/images/posts/post3.jpg new file mode 100644 index 0000000..d706d8b Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post3.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post4.jpg b/MyOffice.SPA/src/assets/images/posts/post4.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post4.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post5.jpg b/MyOffice.SPA/src/assets/images/posts/post5.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post5.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post6.jpg b/MyOffice.SPA/src/assets/images/posts/post6.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post6.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post7.jpg b/MyOffice.SPA/src/assets/images/posts/post7.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post7.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post8.jpg b/MyOffice.SPA/src/assets/images/posts/post8.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post8.jpg differ diff --git a/MyOffice.SPA/src/assets/images/posts/post9.jpg b/MyOffice.SPA/src/assets/images/posts/post9.jpg new file mode 100644 index 0000000..5d46edc Binary files /dev/null and b/MyOffice.SPA/src/assets/images/posts/post9.jpg differ diff --git a/MyOffice.SPA/src/assets/images/products/p-13.jpg b/MyOffice.SPA/src/assets/images/products/p-13.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/products/p-13.jpg differ diff --git a/MyOffice.SPA/src/assets/images/products/p-14.jpg b/MyOffice.SPA/src/assets/images/products/p-14.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/products/p-14.jpg differ diff --git a/MyOffice.SPA/src/assets/images/products/p-15.jpg b/MyOffice.SPA/src/assets/images/products/p-15.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/products/p-15.jpg differ diff --git a/MyOffice.SPA/src/assets/images/test.pdf b/MyOffice.SPA/src/assets/images/test.pdf new file mode 100644 index 0000000..fc3d58a Binary files /dev/null and b/MyOffice.SPA/src/assets/images/test.pdf differ diff --git a/MyOffice.SPA/src/assets/images/thumbs-up.png b/MyOffice.SPA/src/assets/images/thumbs-up.png new file mode 100644 index 0000000..8273711 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/thumbs-up.png differ diff --git a/MyOffice.SPA/src/assets/images/user/admin.jpg b/MyOffice.SPA/src/assets/images/user/admin.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/admin.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user1.jpg b/MyOffice.SPA/src/assets/images/user/user1.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user1.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user10.jpg b/MyOffice.SPA/src/assets/images/user/user10.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user10.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user11.jpg b/MyOffice.SPA/src/assets/images/user/user11.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user11.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user2.jpg b/MyOffice.SPA/src/assets/images/user/user2.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user2.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user3.jpg b/MyOffice.SPA/src/assets/images/user/user3.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user3.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user4.jpg b/MyOffice.SPA/src/assets/images/user/user4.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user4.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user5.jpg b/MyOffice.SPA/src/assets/images/user/user5.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user5.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user6.jpg b/MyOffice.SPA/src/assets/images/user/user6.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user6.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user7.jpg b/MyOffice.SPA/src/assets/images/user/user7.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user7.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user8.jpg b/MyOffice.SPA/src/assets/images/user/user8.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user8.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/user9.jpg b/MyOffice.SPA/src/assets/images/user/user9.jpg new file mode 100644 index 0000000..dd2b3b8 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/user9.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig1.jpg b/MyOffice.SPA/src/assets/images/user/usrbig1.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig1.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig10.jpg b/MyOffice.SPA/src/assets/images/user/usrbig10.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig10.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig11.jpg b/MyOffice.SPA/src/assets/images/user/usrbig11.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig11.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig2.jpg b/MyOffice.SPA/src/assets/images/user/usrbig2.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig2.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig3.jpg b/MyOffice.SPA/src/assets/images/user/usrbig3.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig3.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig4.jpg b/MyOffice.SPA/src/assets/images/user/usrbig4.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig4.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig5.jpg b/MyOffice.SPA/src/assets/images/user/usrbig5.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig5.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig6.jpg b/MyOffice.SPA/src/assets/images/user/usrbig6.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig6.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig7.jpg b/MyOffice.SPA/src/assets/images/user/usrbig7.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig7.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig8.jpg b/MyOffice.SPA/src/assets/images/user/usrbig8.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig8.jpg differ diff --git a/MyOffice.SPA/src/assets/images/user/usrbig9.jpg b/MyOffice.SPA/src/assets/images/user/usrbig9.jpg new file mode 100644 index 0000000..cbe59c3 Binary files /dev/null and b/MyOffice.SPA/src/assets/images/user/usrbig9.jpg differ diff --git a/MyOffice.SPA/src/assets/scss/apps/_calendar.scss b/MyOffice.SPA/src/assets/scss/apps/_calendar.scss new file mode 100644 index 0000000..0a416be --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_calendar.scss @@ -0,0 +1,340 @@ +/* + * Document : _calendar.scss + * Author : RedStar Template + * Description: This scss file for style related to calendar app + */ + +#event_title { + font-size: 1.2rem; +} + +#calendar { + float: right; + width: 100%; +} + +#external-events { + .fc-event { + padding: 5px 10px; + font-size: 14px; + margin-bottom: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + border-radius: 3px; + cursor: move; + } + + .form-check .form-check-label { + font-size: 14px; + } +} + +.cal-event { + display: inline-block !important; + height: 10px; + width: 10px; + border-radius: 50%; + padding: 0; +} + +.fc-state-active { + background: #a389d4 !important; + color: #fff; +} + +.fc-day-grid-event { + color: white !important; + text-align: center; +} + +.fc-event-primary { + border: none !important; + background-color: #007bff !important; + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), + 0 7px 10px -5px rgba(0, 154, 255, 0.4); + color: #fff; +} + +.fc-event-warning { + border: none !important; + background-color: #ff9800 !important; + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), + 0 7px 10px -5px rgba(255, 152, 0, 0.4); + color: #fff; +} + +.fc-event-success { + border: none !important; + position: relative; + background-color: #53b958 !important; + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), + 0 7px 10px -5px rgba(76, 175, 80, 0.4); + font-weight: 400; + color: #fff; +} + +.fc-event-danger { + border: none !important; + background-color: #f9483b !important; + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), + 0 7px 10px -5px rgba(244, 67, 54, 0.4); + color: #fff; +} + +.fc-event-info { + border: none !important; + position: relative; + background-color: #03c5de !important; + box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), + 0 7px 10px -5px rgba(0, 188, 212, 0.4); + font-weight: 400; + color: #fff; +} + +.fc-event-default { + background: #007bff; + border: 1px solid #007bff; +} + +.fc-state-default { + border: 1px solid #eee; + background: transparent !important; + color: #7e869d; + border-radius: 0; +} + +.catLbl { + font-weight: 600; + color: #34395e; + font-size: 12px; + letter-spacing: 0.5px; + margin-bottom: 0; +} + +.fc .fc-button-primary { + background-color: #ffffff !important; + border: 1px solid #eee !important; + color: #7e869d !important; + border-radius: 5px !important; + margin-right: 8px !important; + + &:disabled { + color: #fff !important; + background-color: #6777ef !important; + border-color: #6777ef !important; + } + + &:hover { + color: #868181 !important; + background-color: #e1e0e0 !important; + border-color: #e1e0e0 !important; + } + + &:focus { + box-shadow: none !important; + } + + &:not(:disabled) { + &.fc-button-active { + color: #fff !important; + background-color: #6777ef !important; + border-color: #6777ef !important; + } + + &:active { + color: #fff !important; + background-color: #6777ef !important; + border-color: #6777ef !important; + } + } +} + +.fc-color-picker { + list-style: none; + margin: 0; + padding: 0; + + > li { + float: left; + font-size: 30px; + margin-right: 5px; + line-height: 30px; + } +} + +.fc-content-skeleton thead { + border-bottom: none; +} + +.fc-toolbar h2 { + font-size: 16px; + margin-top: 4px; +} + +.fc-view { + border-color: #f2f2f2; + + > table { + border-color: #f2f2f2; + + th { + border-color: #ddd; + color: color(fontdark) !important; + font-weight: 500; + padding: 15px; + } + } + + color: color(fontdark) !important; + font-weight: 500; + padding: 10px; + + .fc-scrollgrid-section { + > th { + padding: 0px; + } + } +} + +.fc-view-container > .fc-view { + padding: 0; +} + +.fc-view { + color: #666; + text-align: right; + + > table td { + color: #666; + text-align: right; + } +} + +.fc button .fc-icon { + top: -0.09em; +} + +.fc-basic-view { + .fc-day-number, + .fc-week-number { + padding: 10px; + } +} + +.fc .fc-daygrid-event { + padding: 0px 10px; + box-shadow: 0 4px 25px 0 rgba(0, 0, 0, 0.1); + color: #ffffff; + text-align: left; +} +.fc-daygrid-block-event .fc-event-time { + font-weight: 400 !important; + font-size: 12px; +} +.fc-daygrid-event-dot { + display: none; +} +.fc-daygrid-dot-event .fc-event-title { + font-weight: 400 !important; + text-align: left; + font-size: 12px; +} +.fc-daygrid-dot-event .fc-event-time { + font-weight: 400 !important; + text-align: left; + font-size: 12px; +} +.fc-event-title-container .fc-event-title { + font-weight: 400 !important; + text-align: left; + font-size: 12px; +} + +tr:first-child > td > .fc-day-grid-event { + margin-bottom: 10px; +} + +.fc-state-default { + border-radius: 3px; + background-color: #f2f2f2; + background-image: none; + border: none; + box-shadow: none; + text-transform: capitalize; + font-weight: 500; +} + +.fc button { + height: auto; + padding: 10px 15px; + text-shadow: none; + border-radius: 0; + + &.fc-state-active { + background-color: color(primary); + color: #fff; + } +} + +.fc .fc-axis { + vertical-align: middle; + padding: 0 4px; + white-space: nowrap; +} + +.ngx-mat-timepicker { + .ng-pristine { + td { + padding: 0px; + border-top: none; + border-bottom: none; + } + } +} + +.fc-time-grid-event .fc-content { + color: #ffffff; +} + +.fc-list-event { + color: #ffffff; +} + +.fc-list-event:hover td { + background-color: #cccaca !important; +} + +.fc-event-container:hover { + cursor: pointer; +} + +.fc-daygrid-day-top { + text-align: center; + display: block !important; + .fc-daygrid-day-number { + color: #666; + display: inline-flex; + align-items: center; + justify-content: center; + margin: 4px 0; + font-size: 12px !important; + } +} +.fc-day-today .fc-daygrid-day-number { + display: inline-flex; + align-items: center; + justify-content: center; + width: 25px; + height: 25px; + margin: 4px 0; + font-size: 12px; + border-radius: 50%; + background: #6777ef; + color: #fff; +} +.fc .fc-daygrid-day.fc-day-today { + background-color: transparent !important; +} +.fc .fc-col-header-cell-cushion { + color: #666; +} diff --git a/MyOffice.SPA/src/assets/scss/apps/_chat.scss b/MyOffice.SPA/src/assets/scss/apps/_chat.scss new file mode 100644 index 0000000..4cc8208 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_chat.scss @@ -0,0 +1,218 @@ +/* + * Document : _chat.scss + * Author : RedStar Template + * Description: This scss file for style related to chat app + */ +%font_extend { + font-size: 16px; + color: gray; + cursor: pointer; +} + +.chat-app { + height: 690px; + .people-list { + width: 280px; + position: absolute; + left: 0; + top: 0; + padding: 20px; + } + .chat { + // margin-left: 280px; + border-left: 1px solid #e8e8e8; + } + .list_btn { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 9999; + padding: 0; + width: 40px; + height: 40px; + text-align: center; + line-height: 40px; + display: none; + @include box-shadow(0 10px 25px 0 rgba(0, 0, 0, 0.3)); + @include border-radius(3px); + } +} +.people-list { + transition: 0.5s; + .chat-list { + li { + padding: 10px 15px; + list-style: none; + @include border-radius(3px); + &:hover { + background: #efefef; + cursor: pointer; + } + &.active { + background: #efefef; + } + .name { + font-size: 15px; + } + } + img { + width: 45px; + @include border-radius(50%); + } + } + img { + float: left; + border: 1px solid #fff; + @include box-shadow(0px 5px 25px 0px rgba(0, 0, 0, 0.2)); + @include border-radius(50%); + } + .about { + float: left; + padding-left: 8px; + } + .status { + color: #999; + font-size: 13px; + } +} +.chat { + .chat-header { + padding: 20px; + border-bottom: 1px solid #eee; + border-radius: 0 0.55rem 0 0; + img { + float: left; + @include border-radius(50%); + width: 45px; + } + .chat-about { + float: left; + padding-left: 10px; + } + .chat-with { + font-weight: bold; + font-size: 16px; + } + .chat-num-messages { + color: 434651; + } + } + .chat-history { + padding: 20px; + border-bottom: 2px solid #fff; + height: 450px; + ul { + padding: 0; + li { + list-style: none; + } + } + .message-data { + margin-bottom: 15px; + .message-data-name { + font-size: 13px; + font-weight: 700; + } + } + .message-data-time { + color: #434651; + padding-left: 6px; + } + .message { + color: #444; + padding: 18px 20px; + line-height: 26px; + font-size: 13px; + @include border-radius(7px); + margin-bottom: 30px; + width: 90%; + position: relative; + &:after { + bottom: 100%; + left: 7%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-bottom-color: #fff; + border-width: 10px; + margin-left: -10px; + } + } + .my-message { + background: #e8e8e8; + &:after { + bottom: 100%; + left: 7%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-bottom-color: #e8e8e8; + border-width: 10px; + margin-left: -10px; + } + } + .other-message { + background: #d9e7ea; + &:after { + border-bottom-color: #d9e7ea; + left: 93%; + } + } + } + .chat-message { + padding: 20px; + textarea { + width: 100%; + border: none; + padding: 10px 20px; + font: 14px/22px Lato, Arial, sans-serif; + margin-bottom: 10px; + @include border-radius(5px); + resize: none; + } + .fa-file-o { + @extend %font_extend; + } + .fa-file-image-o { + @extend %font_extend; + } + } +} +.online { + margin-right: 3px; + font-size: 10px; + color: #86bb71; +} +.offline { + margin-right: 3px; + font-size: 10px; + color: #e38968; +} +.me { + margin-right: 3px; + font-size: 10px; + color: #0498bd; +} +.float-end { + float: right; +} +.clearfix:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} +.slimScrollBar { + z-index: 0 !important; +} +.chat-upload { + float: right; +} diff --git a/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss b/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss new file mode 100644 index 0000000..5e7eea7 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_contactgrid.scss @@ -0,0 +1,36 @@ +/* + * Document : _contactgrid.scss + * Author : RedStar Template + * Description: This scss file for style related to contact grid app + */ +.contact-grid { + float: left; + width: 100%; + text-align: center; +} +.profile-header { + min-height: 150px; + color: #fff; +} +.user-name { + padding: 3px; + font-size: 22px; + text-align: center; + padding-top: 10px; +} +.user-img { + padding: 3px; + border-radius: 50% 50% 50% 50%; + max-width: 112px; + margin-top: -70px; + box-shadow: 0px 10px 25px 0px rgba(0, 0, 0, 0.3); + margin-bottom: 20px; +} +.profile-userbuttons { + text-align: center; + margin-top: 10px; +} +.contact-grid .phone .material-icons { + font-size: 16px; + padding: 4px 7px 40px 0px; +} diff --git a/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss b/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss new file mode 100644 index 0000000..18c17da --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_contactlist.scss @@ -0,0 +1,127 @@ +/* + * Document : _contactlist.scss + * Author : RedStar Template + * Description: This scss file for style related to contact list app + */ +.contact-detail { + .fa { + float: left; + width: 30px; + font-size: 20px; + margin-top: 5px; + } + span { + float: left; + width: calc(100% - 30px); + margin-bottom: 20px; + } + .fa-envelope { + font-size: 15px; + } + .fa-mobile { + font-size: 25px; + } +} +.contact-photo { + float: left; + width: 100%; + text-align: center; + padding-top: 20px; + img { + margin: 0 auto; + width: 130px; + padding: 3px; + border: 3px solid rgb(210, 214, 222); + border-radius: 50% 50% 50% 50%; + } +} +.contact-usertitle { + text-align: center; + margin-top: 5px; +} +.contact-usertitle-name { + font-size: 20px; + margin-bottom: 2px; + font-weight: bold; + color: #3a405b; +} +.contact-usertitle-job { + color: #777777; + font-size: 12px; + margin-bottom: 5px; +} +.newLabelBtn { + padding: 20px 0; + text-align: center; +} +.alert-dismissible .close { + text-indent: 0; +} +.alert.alert-dismissible { + color: #ffffff; +} +.contact_list { + .phone { + position: relative; + padding-left: 20px; + .material-icons { + position: absolute; + left: 0; + font-size: 16px; + top: 1px; + } + } +} +.list-group-unbordered { + .list-group-item { + border: 0px; + } +} +.contact-header { + display: flex; + + .contact-details-img img { + position: relative; + display: flex; + width: 80px; + height: 80px; + border-radius: 50%; + margin-right: 0px; + overflow: hidden; + } +} + +.contact-details-name { + font-size: 20px; + font-weight: 500; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + letter-spacing: 1px; +} + +.contact-details-field { + display: flex; + margin-top: 30px; + + .material-icons-two-tone { + margin: 0 20px 0 10px; + } + + .contact-detail-info { + white-space: pre-wrap; + } + + .color-icon { + filter: invert(14%) sepia(0%) saturate(5141%) hue-rotate(101deg) + brightness(95%) contrast(97%); + } +} + +.contact-form { + .modalHeader img { + border-radius: 50%; + height: 35px; + width: 35px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss b/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss new file mode 100644 index 0000000..cd4c6eb --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_dragdrop.scss @@ -0,0 +1,153 @@ +.example-box { + width: 200px; + height: 200px; + border: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + cursor: move; + display: inline-flex; + justify-content: center; + align-items: center; + text-align: center; + background: #fff; + border-radius: 4px; + margin-right: 25px; + position: relative; + z-index: 1; + box-sizing: border-box; + padding: 10px; + transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1); + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), + 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.example-box:active { + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.example-boundary { + width: 400px; + height: 400px; + max-width: 100%; + border: dotted #ccc 2px; +} + +.example-container2 { + width: 400px; + max-width: 100%; + margin: 0 25px 25px 0; + display: inline-block; + vertical-align: top; +} + +.example-list { + border: solid 1px #ccc; + min-height: 60px; + background: white; + border-radius: 4px; + overflow: hidden; + display: block; +} + +.example-box-small { + padding: 20px 10px; + border-bottom: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + box-sizing: border-box; + cursor: move; + background: white; + font-size: 14px; +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-box-small:last-child { + border: none; +} + +.example-list.cdk-drop-list-dragging + .example-box-small:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-list2 { + width: 500px; + max-width: 100%; + border: solid 1px #ccc; + min-height: 60px; + display: block; + background: white; + border-radius: 4px; + overflow: hidden; +} + +.example-box2 { + padding: 20px 10px; + border-bottom: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + box-sizing: border-box; + cursor: move; + background: white; + font-size: 14px; +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-box2:last-child { + border: none; +} + +.example-list2.cdk-drop-list-dragging .example-box2:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-custom-placeholder { + background: #ccc; + border: dotted 3px #999; + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.example-box-small.cdk-drag-disabled { + background: #ccc; + cursor: default; +} +.example-handle { + position: absolute; + top: 10px; + right: 10px; + color: #ccc; + cursor: move; + width: 24px; + height: 24px; +} diff --git a/MyOffice.SPA/src/assets/scss/apps/_task.scss b/MyOffice.SPA/src/assets/scss/apps/_task.scss new file mode 100644 index 0000000..28116f9 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/apps/_task.scss @@ -0,0 +1,250 @@ +.gu-mirror { + position: fixed !important; + margin: 0 !important; + z-index: 9999 !important; + opacity: 0.8; + filter: alpha(opacity=80); +} + +.gu-hide { + display: none !important; +} + +.gu-unselectable { + //Instead of the line below you could use @include user-select($select) + user-select: none !important; +} + +.gu-transit { + opacity: 0.2; + filter: alpha(opacity=20); +} + +.taskbar { + .checked { + border: 3px solid #dda500 !important; + } + + .box { + padding-bottom: 7px; + + .task-name { + font-size: 18px; + font-weight: 600; + color: green; + } + + .task-desc { + font-size: 1.1em; + color: #555; + } + + .task-deadline { + margin-top: 5px; + margin-right: 5px; + font-size: 0.8em; + color: #555; + } + } + + .done div.box { + pointer-events: none; + + .tasks { + color: #fff !important; + } + } + + .avatar-image { + display: inline-block; + position: relative; + } + + .task-header { + text-align: center; + font-size: 25px; + padding: 20px; + color: #6b6a6a; + } + + .card-footer { + background: #fff !important; + border-radius: 0px 0px 10px 10px; + + .progress { + height: 5px; + } + } +} + +.pad { + padding-left: 0; + padding-right: 0; + display: flex; +} + +.move { + text-align: center; + background: #eee; + + .btn { + margin-bottom: 20px; + } +} + +.task-module { + display: flex; + flex-direction: column; + padding: 0 !important; + min-height: 100%; + + .mat-drawer.mat-drawer-end { + width: 500px; + min-width: 500px; + border: 1px solid #dcd6d6; + } + + .task-header { + display: flex; + flex: 0 1 auto; + align-items: center; + margin: 10px 0px 23px 0px; + } + + .header-button { + margin-left: auto; + } +} + +.task-container { + .header { + .header-title { + margin: 0px 0px 0px 5px; + } + + .header-close { + position: absolute; + top: 10px; + right: 15px; + list-style: none; + } + } +} + +.task-list { + width: 100%; + max-width: 100%; + border: solid 1px #ccc; + min-height: 60px; + display: block; + background: white; + border-radius: 4px; + overflow: hidden; +} + +.task-user-img { + height: 30px; + width: 30px; + position: relative; + margin-left: 30px; + border-radius: 50%; +} + +.task-date { + margin-left: 30px; +} + +.lbl-low { + display: inline-flex; + vertical-align: middle; +} + +.lbl-high { + display: inline-flex; + vertical-align: middle; +} + +.lbl-normal { + display: inline-flex; + vertical-align: middle; +} + +.task-low { + color: #0bc53a; + position: relative; + margin-left: auto; +} + +.task-high { + color: #f9683a; + position: relative; + margin-left: auto; +} + +.task-normal { + color: #868688; + position: relative; + margin-left: auto; +} + +.task-box { + padding: 10px 10px; + border-bottom: solid 1px #ccc; + color: rgba(0, 0, 0, 0.87); + display: flex; + flex-direction: row; + align-items: center; + // justify-content: space-between; + box-sizing: border-box; + cursor: move; + background: white; + font-size: 14px; + + &:hover { + cursor: pointer; + } +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.task-box:last-child { + border: none; +} + +.task-list.cdk-drop-list-dragging .task-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.task-custom-placeholder { + background: #ccc; + border: dotted 3px #999; + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.task-handle { + color: #ccc; + cursor: move; + width: 24px; + height: 24px; +} + +.done { + text-decoration: line-through; + opacity: 0.5; +} + +.mat-list-item-content { + display: flex; + flex-direction: row; + justify-content: space-between; +} diff --git a/MyOffice.SPA/src/assets/scss/browser/_ie10.scss b/MyOffice.SPA/src/assets/scss/browser/_ie10.scss new file mode 100644 index 0000000..698e265 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/browser/_ie10.scss @@ -0,0 +1,60 @@ +html { + &.ie10 { + .sidebar { + .menu { + .list { + li { + line-height: 30px; + } + + .ml-menu { + li { + &.active { + a { + &:not(.menu-toggle) { + &.toggled { + &:before { + top: 6px !important; + line-height: 20px !important; + } + } + } + } + } + } + } + } + } + + .user-info { + .info-container { + top: 15px; + } + } + } + + .search-bar { + input[type="text"] { + padding: 26px 60px 26px 56px; + } + } + + .dropdown-menu { + ul { + &.menu { + li { + a { + margin-top: -22px; + } + } + } + } + } + + .bs-searchbox { + .form-control { + width: 90%; + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/browser/_ie11.scss b/MyOffice.SPA/src/assets/scss/browser/_ie11.scss new file mode 100644 index 0000000..00779db --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/browser/_ie11.scss @@ -0,0 +1,56 @@ +html { + &.ie11 { + .sidebar { + .menu { + .list { + .ml-menu { + li { + &.active { + a { + &:not(.menu-toggle) { + &.toggled { + &:before { + top: 6px !important; + line-height: 20px !important; + } + } + } + } + } + } + } + } + } + + .user-info { + .info-container { + top: 15px; + } + } + } + + .search-bar { + input[type="text"] { + padding: 26px 60px 26px 56px; + } + } + + .dropdown-menu { + ul { + &.menu { + li { + a { + margin-top: -22px; + } + } + } + } + } + + .bs-searchbox { + .form-control { + width: 90%; + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_animation.scss b/MyOffice.SPA/src/assets/scss/common/_animation.scss new file mode 100644 index 0000000..6ed8cde --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_animation.scss @@ -0,0 +1,1046 @@ +/* + * Document : _animation.scss + * Author : RedStar Template + * Description: This scss file for animation css classes + */ +.waves-effect { + position: relative; + cursor: pointer; + display: inline-block; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; +} +.waves-effect .waves-ripple { + position: absolute; + border-radius: 50%; + width: 100px; + height: 100px; + margin-top: -50px; + margin-left: -50px; + opacity: 0; + background: transparent; + // background:rgba(0,0,0,0.2); + // background:-webkit-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); + // background:-o-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); + // background:-moz-radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); + // background:radial-gradient(rgba(0,0,0,0.2) 0, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.5) 60%, rgba(255,255,255,0) 70%); + -webkit-transition: all 0.5s ease-out; + -moz-transition: all 0.5s ease-out; + -o-transition: all 0.5s ease-out; + transition: all 0.5s ease-out; + -webkit-transition-property: -webkit-transform, opacity; + -moz-transition-property: -moz-transform, opacity; + -o-transition-property: -o-transform, opacity; + transition-property: transform, opacity; + -webkit-transform: scale(0) translate(0, 0); + -moz-transform: scale(0) translate(0, 0); + -ms-transform: scale(0) translate(0, 0); + -o-transform: scale(0) translate(0, 0); + transform: scale(0) translate(0, 0); + pointer-events: none; +} +.waves-effect.waves-light .waves-ripple { + background: rgba(255, 255, 255, 0.4); + background: -webkit-radial-gradient( + rgba(255, 255, 255, 0.2) 0, + rgba(255, 255, 255, 0.3) 40%, + rgba(255, 255, 255, 0.4) 50%, + rgba(255, 255, 255, 0.5) 60%, + rgba(255, 255, 255, 0) 70% + ); + background: -o-radial-gradient( + rgba(255, 255, 255, 0.2) 0, + rgba(255, 255, 255, 0.3) 40%, + rgba(255, 255, 255, 0.4) 50%, + rgba(255, 255, 255, 0.5) 60%, + rgba(255, 255, 255, 0) 70% + ); + background: -moz-radial-gradient( + rgba(255, 255, 255, 0.2) 0, + rgba(255, 255, 255, 0.3) 40%, + rgba(255, 255, 255, 0.4) 50%, + rgba(255, 255, 255, 0.5) 60%, + rgba(255, 255, 255, 0) 70% + ); + background: radial-gradient( + rgba(255, 255, 255, 0.2) 0, + rgba(255, 255, 255, 0.3) 40%, + rgba(255, 255, 255, 0.4) 50%, + rgba(255, 255, 255, 0.5) 60%, + rgba(255, 255, 255, 0) 70% + ); +} +.waves-effect.waves-classic .waves-ripple { + background: rgba(0, 0, 0, 0.2); +} +.waves-effect.waves-classic.waves-light .waves-ripple { + background: rgba(255, 255, 255, 0.4); +} +.waves-notransition { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important; +} +.waves-button, +.waves-circle { + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); + -webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%); +} +.waves-button, +.waves-button:hover, +.waves-button:visited, +.waves-button-input { + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + border: none; + outline: none; + color: inherit; + background-color: transparent; + font-size: 1em; + line-height: 1em; + text-align: center; + text-decoration: none; + z-index: 1; +} +.waves-button { + padding: 0.85em 1.1em; + border-radius: 0.2em; +} +.waves-button-input { + margin: 0; + padding: 0.85em 1.1em; +} +.waves-input-wrapper { + border-radius: 0.2em; + vertical-align: bottom; +} +.waves-input-wrapper.waves-button { + padding: 0; +} +.waves-input-wrapper .waves-button-input { + position: relative; + top: 0; + left: 0; + z-index: 1; +} +.waves-circle { + text-align: center; + width: 2.5em; + height: 2.5em; + line-height: 2.5em; + border-radius: 50%; +} +.waves-float { + -webkit-mask-image: none; + -webkit-box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); + box-shadow: 0px 1px 1.5px 1px rgba(0, 0, 0, 0.12); + -webkit-transition: all 300ms; + -moz-transition: all 300ms; + -o-transition: all 300ms; + transition: all 300ms; +} +.waves-float:active { + -webkit-box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); + box-shadow: 0px 8px 20px 1px rgba(0, 0, 0, 0.3); +} +.waves-block { + display: block; +} +.slideDown { + animation-name: slideDown; + -webkit-animation-name: slideDown; + animation-duration: 1s; + -webkit-animation-duration: 1s; + animation-timing-function: ease; + -webkit-animation-timing-function: ease; + visibility: visible !important; +} +@keyframes slideDown { + 0% { + transform: translateY(-100%); + } + 50% { + transform: translateY(8%); + } + 65% { + transform: translateY(-4%); + } + 80% { + transform: translateY(4%); + } + 95% { + transform: translateY(-2%); + } + 100% { + transform: translateY(0%); + } +} +@-webkit-keyframes slideDown { + 0% { + -webkit-transform: translateY(-100%); + } + 50% { + -webkit-transform: translateY(8%); + } + 65% { + -webkit-transform: translateY(-4%); + } + 80% { + -webkit-transform: translateY(4%); + } + 95% { + -webkit-transform: translateY(-2%); + } + 100% { + -webkit-transform: translateY(0%); + } +} +.slideUp { + animation-name: slideUp; + -webkit-animation-name: slideUp; + animation-duration: 1s; + -webkit-animation-duration: 1s; + animation-timing-function: ease; + -webkit-animation-timing-function: ease; + visibility: visible !important; +} +@keyframes slideUp { + 0% { + transform: translateY(100%); + } + 50% { + transform: translateY(-8%); + } + 65% { + transform: translateY(4%); + } + 80% { + transform: translateY(-4%); + } + 95% { + transform: translateY(2%); + } + 100% { + transform: translateY(0%); + } +} +@-webkit-keyframes slideUp { + 0% { + -webkit-transform: translateY(100%); + } + 50% { + -webkit-transform: translateY(-8%); + } + 65% { + -webkit-transform: translateY(4%); + } + 80% { + -webkit-transform: translateY(-4%); + } + 95% { + -webkit-transform: translateY(2%); + } + 100% { + -webkit-transform: translateY(0%); + } +} +.slideLeft { + animation-name: slideLeft; + -webkit-animation-name: slideLeft; + animation-duration: 1s; + -webkit-animation-duration: 1s; + animation-timing-function: ease-in-out; + -webkit-animation-timing-function: ease-in-out; + visibility: visible !important; +} +@keyframes slideLeft { + 0% { + transform: translateX(150%); + } + 50% { + transform: translateX(-8%); + } + 65% { + transform: translateX(4%); + } + 80% { + transform: translateX(-4%); + } + 95% { + transform: translateX(2%); + } + 100% { + transform: translateX(0%); + } +} +@-webkit-keyframes slideLeft { + 0% { + -webkit-transform: translateX(150%); + } + 50% { + -webkit-transform: translateX(-8%); + } + 65% { + -webkit-transform: translateX(4%); + } + 80% { + -webkit-transform: translateX(-4%); + } + 95% { + -webkit-transform: translateX(2%); + } + 100% { + -webkit-transform: translateX(0%); + } +} +.slideRight { + animation-name: slideRight; + -webkit-animation-name: slideRight; + animation-duration: 1s; + -webkit-animation-duration: 1s; + animation-timing-function: ease-in-out; + -webkit-animation-timing-function: ease-in-out; + visibility: visible !important; +} +@keyframes slideRight { + 0% { + transform: translateX(-150%); + } + 50% { + transform: translateX(8%); + } + 65% { + transform: translateX(-4%); + } + 80% { + transform: translateX(4%); + } + 95% { + transform: translateX(-2%); + } + 100% { + transform: translateX(0%); + } +} +@-webkit-keyframes slideRight { + 0% { + -webkit-transform: translateX(-150%); + } + 50% { + -webkit-transform: translateX(8%); + } + 65% { + -webkit-transform: translateX(-4%); + } + 80% { + -webkit-transform: translateX(4%); + } + 95% { + -webkit-transform: translateX(-2%); + } + 100% { + -webkit-transform: translateX(0%); + } +} +.slideExpandUp { + animation-name: slideExpandUp; + -webkit-animation-name: slideExpandUp; + animation-duration: 1.6s; + -webkit-animation-duration: 1.6s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease -out; + visibility: visible !important; +} +@keyframes slideExpandUp { + 0% { + transform: translateY(100%) scaleX(0.5); + } + 30% { + transform: translateY(-8%) scaleX(0.5); + } + 40% { + transform: translateY(2%) scaleX(0.5); + } + 50% { + transform: translateY(0%) scaleX(1.1); + } + 60% { + transform: translateY(0%) scaleX(0.9); + } + 70% { + transform: translateY(0%) scaleX(1.05); + } + 80% { + transform: translateY(0%) scaleX(0.95); + } + 90% { + transform: translateY(0%) scaleX(1.02); + } + 100% { + transform: translateY(0%) scaleX(1); + } +} +@-webkit-keyframes slideExpandUp { + 0% { + -webkit-transform: translateY(100%) scaleX(0.5); + } + 30% { + -webkit-transform: translateY(-8%) scaleX(0.5); + } + 40% { + -webkit-transform: translateY(2%) scaleX(0.5); + } + 50% { + -webkit-transform: translateY(0%) scaleX(1.1); + } + 60% { + -webkit-transform: translateY(0%) scaleX(0.9); + } + 70% { + -webkit-transform: translateY(0%) scaleX(1.05); + } + 80% { + -webkit-transform: translateY(0%) scaleX(0.95); + } + 90% { + -webkit-transform: translateY(0%) scaleX(1.02); + } + 100% { + -webkit-transform: translateY(0%) scaleX(1); + } +} +.expandUp { + animation-name: expandUp; + -webkit-animation-name: expandUp; + animation-duration: 0.7s; + -webkit-animation-duration: 0.7s; + animation-timing-function: ease; + -webkit-animation-timing-function: ease; + visibility: visible !important; +} +@keyframes expandUp { + 0% { + transform: translateY(100%) scale(0.6) scaleY(0.5); + } + 60% { + transform: translateY(-7%) scaleY(1.12); + } + 75% { + transform: translateY(3%); + } + 100% { + transform: translateY(0%) scale(1) scaleY(1); + } +} +@-webkit-keyframes expandUp { + 0% { + -webkit-transform: translateY(100%) scale(0.6) scaleY(0.5); + } + 60% { + -webkit-transform: translateY(-7%) scaleY(1.12); + } + 75% { + -webkit-transform: translateY(3%); + } + 100% { + -webkit-transform: translateY(0%) scale(1) scaleY(1); + } +} +.fadeIn { + animation-name: fadeIn; + -webkit-animation-name: fadeIn; + animation-duration: 1.5s; + -webkit-animation-duration: 1.5s; + animation-timing-function: ease-in-out; + -webkit-animation-timing-function: ease-in-out; + visibility: visible !important; +} +@keyframes fadeIn { + 0% { + transform: scale(0); + opacity: 0; + } + 60% { + transform: scale(1.1); + } + 80% { + transform: scale(0.9); + opacity: 1; + } + 100% { + transform: scale(1); + opacity: 1; + } +} +@-webkit-keyframes fadeIn { + 0% { + -webkit-transform: scale(0); + opacity: 0; + } + 60% { + -webkit-transform: scale(1.1); + } + 80% { + -webkit-transform: scale(0.9); + opacity: 1; + } + 100% { + -webkit-transform: scale(1); + opacity: 1; + } +} +.expandOpen { + animation-name: expandOpen; + -webkit-animation-name: expandOpen; + animation-duration: 1.2s; + -webkit-animation-duration: 1.2s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + visibility: visible !important; +} +@keyframes expandOpen { + 0% { + transform: scale(1.8); + } + 50% { + transform: scale(0.95); + } + 80% { + transform: scale(1.05); + } + 90% { + transform: scale(0.98); + } + 100% { + transform: scale(1); + } +} +@-webkit-keyframes expandOpen { + 0% { + -webkit-transform: scale(1.8); + } + 50% { + -webkit-transform: scale(0.95); + } + 80% { + -webkit-transform: scale(1.05); + } + 90% { + -webkit-transform: scale(0.98); + } + 100% { + -webkit-transform: scale(1); + } +} +.bigEntrance { + animation-name: bigEntrance; + -webkit-animation-name: bigEntrance; + animation-duration: 1.6s; + -webkit-animation-duration: 1.6s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + visibility: visible !important; +} +@keyframes bigEntrance { + 0% { + transform: scale(0.3) rotate(6deg) translateX(-30%) translateY(30%); + opacity: 0.2; + } + 30% { + transform: scale(1.03) rotate(-2deg) translateX(2%) translateY(-2%); + opacity: 1; + } + 45% { + transform: scale(0.98) rotate(1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 60% { + transform: scale(1.01) rotate(-1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 75% { + transform: scale(0.99) rotate(1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 90% { + transform: scale(1.01) rotate(0deg) translateX(0%) translateY(0%); + opacity: 1; + } + 100% { + transform: scale(1) rotate(0deg) translateX(0%) translateY(0%); + opacity: 1; + } +} +@-webkit-keyframes bigEntrance { + 0% { + -webkit-transform: scale(0.3) rotate(6deg) translateX(-30%) translateY(30%); + opacity: 0.2; + } + 30% { + -webkit-transform: scale(1.03) rotate(-2deg) translateX(2%) translateY(-2%); + opacity: 1; + } + 45% { + -webkit-transform: scale(0.98) rotate(1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 60% { + -webkit-transform: scale(1.01) rotate(-1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 75% { + -webkit-transform: scale(0.99) rotate(1deg) translateX(0%) translateY(0%); + opacity: 1; + } + 90% { + -webkit-transform: scale(1.01) rotate(0deg) translateX(0%) translateY(0%); + opacity: 1; + } + 100% { + -webkit-transform: scale(1) rotate(0deg) translateX(0%) translateY(0%); + opacity: 1; + } +} +.hatch { + animation-name: hatch; + -webkit-animation-name: hatch; + animation-duration: 2s; + -webkit-animation-duration: 2s; + animation-timing-function: ease-in-out; + -webkit-animation-timing-function: ease-in-out; + transform-origin: 50% 100%; + -ms-transform-origin: 50% 100%; + -webkit-transform-origin: 50% 100%; + visibility: visible !important; +} +@keyframes hatch { + 0% { + transform: rotate(0deg) scaleY(0.6); + } + 20% { + transform: rotate(-2deg) scaleY(1.05); + } + 35% { + transform: rotate(2deg) scaleY(1); + } + 50% { + transform: rotate(-2deg); + } + 65% { + transform: rotate(1deg); + } + 80% { + transform: rotate(-1deg); + } + 100% { + transform: rotate(0deg); + } +} +@-webkit-keyframes hatch { + 0% { + -webkit-transform: rotate(0deg) scaleY(0.6); + } + 20% { + -webkit-transform: rotate(-2deg) scaleY(1.05); + } + 35% { + -webkit-transform: rotate(2deg) scaleY(1); + } + 50% { + -webkit-transform: rotate(-2deg); + } + 65% { + -webkit-transform: rotate(1deg); + } + 80% { + -webkit-transform: rotate(-1deg); + } + 100% { + -webkit-transform: rotate(0deg); + } +} +.bounce { + animation-name: bounce; + -webkit-animation-name: bounce; + animation-duration: 1.6s; + -webkit-animation-duration: 1.6s; + animation-timing-function: ease; + -webkit-animation-timing-function: ease; + transform-origin: 50% 100%; + -ms-transform-origin: 50% 100%; + -webkit-transform-origin: 50% 100%; +} +@keyframes bounce { + 0% { + transform: translateY(0%) scaleY(0.6); + } + 60% { + transform: translateY(-100%) scaleY(1.1); + } + 70% { + transform: translateY(0%) scaleY(0.95) scaleX(1.05); + } + 80% { + transform: translateY(0%) scaleY(1.05) scaleX(1); + } + 90% { + transform: translateY(0%) scaleY(0.95) scaleX(1); + } + 100% { + transform: translateY(0%) scaleY(1) scaleX(1); + } +} +@-webkit-keyframes bounce { + 0% { + -webkit-transform: translateY(0%) scaleY(0.6); + } + 60% { + -webkit-transform: translateY(-100%) scaleY(1.1); + } + 70% { + -webkit-transform: translateY(0%) scaleY(0.95) scaleX(1.05); + } + 80% { + -webkit-transform: translateY(0%) scaleY(1.05) scaleX(1); + } + 90% { + -webkit-transform: translateY(0%) scaleY(0.95) scaleX(1); + } + 100% { + -webkit-transform: translateY(0%) scaleY(1) scaleX(1); + } +} +.pulse { + animation-name: pulse; + -webkit-animation-name: pulse; + animation-duration: 1.5s; + -webkit-animation-duration: 1.5s; + animation-iteration-count: infinite; + -webkit-animation-iteration-count: infinite; +} +@keyframes pulse { + 0% { + transform: scale(0.9); + opacity: 0.7; + } + 50% { + transform: scale(1); + opacity: 1; + } + 100% { + transform: scale(0.9); + opacity: 0.7; + } +} +@-webkit-keyframes pulse { + 0% { + -webkit-transform: scale(0.95); + opacity: 0.7; + } + 50% { + -webkit-transform: scale(1); + opacity: 1; + } + 100% { + -webkit-transform: scale(0.95); + opacity: 0.7; + } +} +.floating { + animation-name: floating; + -webkit-animation-name: floating; + animation-duration: 1.5s; + -webkit-animation-duration: 1.5s; + animation-iteration-count: infinite; + -webkit-animation-iteration-count: infinite; +} +@keyframes floating { + 0% { + transform: translateY(0%); + } + 50% { + transform: translateY(8%); + } + 100% { + transform: translateY(0%); + } +} +@-webkit-keyframes floating { + 0% { + -webkit-transform: translateY(0%); + } + 50% { + -webkit-transform: translateY(8%); + } + 100% { + -webkit-transform: translateY(0%); + } +} +.tossing { + animation-name: tossing; + -webkit-animation-name: tossing; + animation-duration: 2.5s; + -webkit-animation-duration: 2.5s; + animation-iteration-count: infinite; + -webkit-animation-iteration-count: infinite; +} +@keyframes tossing { + 0% { + transform: rotate(-4deg); + } + 50% { + transform: rotate(4deg); + } + 100% { + transform: rotate(-4deg); + } +} +@-webkit-keyframes tossing { + 0% { + -webkit-transform: rotate(-4deg); + } + 50% { + -webkit-transform: rotate(4deg); + } + 100% { + -webkit-transform: rotate(-4deg); + } +} +.pullUp { + animation-name: pullUp; + -webkit-animation-name: pullUp; + animation-duration: 1.1s; + -webkit-animation-duration: 1.1s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + transform-origin: 50% 100%; + -ms-transform-origin: 50% 100%; + -webkit-transform-origin: 50% 100%; +} +@keyframes pullUp { + 0% { + transform: scaleY(0.1); + } + 40% { + transform: scaleY(1.02); + } + 60% { + transform: scaleY(0.98); + } + 80% { + transform: scaleY(1.01); + } + 100% { + transform: scaleY(0.98); + } + 80% { + transform: scaleY(1.01); + } + 100% { + transform: scaleY(1); + } +} +@-webkit-keyframes pullUp { + 0% { + -webkit-transform: scaleY(0.1); + } + 40% { + -webkit-transform: scaleY(1.02); + } + 60% { + -webkit-transform: scaleY(0.98); + } + 80% { + -webkit-transform: scaleY(1.01); + } + 100% { + -webkit-transform: scaleY(0.98); + } + 80% { + -webkit-transform: scaleY(1.01); + } + 100% { + -webkit-transform: scaleY(1); + } +} +.pullDown { + animation-name: pullDown; + -webkit-animation-name: pullDown; + animation-duration: 0.8s; + -webkit-animation-duration: 0.8s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + transform-origin: 50% 0%; + -ms-transform-origin: 50% 0%; + -webkit-transform-origin: 50% 0%; +} +@keyframes pullDown { + 0% { + transform: scaleY(0.1); + } + 40% { + transform: scaleY(1.02); + } + 60% { + transform: scaleY(0.98); + } + 80% { + transform: scaleY(1.01); + } + 100% { + transform: scaleY(0.98); + } + 80% { + transform: scaleY(1.01); + } + 100% { + transform: scaleY(1); + } +} +@-webkit-keyframes pullDown { + 0% { + -webkit-transform: scaleY(0.1); + } + 40% { + -webkit-transform: scaleY(1.02); + } + 60% { + -webkit-transform: scaleY(0.98); + } + 80% { + -webkit-transform: scaleY(1.01); + } + 100% { + -webkit-transform: scaleY(0.98); + } + 80% { + -webkit-transform: scaleY(1.01); + } + 100% { + -webkit-transform: scaleY(1); + } +} +.stretchLeft { + animation-name: stretchLeft; + -webkit-animation-name: stretchLeft; + animation-duration: 1.5s; + -webkit-animation-duration: 1.5s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + transform-origin: 100% 0%; + -ms-transform-origin: 100% 0%; + -webkit-transform-origin: 100% 0%; +} +@keyframes stretchLeft { + 0% { + transform: scaleX(0.3); + } + 40% { + transform: scaleX(1.02); + } + 60% { + transform: scaleX(0.98); + } + 80% { + transform: scaleX(1.01); + } + 100% { + transform: scaleX(0.98); + } + 80% { + transform: scaleX(1.01); + } + 100% { + transform: scaleX(1); + } +} +@-webkit-keyframes stretchLeft { + 0% { + -webkit-transform: scaleX(0.3); + } + 40% { + -webkit-transform: scaleX(1.02); + } + 60% { + -webkit-transform: scaleX(0.98); + } + 80% { + -webkit-transform: scaleX(1.01); + } + 100% { + -webkit-transform: scaleX(0.98); + } + 80% { + -webkit-transform: scaleX(1.01); + } + 100% { + -webkit-transform: scaleX(1); + } +} +.stretchRight { + animation-name: stretchRight; + -webkit-animation-name: stretchRight; + animation-duration: 1.5s; + -webkit-animation-duration: 1.5s; + animation-timing-function: ease-out; + -webkit-animation-timing-function: ease-out; + transform-origin: 0% 0%; + -ms-transform-origin: 0% 0%; + -webkit-transform-origin: 0% 0%; +} +@keyframes stretchRight { + 0% { + transform: scaleX(0.3); + } + 40% { + transform: scaleX(1.02); + } + 60% { + transform: scaleX(0.98); + } + 80% { + transform: scaleX(1.01); + } + 100% { + transform: scaleX(0.98); + } + 80% { + transform: scaleX(1.01); + } + 100% { + transform: scaleX(1); + } +} +@-webkit-keyframes stretchRight { + 0% { + -webkit-transform: scaleX(0.3); + } + 40% { + -webkit-transform: scaleX(1.02); + } + 60% { + -webkit-transform: scaleX(0.98); + } + 80% { + -webkit-transform: scaleX(1.01); + } + 100% { + -webkit-transform: scaleX(0.98); + } + 80% { + -webkit-transform: scaleX(1.01); + } + 100% { + -webkit-transform: scaleX(1); + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_customanimate.scss b/MyOffice.SPA/src/assets/scss/common/_customanimate.scss new file mode 100644 index 0000000..bd021ce --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_customanimate.scss @@ -0,0 +1,76 @@ +/* + * Document : _customanimate.scss + * Author : RedStar Template + * Description: This scss file for mixure of custom animation classes + */ +@-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + to { + -ms-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -o-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + to { + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); + } + + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes spin { + from { + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + to { + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_demo.scss b/MyOffice.SPA/src/assets/scss/common/_demo.scss new file mode 100644 index 0000000..74cbef7 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_demo.scss @@ -0,0 +1,372 @@ +/* + * Document : _demo.scss + * Author : RedStar Template + * Description: This scss file style classes of following components + + Structure (with shortcodes): + + 1. BUTTONS + 2. CHECKBOX & RADIO + 3. JQUERY KNOB-CHART + 4. SWITCH + 5. COLOR BOX + 6. IMAGES + 7. TAGS INPUT + 8. GOOGLE MATERIAL DESIGN ICON + 9. PRELOADER + 10. ION RANGE SLIDER + 11. RIGHT SIDEBAR + + */ + +/*********************************************************************** + + [1. BUTTONS ] + +***********************************************************************/ +.demo-button-sizes { + .btn { + margin-bottom: 5px; + } +} + +.icon-button-demo { + button { + margin-right: 5px; + margin-bottom: 12px; + } +} + +.icon-and-text-button-demo { + button { + margin-right: 5px; + margin-bottom: 12px; + width: 16.66666666666667%; + } +} + +.button-demo { + ul { + padding-left: 0; + + li { + list-style: none; + padding-left: 0; + display: inline-block; + margin-right: 7px; + + .btn { + display: block; + min-width: 175px; + } + } + } + + .btn { + margin-right: 8px; + margin-bottom: 13px; + min-width: 100px; + } +} + +.demo-button-groups { + .btn-group { + margin-right: 10px; + margin-bottom: 10px; + } +} + +.demo-button-toolbar { + .btn-toolbar { + float: left; + margin-right: 25px; + margin-bottom: 10px; + .btn-group { + margin-left: 5px; + } + } +} + +.demo-button-nesting { + > .btn-group { + margin-right: 15px; + } +} + +.demo-single-button-dropdowns { + > .btn-group { + margin-right: 10px; + } +} + +.demo-splite-button-dropdowns { + > .btn-group { + margin-right: 10px; + } +} + +.demo-dropup { + .dropup { + margin-right: 10px; + } +} + +/*********************************************************************** + + [2. CHECKBOX & RADIO ] + +***********************************************************************/ + +.demo-checkbox, +.demo-radio-button { + label { + min-width: 150px; + } +} +/*********************************************************************** + + [3. JQUERY KNOB-CHART ] + +***********************************************************************/ + +.demo-knob-chart { + div { + margin-right: 15px; + } +} +/*********************************************************************** + + [4. SWITCH ] + +***********************************************************************/ + +.demo-switch { + .switch { + display: inline-block; + min-width: 170px; + } + + .demo-switch-title { + min-width: 95px; + display: inline-block; + } +} +/*********************************************************************** + + [5. COLOR BOX ] + +***********************************************************************/ +.demo-color-box { + padding: 15px 0; + text-align: center; + margin-bottom: 20px; + @include border-radius(3px); + + .color-name { + font-size: 16px; + margin-bottom: 5px; + } + + .color-code, + .color-class-name { + font-size: 13px; + } +} +/*********************************************************************** + + [6. IMAGES ] + +***********************************************************************/ +.demo-image-copyright { + text-align: right; + font-style: italic; + font-size: 12px; + color: #777; + margin: 5px 0 10px 0; + + a { + font-weight: bold; + color: #555 !important; + } +} +/*********************************************************************** + + [7. TAGS INPUT ] + +***********************************************************************/ +.demo-tagsinput-area { + margin-bottom: 0px !important; + &.form-group .form-line:after { + border-bottom: 0px; + } +} +/*********************************************************************** + + [8 .GOOGLE MATERIAL DESIGN ICON ] + +***********************************************************************/ +.demo-icon-container { + .demo-google-material-icon { + margin-bottom: 5px; + text-align: left; + + .icon-name { + position: relative; + top: -8px; + left: 7px; + } + + .material-icons { + width: 24px; + } + } +} +/*********************************************************************** + + [9. PRELOADERS ] + +***********************************************************************/ +.demo-preloader { + .preloader { + margin-right: 10px; + } +} +/*********************************************************************** + + [10. ION RANGE SLIDER ] + +***********************************************************************/ +.irs-demo { + margin-bottom: 40px; + + .irs { + margin-top: 15px; + } +} +/*********************************************************************** + + [11. RIGHT SIDEBAR ] + +***********************************************************************/ +.right-sidebar { + .nav-tabs + .tab-content { + padding: 0; + } + + p { + margin: 20px 15px 15px 15px; + font-weight: bold; + text-align: center; + } + + #settings { + .setting-list { + list-style: none; + padding-left: 0; + margin-bottom: 20px; + + li { + padding: 15px; + position: relative; + border-top: 1px solid #eee; + + .switch { + position: absolute; + top: 15px; + right: 5px; + } + } + } + } + .progress { + -webkit-border-radius: 50px; + -moz-border-radius: 50px; + -ms-border-radius: 50px; + border-radius: 50px; + height: 7px; + margin: 10px 0px 0px 0px; + } +} +.right-sidebar .choose-theme li { + position: relative; + cursor: pointer; + display: inline-block; +} + +.demo-choose-skin, +.demo-choose-logoheader { + list-style: none; + padding-left: 0; + overflow-y: hidden; + + li { + padding: 10px 7px 4px 0px; + position: relative; + cursor: pointer; + float: left; + + &.actived { + &:after { + font-family: "Material Icons"; + position: absolute; + top: 10px; + right: 10px; + content: "\E876"; + font-size: 18px; + color: #ece6e6; + } + } + + div { + width: 24px; + height: 24px; + display: inline-block; + @include border-radius(3px); + } + + span { + position: relative; + bottom: 7px; + left: 5px; + } + } + .white-theme { + background-color: #fff; + } + .black-theme { + background-color: #3a3f51; + } + .purple-theme { + background-color: #813ae1; + } + .blue-theme { + background-color: #03a9f3; + } + .cyan-theme { + background-color: #13d1d3; + } + .green-theme { + background-color: #13b464; + } + .orange-theme { + background-color: #f06533; + } + + @each $key, $val in $colors { + .#{$key} { + background-color: $val; + } + } +} +.white-theme-border { + border: 1px solid #888888; +} + +.btn-sidebar-light, +.btn-theme-light { + background: 0 0 !important; + color: #888888 !important; + border: 1px solid #888888 !important; + margin: 10px; +} +//===================================================================================== diff --git a/MyOffice.SPA/src/assets/scss/common/_general.scss b/MyOffice.SPA/src/assets/scss/common/_general.scss new file mode 100644 index 0000000..80cfc33 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_general.scss @@ -0,0 +1,374 @@ +/* + * Document : _general.scss + * Author : RedStar Template + * Description: This scss file for all common style classes + */ + +body, +html { + @include transition(all 0.5s); + background-color: #f0eff3; + font-family: "Roboto", sans-serif; + font-size: 14px; +} + +button, +input, +select, +a { + outline: none !important; + font-size: 14px !important; + text-decoration: none; + + &:hover { + text-decoration: none; + } +} + +textarea { + font-size: 14px !important; +} + +ol, +ul, +dl { + padding-left: 0px; + list-style-type: none; +} + +.no-animate { + -o-transition-property: none !important; + -moz-transition-property: none !important; + -ms-transition-property: none !important; + -webkit-transition-property: none !important; + transition-property: none !important; + -o-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + -webkit-transform: none !important; + transform: none !important; + -webkit-animation: none !important; + -moz-animation: none !important; + -o-animation: none !important; + -ms-animation: none !important; + animation: none !important; +} + +section { + &.content { + margin: 55px 27px 0 260px; + min-height: calc(100vh - 76px); + @include transition(0.5s); + .content-block { + padding: 25px 0px 0px 25px; + } + } +} + +.horizontal-layout { + section { + &.content { + margin: 170px 15px 0 15px; + float: left; + width: calc(100% - 30px); + } + } +} + +.pull-left { + float: left !important; +} + +.pull-right { + float: right !important; +} + +.msl-1 { + margin-left: 0.25rem !important; +} +.msl-2 { + margin-left: 0.5rem !important; +} +.msl-3 { + margin-left: 1rem !important; +} +.msl-4 { + margin-left: 1.5rem !important; +} +.msl-5 { + margin-left: 3rem !important; +} + +.msr-1 { + margin-right: 0.25rem !important; +} +.msr-2 { + margin-right: 0.5rem !important; +} +.msr-3 { + margin-right: 1rem !important; +} +.msr-4 { + margin-right: 1.5rem !important; +} +.msr-5 { + margin-right: 3rem !important; +} + +.psl-1 { + padding-left: 0.25rem !important; +} +.psl-2 { + padding-left: 0.5rem !important; +} +.psl-3 { + padding-left: 1rem !important; +} +.psl-4 { + padding-left: 1.5rem !important; +} +.psl-5 { + padding-left: 3rem !important; +} + +.psr-1 { + padding-right: 0.25rem !important; +} +.psr-2 { + padding-right: 0.5rem !important; +} +.psr-3 { + padding-right: 1rem !important; +} +.psr-4 { + padding-right: 1.5rem !important; +} +.psr-5 { + padding-right: 3rem !important; +} +.cursor-pointer { + cursor: pointer; +} + +.jqvmap-zoomin, +.jqvmap-zoomout { + width: 15px; + height: 15px; +} + +table { + .checkbox { + [type="checkbox"] + label { + margin: 0; + height: 20px; + padding-left: 20px; + vertical-align: middle; + } + } +} + +.loading-img-spin { + position: absolute; + top: 50%; + left: 50%; + width: 50px; + height: 50px; + margin: -60px 0 20px -20px; + -webkit-animation: spin 1.5s linear infinite; + -moz-animation: spin 1.5s linear infinite; + animation: spin 1.5s linear infinite; +} + +.shadow-style { + -webkit-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); +} + +.review-img { + padding-left: 20px; + padding-top: 5px; + width: 70px; + + img { + border-radius: 50%; + border: 2px solid #ffffff; + box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); + } +} + +.horizontal-layout { + .sidebar, + .nav-left-menu { + display: none; + } +} + +.bootstrap-notify-container { + max-width: 320px; + text-align: center; +} + +.map iframe { + width: 100%; +} + +.jqvmap-label { + position: absolute; + display: none; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + border-radius: 30px; + background: #eee; + color: black; + font-size: 14px; + font-family: sans-serif, Verdana; + padding: 10px; + pointer-events: none; +} + +.logo-white { + .navbar-toggle, + .bars:before, + .bars:after { + color: #000 !important; + } +} + +.logo-black { + .navbar-toggle, + .bars:before, + .bars:after { + color: #fff !important; + } +} + +.dark { + .sidemenu-collapse i { + color: #fff; + } + + .nav { + > li { + > a { + color: #fff; + } + } + } +} + +.light { + .sidemenu-collapse i { + color: #0d091d; + } + + .nav { + > li { + > a { + color: #0d091d; + } + } + } +} + +.border-apply { + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2) !important; +} + +input::-webkit-input-placeholder { + font-size: 12px; + color: #adabab; +} + +input:-moz-placeholder { + /* Firefox 18- */ + font-size: 12px; + color: #adabab; +} + +input::-moz-placeholder { + /* Firefox 19+ */ + font-size: 12px; + color: #adabab; +} + +input:-ms-input-placeholder { + font-size: 12px; + color: #adabab; +} + +textarea::-webkit-input-placeholder { + font-size: 12px; + color: #adabab; +} + +textarea:-moz-placeholder { + /* Firefox 18- */ + font-size: 12px; + color: #adabab; +} + +textarea::-moz-placeholder { + /* Firefox 19+ */ + font-size: 12px; + color: #adabab; +} + +textarea:-ms-input-placeholder { + font-size: 12px; + color: #adabab; +} + +.profile-image img { + width: 100%; +} + +@media screen and (max-width: 1169px) { + .horizontal-layout { + .sidebar { + display: block; + } + + .top-sidebar { + display: none; + } + + section.content { + margin-top: 100px; + } + } +} + +.font-icon { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 20px; + padding: 10px; + transition: all 0.2s; + + .icon-preview { + font-size: 1.8rem; + margin-right: 10px; + line-height: 1; + color: #333439; + } +} + +.deshboard-echart-height { + height: 250px; +} +.pill-style { + font-size: 17px; + color: #a9a6a6; + padding-right: 5px; +} +.pill-timing { + width: 30%; +} + +@media screen and (min-width: 1400px) { + .boxed-layout .container { + width: 1370px; + max-width: 100%; + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_helpers.scss b/MyOffice.SPA/src/assets/scss/common/_helpers.scss new file mode 100644 index 0000000..12b1938 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_helpers.scss @@ -0,0 +1,164 @@ +@use "sass:math"; +@for $i from -25 through 25 { + .m-l-#{$i * 5} { + margin-left: #{$i * 5}px; + } + + .m-t-#{$i * 5} { + margin-top: #{$i * 5}px; + } + + .m-r-#{$i * 5} { + margin-right: #{$i * 5}px; + } + + .m-b-#{$i * 5} { + margin-bottom: #{$i * 5}px; + } +} + +.margin-0 { + margin: 0; +} + +@for $i from 0 through 25 { + .p-l-#{$i * 5} { + padding-left: #{$i * 5}px; + } + + .p-t-#{$i * 5} { + padding-top: #{$i * 5}px; + } + + .p-r-#{$i * 5} { + padding-right: #{$i * 5}px; + } + + .p-b-#{$i * 5} { + padding-bottom: #{$i * 5}px; + } +} +@for $i from 0 through 25 { + .margin-#{$i * 5} { + margin: #{$i * 5}px; + } + .padding-#{$i * 5} { + padding: #{$i * 5}px; + } +} + +.padding-0 { + padding: 0; +} + +@for $i from 5 through 49 { + .font-#{$i + 1} { + font-size: #{$i + 1}px; + } +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +.align-justify { + text-align: justify; +} + +.no-resize { + resize: none; +} + +.font-bold { + font-weight: bold; +} + +.font-italic { + font-style: italic; +} + +.font-underline { + text-decoration: underline; +} + +.font-line-through { + text-decoration: line-through; +} + +.font-overline { + text-decoration: overline; +} + +.block-header { + //margin-bottom: 15px; + + h2 { + margin: 0 !important; + color: #666 !important; + font-weight: normal; + font-size: 22px; + line-height: 46px; + + small { + display: block; + font-size: 12px; + margin-top: 8px; + color: #888; + + a { + font-weight: bold; + color: #777; + } + } + } +} + +@each $key, $val in $colors { + .bg-#{$key} { + background-color: $val !important; + color: #fff; + + .content { + .text, + .number { + color: #fff !important; + } + } + } +} + +@each $key, $val in $linear-colors { + .l-bg-#{$key} { + background: $val !important; + color: #fff; + + .content { + .text, + .number { + color: #fff !important; + } + } + } +} + +@each $key, $val in $colors { + .col-#{$key} { + color: $val !important; + } +} +@for $i from 0 through 100 { + .width-per-#{$i} { + width: round(percentage(math.div($i, 100))); + } + .tbl-col-width-per-#{$i} { + max-width: round(percentage(math.div($i, 100))); + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_media.scss b/MyOffice.SPA/src/assets/scss/common/_media.scss new file mode 100644 index 0000000..24868d0 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_media.scss @@ -0,0 +1,367 @@ +/* + * Document : _media.scss + * Author : RedStar Template + * Description: This scss file for media queries classes + */ +@media (max-width: 1169px) { + // .sidemenu-collapse { + // display: none !important; + // } + .ls-closed .sidebar { + margin-left: -300px; + } + section.content { + margin: 83px 15px 0 0px; + } + .search-box { + margin-left: 25px; + } + .side-closed.submenu-closed .navbar-header { + width: 260px !important; + .navbar-brand span { + display: inline-block !important; + } + } + nav.navbar { + width: calc(100% - 4rem) !important; + } + .navbar .collapse-menu-icon { + display: block !important; + } + .sidebar .sidemenu-collapse { + display: none !important; + } +} +@media (max-width: 800px) { + .responsive_table { + overflow-x: auto !important; + } + + .mat-table { + min-width: 800px; + } +} + +@media (max-width: 799px) { + .navbar { + .search-box { + margin-left: 20px; + } + // .nav > li > a { + // padding: 10px 10px; + // } + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + &.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + } + .navbar-toggle { + display: none; + } + .navbar-nav { + float: left; + margin: 0; + > li { + float: left; + > a { + padding-top: 15px; + padding-bottom: 15px; + } + } + } + + .container > { + .navbar-header { + margin-right: 0; + margin-left: 0; + } + .navbar-collapse { + margin-right: 0; + margin-left: 0; + } + } + .container-fluid > { + .navbar-header { + margin-right: 0; + margin-left: 0; + } + .navbar-collapse { + margin-right: 0; + margin-left: 0; + } + } + .navbar > { + .container .navbar-brand { + margin-left: -15px; + } + .container-fluid .navbar-brand { + margin-left: -15px; + } + } +} +.container > { + .navbar-header { + margin-right: -15px; + margin-left: -15px; + } + .navbar-collapse { + margin-right: -15px; + margin-left: -15px; + } +} +.container-fluid > { + .navbar-header { + margin-right: -15px; + margin-left: -15px; + border-right: 1px solid #f2f4f9; + } + .navbar-collapse { + margin-right: -15px; + margin-left: -15px; + } +} +@media (max-width: 767px) { + .navbar { + height: auto; + > .container, + > .container-fluid { + .navbar-brand { + margin-left: 30px; + width: 88%; + margin-right: 0; + } + } + + .navbar-toggle { + float: right; + } + + .nav-left-menu { + display: none; + } + + .navbar-right { + .fullscreen { + display: none; + } + } + + .navbar-header { + display: inline-block; + // margin-bottom: -25px; + width: calc(100% + 30px); + float: left; + } + + .nav { + > li { + display: inline-block; + > a { + // padding: 13px 15px 8px 15px; + &.js-right-sidebar { + padding: 9px 8px 8px 15px; + } + } + } + } + + .navbar-nav { + // margin-top: -10px; + margin-bottom: 1px; + margin-left: -7px; + + .open { + .dropdown-menu { + background-color: #fff; + position: absolute; + } + } + } + + .dropdown-menu { + margin-left: -50px; + } + + .navbar-collapse { + display: block; + } + } + .side-closed.submenu-closed .navbar-header { + width: calc(100% + 30px) !important; + } + .side-closed.submenu-closed .navbar-header .navbar-brand span { + display: inline-block !important; + } + .dt-buttons { + float: none !important; + text-align: center; + margin-bottom: 15px; + } + + .panel-switch-btn { + top: 12px; + right: 0 !important; + } + .rtl { + .navbar { + .navbar-toggle { + float: left; + margin-left: 15px; + margin-right: 0; + } + .navbar-header { + margin-bottom: 0px; + } + } + } + section.content, + body.ls-closed section.content { + margin-right: 0px; + margin-left: 0px; + } +} +@media (max-width: 600px) { + .navbar { + > .container, + > .container-fluid { + .navbar-brand { + /*width: 86%;*/ + } + } + .navbar-header { + margin-bottom: 0; + } + .navbar-toggle:before { + margin-top: 2px; + float: left; + } + // .nav-notification-icons { + // margin-top: 7px; + // } + } + .ls-closed .bars:after, + .ls-closed .bars:before { + margin-top: 2px; + } +} +@media (max-width: 500px) { + .navbar-nav { + &.nav { + .dropdown-menu { + width: 245px; + right: -80px; + &::before { + right: 95px; + } + &::after { + right: 96px; + } + } + .user_profile { + .dropdown-menu { + &::before { + right: 19px; + } + &::after { + right: 20px; + } + } + } + } + } + .navbar { + > .container, + > .container-fluid { + .navbar-brand { + margin-left: 28px; + width: 84%; + } + } + } + .breadcrumb-chart { + margin: 0 0 0 20px; + } + .search-box { + display: none; + } + full-calendar > div.fc-toolbar { + display: block !important; + } +} +@media (max-width: 420px) { + .navbar { + > .container, + > .container-fluid { + .navbar-brand { + width: 79%; + } + } + } + .btnAppList { + display: none; + } +} +@media (max-width: 350px) { + .navbar { + .nav { + > li { + > a { + padding: 13px 10px 8px 10px; + &.js-right-sidebar { + padding: 9px 10px 8px 10px; + } + } + } + .user_profile { + .dropdown-toggle { + padding: 7px 0px 9px 10px; + } + } + } + > .container-fluid { + .navbar-brand { + margin-left: 25px; + } + } + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .navbar { + > .container, + > .container-fluid { + .navbar-brand { + margin-left: 20px; + } + } + } +} + +@media (min-width: 992px) and (max-width: 1169px) { + .navbar { + > .container, + > .container-fluid { + .navbar-brand { + margin-left: 20px; + } + } + } +} + +@media (min-width: 1170px) and (max-width: 1999px) { +} + +@media (min-width: 1200px) { +} diff --git a/MyOffice.SPA/src/assets/scss/common/_mixins.scss b/MyOffice.SPA/src/assets/scss/common/_mixins.scss new file mode 100644 index 0000000..ba9a5d6 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_mixins.scss @@ -0,0 +1,70 @@ +@mixin border-radius($radius) { + -webkit-border-radius: $radius; + -moz-border-radius: $radius; + -ms-border-radius: $radius; + border-radius: $radius; +} + +@mixin box-shadow($shadowinfo) { + -webkit-box-shadow: $shadowinfo; + -moz-box-shadow: $shadowinfo; + -ms-box-shadow: $shadowinfo; + box-shadow: $shadowinfo; +} +@mixin transform($transform) { + -moz-transform: $transform; + -ms-transform: $transform; + -o-transform: $transform; + -webkit-transform: $transform; + transform: $transform; +} + +@mixin transition($transition) { + -moz-transition: $transition; + -o-transition: $transition; + -webkit-transition: $transition; + transition: $transition; +} + +@mixin three-dots-overflow() { + white-space: nowrap; + -ms-text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + overflow: hidden; +} + +@mixin navbar-link-color($textcolor, $navbarcolor, $opacity) { + .navbar-brand, + .navbar-brand:hover, + .navbar-brand:active, + .navbar-brand:focus { + color: $textcolor; + } + + .nav > li > a:hover, + .nav > li > a:focus, + .nav .open > a, + .nav .open > a:hover, + .nav .open > a:focus { + background-color: transparentize($navbarcolor, $opacity); + } + + .nav > li > a { + color: $textcolor; + } + + .bars { + float: left; + padding: 10px 20px; + font-size: 22px; + color: $textcolor; + margin-right: 10px; + margin-left: -10px; + margin-top: 4px; + } + + .bars:hover { + background-color: rgba(0, 0, 0, 0.08); + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_rtl.scss b/MyOffice.SPA/src/assets/scss/common/_rtl.scss new file mode 100644 index 0000000..a213c35 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_rtl.scss @@ -0,0 +1,816 @@ +.rtl { + direction: rtl; + text-align: right; + .navbar { + right: unset; + left: 0; + .navbar-toggle { + float: left; + margin-left: 15px; + margin-right: 0; + } + + .navbar-header { + margin-bottom: 0px; + } + .navbar-left { + padding-right: 0px; + } + } + + .navbar-nav { + &.navbar-right { + float: left !important; + margin-left: 0px; + margin-right: unset; + display: flex !important; + flex-direction: unset; + + .user_profile { + margin: 0px 0px 0px 6px; + .user_img { + border-radius: 50%; + } + } + + // .lang-dropdown { + // margin: 14px 10px 0px 20px; + // } + } + .dropdown-menu { + left: 0; + right: auto !important; + } + .nfc-dropdown { + left: 0; + right: auto !important; + } + .nfc-dropdown::before { + left: 19px; + right: unset; + } + .nfc-dropdown::after { + left: 20px; + right: unset; + } + > li .js-right-sidebar { + margin-left: 0px; + margin-right: 0; + } + .user_profile .user_dw_menu li i { + float: right; + padding-left: 5px; + } + .app-dropdown { + left: unset !important; + right: 0 !important; + + &::before { + right: 19px !important; + left: unset !important; + } + &::after { + right: 20px !important; + left: unset !important; + } + } + } + section { + &.content { + margin: 55px 260px 0px 27px; + min-height: calc(100vh - 76px); + transition: 0.5s; + .content-block { + padding: 25px 25px 0px 0px; + } + } + } + .breadcrumb-main { + .page-title { + border-right: none; + padding-right: 0px; + &:after { + display: none; + } + &:before { + content: "\f104"; + font-family: "Font Awesome 5 Free"; + font-size: 18px; + font-weight: 900; + padding: 0px 5px; + } + } + .breadcrumb-list { + float: left; + } + li a .fa-home { + float: right; + padding-right: 10px; + padding-left: unset; + } + .breadcrumb-item + .breadcrumb-item { + padding-right: 5px; + padding-left: unset; + &:after { + content: "\f104"; + font-family: "Font Awesome 5 Free"; + font-size: 14px; + font-weight: 900; + padding-left: 0.5rem; + } + &:before { + display: none; + } + } + } + .sidebar { + right: 0; + .menu { + clear: right; + .list { + .menu-toggle { + &:after { + left: 17px; + right: unset; + } + &:before { + content: "\f053"; + left: 17px; + right: unset; + } + } + a { + padding: 9px 9px 9px 9px; + span { + margin: 7px 12px 7px 0; + } + .mat-button-wrapper { + margin: 7px 0 7px 12px; + } + .material-icons-two-tone { + float: right; + } + .sidebarIcon { + float: right; + margin-right: 5px; + } + } + .ml-menu { + li a { + padding-right: 55px; + padding-top: 7px; + padding-bottom: 7px; + margin-right: 0; + } + .ml-menu-2 { + padding-right: 55px; + li a { + padding-right: 20px; + padding-top: 4px; + padding-bottom: 4px; + } + } + .ml-menu-3 { + padding-right: 20px; + li a { + padding-right: 20px; + padding-top: 4px; + padding-bottom: 4px; + } + } + } + .ml-sub-menu:after, + .ml-sub-menu:before { + left: 17px; + right: unset; + } + .header { + margin: 15px 35px 5px 0 !important; + } + .ml-sub-menu2:after, + .ml-sub-menu2:before { + left: 17px; + right: unset; + } + } + } + .sidebar-badge { + left: 35px; + right: unset; + } + .nav { + padding-right: 0px; + .logo { + margin-left: auto; + margin-right: unset; + } + } + } + .sidemenu-reorder { + float: right; + } + .form-check { + .form-check-label { + padding-right: 30px; + } + .form-check-sign { + left: unset; + right: 0px; + padding-right: 0px; + } + } + .mat-radio-button ~ .mat-radio-button { + margin-right: 16px; + } + @media (min-width: 768px) { + .navbar-header { + float: right; + } + } + + .msl-1 { + margin-right: 0.25rem !important; + margin-left: unset !important; + } + .msl-2 { + margin-right: 0.5rem !important; + margin-left: unset !important; + } + .msl-3 { + margin-right: 1rem !important; + margin-left: unset !important; + } + .msl-4 { + margin-right: 1.5rem !important; + margin-left: unset !important; + } + .msl-5 { + margin-right: 3rem !important; + margin-left: unset !important; + } + + .msr-1 { + margin-left: 0.25rem !important; + margin-right: unset !important; + } + .msr-2 { + margin-left: 0.5rem !important; + margin-right: unset !important; + } + .msr-3 { + margin-left: 1rem !important; + margin-right: unset !important; + } + .msr-4 { + margin-left: 1.5rem !important; + margin-right: unset !important; + } + .msr-5 { + margin-left: 3rem !important; + margin-right: unset !important; + } + + .psl-1 { + padding-right: 0.25rem !important; + padding-left: unset !important; + } + .psl-2 { + padding-right: 0.5rem !important; + padding-left: unset !important; + } + .psl-3 { + padding-right: 1rem !important; + padding-left: unset !important; + } + .psl-4 { + padding-right: 1.5rem !important; + padding-left: unset !important; + } + .psl-5 { + padding-right: 3rem !important; + padding-left: unset !important; + } + + .psr-1 { + padding-left: 0.25rem !important; + padding-right: unset !important; + } + .psr-2 { + padding-left: 0.5rem !important; + padding-right: unset !important; + } + .psr-3 { + padding-left: 1rem !important; + padding-right: unset !important; + } + .psr-4 { + padding-left: 1.5rem !important; + padding-right: unset !important; + } + .psr-5 { + padding-left: 3rem !important; + padding-right: unset !important; + } + + &.side-closed { + &.side-closed-hover { + section.content { + margin-right: 260px; + margin-left: 27px; + } + .sidebar .menu .list { + .ml-menu { + li a { + padding-right: 55px; + :before { + padding-right: 40px; + } + } + .ml-menu-2 { + padding-right: 55px; + li a { + padding-right: 20px; + } + } + } + li { + i { + float: right; + line-height: 2rem; + } + span { + display: block; + float: right; + } + .sidebarIcon { + float: right; + } + } + li .menu-toggle:before { + content: "\f053"; + } + } + } + section.content { + margin-right: 60px; + margin-left: 27px; + } + .navbar-brand { + margin-right: 5px; + } + a .sidebarIcon { + margin-right: 0px !important; + } + } + .card .header .header-dropdown { + left: 0px; + right: unset; + } + .dropdown-menu ul.menu { + .msg-user { + float: right; + } + .menu-info { + right: 10px; + float: right; + text-align: right; + .menu-desc .material-icons { + float: right; + margin-left: 3px; + } + } + li a { + float: right; + } + } + .right-sidebar { + &.open { + left: 0; + right: unset; + } + .rightSidebarClose { + right: 5px; + left: unset; + } + } + .collapse-menu-icon { + float: right !important; + } + .list-unstyled { + padding-right: 0; + } + .review-img { + padding-left: 0 !important; + padding-right: 20px; + } + .progress-percent { + float: left !important; + } + .todo-actionlist { + left: 0; + } + .ngxTableHeader { + .header-buttons-left { + right: -15px; + li { + margin-right: 10px; + } + .search-icon { + left: 0; + } + } + .header-buttons { + left: 35px; + right: unset; + } + } + #mail-nav { + #mail-folders { + padding-right: 0; + .badge { + float: left; + } + } + #mail-labels { + padding-right: 0; + } + #online-offline { + padding-right: 0; + } + } + .chat { + .chat-header { + img { + float: right; + } + .chat-about { + float: right; + padding-right: 10px; + } + } + .chat-history .my-message:after { + right: 7%; + } + } + .owl-carousel { + direction: ltr; + .owl-item { + direction: rtl; + } + } + .bx-wrapper { + direction: ltr; + } + .lg-outer { + direction: ltr; + } + .rightSetting p { + text-align: right; + } + .sidebar .menu .list { + padding-right: 0; + .active .ml-menu { + // padding-right: 30px; + margin-right: 0; + padding-left: 0px; + } + .ml-menu { + padding-right: 0; + li.active .ml-menu:before { + right: 30px; + left: unset; + content: "\f104"; + font-family: "Font Awesome 5 Free"; + } + .ml-menu-2 li.active a:not(.menu-toggle):before { + right: 0px; + left: unset; + } + } + .ml-menu-3 li.active .ml-menu3:before { + content: "\f104"; + } + } + .notice-board .notice-body { + padding: 0 10px 5px 0; + } + .ngx-datatable.material .datatable-footer .datatable-pager { + text-align: left; + } + .people-list img { + float: right; + } + .cd-timeline-img img { + right: 10%; + } + .navbar-header .bars:before { + right: 10px; + left: unset; + } + .navbar-brand { + margin-right: 60px; + span { + padding-left: unset; + padding-right: 10px; + } + } + .dropdown-menu ul.menu { + padding-right: 0; + } + .navbar-nav .user_profile .user_dw_menu { + padding-right: 0; + text-align: right; + } + .progress-list .status { + left: 0; + right: unset; + } + .to-do-list { + padding-right: 0px; + } + .materialTableHeader { + .tbl-export-btn { + left: 20px; + right: unset; + float: left; + } + .header-buttons-left { + padding-right: 0px; + .tbl-title { + margin-right: 20px; + margin-left: 0px; + } + + .tbl-search-box { + margin-right: 10px; + } + .search-icon { + padding-right: 10px; + padding-left: unset; + } + + input.search-field { + padding: 8px 50px 8px 8px; + } + } + } + #mail-nav #mail-labels li { + float: right; + } + #mail-nav #online-offline .material-icons { + padding: 0px 5px 2px 5px; + } + .chat-upload { + float: left; + } + .modal-header .close { + margin-left: 0px; + } + .modal-close-button { + left: 10px; + right: unset; + } + .owl-dt-container { + direction: rtl; + } + + .owl-dt-control-arrow-button svg { + transform: rotate(180deg); + } + .card-statistic-4 { + .card-spacing { + padding-right: 15px; + padding-top: 1rem; + } + } + .card-statistic-3 .card-icon { + left: -5px; + right: unset; + margin-left: 0px; + } + .card-statistic-2 .card-right { + float: left; + margin: 15px 0px 15px 15px; + } + .post-user { + .avtar-img { + float: right; + margin-left: 15px; + margin-right: unset; + } + } + .info-box6 { + .count-numbers { + left: 35px; + right: unset; + } + .count-name { + left: 35px; + right: unset; + } + } + + .feedBody { + border-right: 1px solid #d6d6d6; + border-left: unset; + margin-right: 30px; + margin-left: unset; + padding-right: 0px; + padding-left: unset; + li { + padding-left: unset; + padding-right: 30px; + .feed-user-img { + right: -20px; + left: unset; + } + } + } + .sl-item { + border-right: 1px solid #13b1e0; + border-left: unset; + padding-right: 15px; + padding-left: unset; + &::before { + right: -6.5px; + left: unset; + } + } + .task-module .header-button { + margin-right: auto; + margin-left: unset; + } + .task-list { + .task-low { + margin-right: auto; + margin-left: unset; + } + + .task-high { + margin-right: auto; + margin-left: unset; + } + + .task-normal { + margin-right: auto; + margin-left: unset; + } + } + .task-container .header .header-close { + left: 15px; + right: unset; + } + .form-check .form-check-sign .check:before { + margin-right: 10px; + margin-left: unset; + } + .top-sell { + .product-title { + margin-right: 20px; + } + .product-price { + margin-right: 20px; + } + .sell-price { + float: left; + } + } + .doc-file-type .media-cta { + margin-left: 15px; + } + .lang-dropdown { + margin-left: 0px; + .country-name { + margin-right: 5px; + } + } + .lang-item .lang-item-list { + text-align: right; + line-height: 15px; + display: block; + .flag-img { + float: right; + margin: 5px 0px 0px 5px; + } + } + &.ls-closed .sidebar { + margin-right: -300px; + margin-left: unset; + } + &.ls-closed section.content { + margin-right: 15px; + margin-left: 15px; + } + &.overlay-open.ls-closed .sidebar { + margin-right: 0; + margin-left: unset; + } + + .btn-space { + margin-left: 10px !important; + } + .ms-auto { + margin-right: auto !important; + margin-left: unset !important; + } + .float-end { + float: left !important; + } + .float-start { + float: right !important; + } + .text-end { + text-align: left !important; + } + .text-start { + text-align: right !important; + } + .settingSidebar { + left: -280px; + right: unset; + &.showSettingPanel { + left: 0; + right: unset; + } + + .settingPanelToggle { + background: #6777ef; + padding: 10px 15px; + color: #fff; + position: absolute; + top: 30%; + left: 280px; + width: 40px; + border-radius: 0px 10px 10px 0px; + } + } + .hiddenradio { + padding: 0px 0px 0px 20px; + margin: 10px 10px 0px 20px; + } + + .card-bnner { + img { + transform: scaleX(-1); + } + } + .user_img { + margin: 0px 0px 0px 5px; + } + &.side-closed .sidebar .menu .list li a { + padding-right: 9px; + } + + .nfc-menu { + right: auto; + left: unset; + .nfc-dropdown .menu { + .msg-user { + float: right; + } + .menu-info { + margin-right: 20px; + float: right; + text-align: right; + .menu-desc .material-icons { + float: right; + margin-left: 3px; + } + } + li a { + float: right; + } + } + } + + .mat-menu-item .user-menu-icons { + float: right; + } + .profile-menu .menu .user_dw_menu .mdc-list-item { + display: block; + .user-menu-icons { + float: right; + } + } + .order-list li + li { + margin-left: unset; + margin-right: -14px; + } + .info-card { + text-align: left; + } + .mdc-linear-progress__bar-inner { + left: 0px; + } + .ng-scrollbar-wrapper { + direction: rtl; + } +} + +@media (max-width: 1169px) { + .rtl { + .sidemenu-collapse { + display: none !important; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/common/_variables.scss b/MyOffice.SPA/src/assets/scss/common/_variables.scss new file mode 100644 index 0000000..3a7718c --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/common/_variables.scss @@ -0,0 +1,34 @@ +$colors: ( + "red": #f44336, + "pink": #e91e63, + "purple": #6f42c1, + "indigo": #3f51b5, + "blue": #2196f3, + "cyan": #00bcd4, + "teal": #009688, + "green": #4caf50, + "yellow": #ffe821, + "orange": #fd7e14, + "deep-orange": #ff5722, + "brown": #795548, + "grey": #9e9e9e, + "black": #000000, + "white": #ffffff, +) !default; + +$linear-colors: ( + "green": linear-gradient(45deg, #9ce89d, #cdfa7e), + "orange": linear-gradient(135deg, #ffc480, #ff763b), + "cyan": linear-gradient(45deg, #72c2ff, #86f0ff), + "red": linear-gradient(316deg, #fc5286, #fbaaa2), + "purple": linear-gradient(230deg, #759bff, #843cf6), + "purple-dark": linear-gradient(45deg, #a52dd8, #e29bf1), + "card1": linear-gradient(to left, #3a7bd5, #3a6073), + "card2": linear-gradient(to right, #c33764, #1d2671), + "card3": linear-gradient(to left, #134e5e, #71b280), + "card4": linear-gradient(to left, #d38312, #a83279), +); + +//Fonts Family +$navbar-font-family: "Roboto", sans-serif; +$sidebar-font-family: "Roboto", sans-serif; diff --git a/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss b/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss new file mode 100644 index 0000000..4721d45 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_breadcrumbs.scss @@ -0,0 +1,159 @@ +/* + * Document : _breadscrumbs.scss + * Author : RedStar Template + * Description: This scss file for breadscrumbs style classes + */ + +.breadcrumb-main { + // background-color: transparent; + // font-size: 15px; + // align-items: center; + // margin: 3rem 0 3rem; + // padding: 0px; + // color: #555; + + // &:before { + // content: ""; + // margin: 0; + // } + + .breadcrumb-title { + background-color: transparent; + font-size: 15px; + align-items: center; + margin: 30px 0px; + padding: 0px; + color: #555; + } + .breadcrumb-list { + background-color: transparent; + font-size: 15px; + align-items: center; + margin: 32px 0px; + float: right; + color: #555; + padding: 0px 5px; + } + + li { + display: inline-block; + a { + color: #444; + text-decoration: none; + + .fa-home { + font-size: 17px; + position: relative; + top: 0; + float: left; + padding-left: 10px; + color: #5798f7; + } + } + + .material-icons { + font-size: 18px; + position: relative; + top: 4px; + float: none; + } + &.active { + color: #444444; + } + } + + > li + li:before { + // content: "/" !important; + // color: #444444; + // padding-left: 5px; + } + .page-title { + // border-right: 1px solid #c5c5c5; + // padding-right: 10px; + font-size: 20px; + font-weight: 500; + color: #444444; + margin-bottom: 0px; + // &:after { + // content: "\f105"; + // font-family: "Font Awesome 5 Free"; + // font-size: 18px; + // font-weight: 900; + // padding: 0px 5px; + // } + i { + padding: 0px 5px; + &:before { + color: #717883; + font-size: 20px; + } + } + } + .breadcrumb-item + .breadcrumb-item { + padding-left: 5px; + &:before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 14px; + display: block; + font-weight: 900; + padding-right: 0.5rem; + } + } +} + +@each $key, $val in $colors { + .breadcrumb-col-#{$key} { + li { + a { + color: $val !important; + font-weight: bold; + } + } + } + + .breadcrumb-bg-#{$key} { + background-color: $val !important; + + li { + a { + color: #fff; + font-weight: bold; + + .material-icons { + padding-bottom: 8px; + } + } + + color: #fff !important; + } + + li + li:before { + color: #fff; + } + } +} +.breadcrumb-style { + border-radius: 30px; + /*background: #ffffff; + padding-left: 20px !important;*/ +} +.breadcrumb-chart { + display: inline-block; + .chart-info p { + font-size: 13px; + } +} +.breadcrumb-icon { + vertical-align: top; + height: 18px !important; + width: 18px !important; + margin: 0px 3px; + .feather { + width: 18px; + height: 18px; + color: #2c323f; + position: relative; + float: left; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss b/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss new file mode 100644 index 0000000..55fbea2 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_checkboxradio.scss @@ -0,0 +1,139 @@ +/* + * Document : _checkboxradio.scss + * Author : RedStar Template + * Description: This scss file for checkbox and radio button style classes + */ +[type="checkbox"] { + +label { + padding-left: 26px; + height: 25px; + line-height: 21px; + font-size: 13px; + font-weight: normal; + vertical-align: middle; + } + + &:checked { + +label { + &:before { + top: -4px; + left: -2px; + width: 11px; + height: 19px; + } + } + } + + @each $key, + $val in $colors { + &:checked.chk-col-#{$key} { + +label { + &:before { + border-right: 2px solid $val; + border-bottom: 2px solid $val; + } + } + } + } +} + +@each $key, +$val in $colors { + :checked.chk-col-#{$key} { + +span { + &:after { + color: $val; + } + } + } +} + +[type="checkbox"].filled-in { + &:checked { + +label { + &:after { + top: 0; + width: 20px; + height: 20px; + border: 2px solid #26a69a; + background-color: #26a69a; + z-index: 0; + } + + &:before { + border-right: 2px solid #fff !important; + border-bottom: 2px solid #fff !important; + } + } + } + + @each $key, + $val in $colors { + &:checked.chk-col-#{$key} { + +label { + &:after { + border: 2px solid $val; + background-color: $val; + } + } + } + } +} + +[type="radio"] { + &:not(:checked) { + +label { + padding-left: 26px; + height: 25px; + line-height: 25px; + font-size: 13px; + font-weight: normal; + } + } + + &:checked { + +label { + padding-left: 26px; + height: 25px; + line-height: 25px; + font-size: 13px; + font-weight: normal; + } + } + + +label { + vertical-align: middle; + } +} + +@each $key, +$val in $colors { + [type="radio"].radio-col-#{$key} { + &:checked { + +label { + &:after { + background-color: $val; + border-color: $val; + } + } + } + } +} + +@each $key, +$val in $colors { + [type="radio"].with-gap.radio-col-#{$key} { + &:checked { + +label { + &:before { + border: 2px solid $val; + } + + &:after { + background-color: $val; + border: 2px solid $val; + } + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss b/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss new file mode 100644 index 0000000..4f21eff --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_dropdownmenu.scss @@ -0,0 +1,338 @@ +/* + * Document : _dropdownmenu.scss + * Author : RedStar Template + * Description: This scss file for dropdown menu style classes + */ +.dropdown-menu { + @include border-radius(0); + margin-top: -35px !important; + margin-left: -15px; + -webkit-box-shadow: 0 5px 15px 2px rgba(64, 70, 74, 0.2) !important; + box-shadow: 0 5px 15px 2px rgba(64, 70, 74, 0.2) !important; + border-radius: 0px; + border: none; + padding: 0px; + + .divider { + margin: 5px 0; + } + + .header { + font-size: 13px; + font-weight: bold; + width: 100%; + border-bottom: 1px solid #eee; + text-align: center; + padding: 4px 0 6px 0; + } + + .footer { + a { + text-align: center; + border-top: 1px solid #eee; + padding: 10px 0 5px 0; + font-size: 13px; + margin-bottom: -5px; + color: #ff5e00; + font-weight: 500; + + &:hover { + background-color: transparent; + } + } + } + + > li { + > a { + padding: 7px 18px; + color: #666; + @include transition(all 0.5s); + font-size: 14px; + line-height: 25px; + display: block; + + &:hover { + background-color: rgba(0, 0, 0, 0.075); + } + + i.material-icons { + float: left; + margin-right: 7px; + margin-top: 2px; + font-size: 20px; + } + } + } +} + +.app-dropdown { + width: 350px; + max-width: 350px !important; + .nfc-header { + padding: 20px; + background-color: #7366ff; + border-radius: 5px 5px 0px 0px; + h5 { + color: #fff; + } + } + .app-icons { + display: block; + border-radius: 3px; + line-height: 34px; + text-align: center; + padding: 15px 0 9px; + border: 1px solid transparent; + color: black; + font-weight: 500; + &:hover { + background-color: #eef4fd; + } + } + .mat-mdc-menu-content { + padding: 0px; + } +} + +.dropdown-content li > a, +.dropdown-content li > span { + font-size: 13px; + color: #636262; +} + +.dropdown-animated { + -webkit-animation-duration: 0.3s !important; + -moz-animation-duration: 0.3s !important; + -o-animation-duration: 0.3s !important; + animation-duration: 0.3s !important; +} + +.dropdown-menu.pull-right.show { + position: absolute !important; + left: auto !important; + right: 0 !important; + top: 50px !important; + transform: none !important; +} +.nfc-menu { + transform-origin: left top; + width: 325px; + max-width: 100vw !important; + right: 10px; + left: auto; + position: absolute !important; + top: 0; + padding: 0; + border-radius: 5px; + .nfc-dropdown { + .menu { + padding-left: 0; + button { + padding: 11px 11px; + text-decoration: none; + @include transition(0.5s); + float: left; + width: 100%; + height: 65px; + // border-bottom: 1px solid #eee; + margin-bottom: 2px; + + &:hover { + background-color: #eef4fd; + } + .mdc-list-item__primary-text { + width: 100%; + } + } + + &.tasks { + h4 { + color: #333; + font-size: 13px; + margin: 0 0 8px 0; + + small { + float: right; + margin-top: 6px; + } + } + + .progress { + height: 7px; + margin-bottom: 7px; + } + } + + .icon-circle { + width: 36px; + height: 36px; + @include border-radius(50%); + color: #fff; + text-align: center; + display: inline-block; + float: left; + + i { + font-size: 18px; + line-height: 36px !important; + } + } + + .msg-user { + width: 44px; + height: 44px; + @include border-radius(50%); + color: #fff; + text-align: center; + display: inline-block; + vertical-align: top; + float: left; + + img { + float: left; + } + } + + li { + &:last-child { + border-bottom: none; + } + } + + .menu-info { + display: inline-block; + position: relative; + top: 3px; + left: 10px; + float: left; + width: calc(100% - 75px); + + h4, + .menu-title { + margin: 0; + font-size: 14px; + color: #121212; + float: left; + width: 100%; + line-height: 1; + } + + p, + .menu-desc { + margin: 0; + font-size: 11px; + color: rgba(0, 0, 0, 0.54); + float: left; + width: 100%; + line-height: 20px; + + .material-icons { + font-size: 13px; + color: rgba(0, 0, 0, 0.54); + position: relative; + top: 3px; + float: left; + margin-right: 3px; + height: 20px; + } + } + } + .nfc-close { + display: flex; + height: 40px; + line-height: 40px; + .feather { + color: #747474; + height: 12px !important; + width: 12px !important; + } + } + .nfc-type-icon { + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + &.nfc-green { + filter: invert(77%) sepia(4%) saturate(5247%) hue-rotate(85deg) + brightness(88%) contrast(95%); + } + &.nfc-blue { + filter: invert(67%) sepia(95%) saturate(5173%) hue-rotate(214deg) + brightness(101%) contrast(101%); + } + &.nfc-orange { + filter: invert(69%) sepia(81%) saturate(523%) hue-rotate(353deg) + brightness(101%) contrast(102%); + } + &.nfc-purple { + filter: invert(19%) sepia(98%) saturate(7474%) hue-rotate(284deg) + brightness(105%) contrast(117%); + } + &.nfc-red { + filter: invert(24%) sepia(94%) saturate(7102%) hue-rotate(356deg) + brightness(103%) contrast(100%); + } + } + .msg-unread { + background-color: #f5f9ff; + border-bottom: 1px solid #eee; + } + .msg-read { + border-bottom: 1px solid #eee; + } + } + } + .mat-menu-content { + padding-top: 0px !important; + padding-bottom: 0px !important; + } + .nfc-header { + padding: 20px; + background-color: #7366ff; + border-radius: 5px 5px 0px 0px; + display: flex; + h5 { + color: #fff; + } + } + + .nfc-mark-as-read { + display: block; + text-align: right; + color: #ffffff; + float: right; + width: 100%; + font-size: 12px !important; + } + .nfc-footer { + line-height: 50px; + cursor: pointer; + text-align: center; + border-top: 1px solid rgba(0, 0, 0, 0.15); + + .nfc-read-all { + color: rgb(106 106 106); + } + } + .mat-mdc-menu-content { + padding: 0px; + } +} +.profile-menu { + width: 200px; + max-width: 200px !important; + right: 10px; + + .user-menu-icons .feather { + height: 18px !important; + width: 18px !important; + vertical-align: middle; + } + .mat-mdc-menu-content { + padding: 0px; + } +} +.lang-item-menu .mat-mdc-menu-content { + padding: 0px; +} diff --git a/MyOffice.SPA/src/assets/scss/components/_feed.scss b/MyOffice.SPA/src/assets/scss/components/_feed.scss new file mode 100644 index 0000000..cdec4ea --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_feed.scss @@ -0,0 +1,189 @@ +/* + * Document : _feed.scss + * Author : RedStar Template + * Description: This scss file for feed style classes + */ +.feedBody { + border-left: 1px solid #d6d6d6; + margin-left: 30px; + padding-top: 10px; + padding-left: 0px; +} + +.col-auto { + padding-left: 15px; + padding-right: 15px; +} + +.feedLblStyle { + font-weight: bold; + padding: 0px 7px 0px 7px; + border-radius: 10px; +} + +.lblFileStyle { + color: red; + border: 1px solid red; +} + +.lblTaskStyle { + color: #2ed8b6; + border: 1px solid #2ed8b6; +} + +.lblCommentStyle { + color: #4099ff; + border: 1px solid #4099ff; +} + +.lblReplyStyle { + color: #f15317; + border: 1px solid #f15317; +} + +.feedBody li { + position: relative; + padding-left: 30px; + margin-bottom: 25px; +} + +.feedBody li .feed-user-img { + position: absolute; + left: -20px; + top: -10px; +} + +.feedBody li .feed-user-img img { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.feedBody li.active-feed .feed-user-img:after { + border-color: #2ed8b6; +} + +.feedBody li .feed-user-img:after { + content: ""; + position: absolute; + top: 3px; + right: 3px; + border: 3px solid transparent; + border-radius: 50%; +} + +.feedBody li h6 { + line-height: 1.5; + cursor: pointer; +} + +.text-muted { + color: #96a2b4 !important; + margin-bottom: 10px; +} + +.img-100 { + width: 100px; +} + +.feedBody li h6 { + line-height: 1.5; + cursor: pointer; +} + +.feedBody li.active-feed .feed-user-img:after { + border-color: #2ed8b6; +} + +.sl-item { + border-left: 1px solid #13b1e0; + padding-bottom: 1px; + padding-left: 15px; + position: relative; + + &:last-child::after { + //Instead of the line below you could use @include border-radius($radius, $vertical-radius) + border-radius: 100%; + bottom: 0; + content: ""; + height: 6px; + left: -3px; + position: absolute; + width: 6px; + } + + .sl-content { + i { + font-size: 12px; + } + + small { + position: relative; + top: -4px; + } + + p { + padding-bottom: 4px; + position: relative; + } + } +} + +.sl-item::before { + background-color: #13b1e0; + border-radius: 100%; + content: ""; + height: 12px; + left: -6.5px; + position: absolute; + top: 0; + width: 12px; +} + +.sl-primary { + border-left-color: #2196f3; + + &:last-child::after { + background-color: #2196f3; + } +} + +.sl-primary::before { + background-color: #2196f3; +} + +.sl-danger { + border-left-color: #f44336; + + &:last-child::after { + background-color: #f44336; + } +} + +.sl-danger::before { + background-color: #f44336; +} + +.sl-success { + border-left-color: #4caf50; + + &:last-child::after { + background-color: #4caf50; + } +} + +.sl-success::before { + background-color: #4caf50; +} + +.sl-warning { + border-left-color: #ff5722; + + &:last-child::after { + background-color: #ff5722; + } +} + +.sl-warning::before { + background-color: #ff5722; +} diff --git a/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss b/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss new file mode 100644 index 0000000..bf97cfc --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_formcomponents.scss @@ -0,0 +1,60 @@ +@import "~@danielmoncada/angular-datetime-picker/assets/style/picker.min.css"; +.example-form { + min-width: 150px; + max-width: 500px; + width: 100%; +} + +.example-full-width { + width: 100%; +} +.example-h2 { + margin: 10px; +} + +.example-section { + display: flex; + align-content: center; + align-items: center; + height: 60px; +} + +.example-margin { + margin: 0 10px; +} + +.example-radio-group { + display: flex; + flex-direction: column; + margin: 15px 0; +} + +.example-radio-button { + margin: 5px; +} + +.advance-validation .error-msg { + margin-top: -15px; +} +.mat-radio-button ~ .mat-radio-button { + margin-left: 16px; +} +.mat-radio-label { + margin-bottom: 0px; +} +.mat-datepicker-content-touch .mat-calendar { + width: 50vh !important; + height: 57vh !important; +} +.mat-datepicker-toggle-default-icon { + width: 1.4em !important; +} +.mat-form-field { + .date-icon { + cursor: pointer; + } +} +.mat-form-field-prefix, +.mat-form-field-suffix { + color: rgba(0, 0, 0, 0.54); +} diff --git a/MyOffice.SPA/src/assets/scss/components/_infobox.scss b/MyOffice.SPA/src/assets/scss/components/_infobox.scss new file mode 100644 index 0000000..188ac5e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_infobox.scss @@ -0,0 +1,690 @@ +/* + * Document : _infobox.scss + * Author : RedStar Template + * Description: This scss file for info box style classes + */ +.info-box { + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + height: 80px; + display: flex; + cursor: default; + background-color: #fff; + position: relative; + overflow: hidden; + margin-bottom: 30px; + + .icon { + display: inline-block; + text-align: center; + background-color: rgba(0, 0, 0, 0.12); + width: 80px; + + i { + color: #fff; + font-size: 50px; + line-height: 80px; + } + + .chart.chart-bar { + height: 100%; + line-height: 100px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-pie { + height: 100%; + line-height: 123px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-line { + height: 100%; + line-height: 115px; + + canvas { + vertical-align: baseline !important; + } + } + } + + .content { + display: inline-block; + padding: 7px 10px; + + .text { + font-size: 13px; + margin-top: 11px; + color: #555; + } + + .number { + font-weight: normal; + font-size: 26px; + margin-top: -4px; + color: #555; + } + } +} + +.info-box.hover-zoom-effect { + .icon { + overflow: hidden; + + i { + @include transition(all 0.3s ease); + } + } + + &:hover { + .icon { + i { + opacity: 0.4; + @include transform(rotate(-32deg) scale(1.4)); + } + } + } +} + +.info-box.hover-expand-effect { + &:after { + background-color: rgba(0, 0, 0, 0.05); + content: "."; + position: absolute; + left: 80px; + top: 0; + width: 0; + height: 100%; + color: transparent; + @include transition(all 0.95s); + } + + &:hover { + &:after { + width: 100%; + } + } +} + +.info-box-2 { + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + height: 80px; + display: flex; + cursor: default; + background-color: #fff; + position: relative; + overflow: hidden; + margin-bottom: 30px; + + .icon { + display: inline-block; + text-align: center; + width: 80px; + + i { + color: #fff; + font-size: 50px; + line-height: 80px; + } + } + + .chart.chart-bar { + height: 100%; + line-height: 105px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-pie { + height: 100%; + line-height: 123px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-line { + height: 100%; + line-height: 115px; + + canvas { + vertical-align: baseline !important; + } + } + + .content { + display: inline-block; + padding: 7px 10px; + + .text { + font-size: 13px; + margin-top: 11px; + color: #555; + } + + .number { + font-weight: normal; + font-size: 26px; + margin-top: -4px; + color: #555; + } + } +} + +.info-box-2.hover-zoom-effect { + .icon { + overflow: hidden; + + i { + @include transition(all 0.3s ease); + } + } + + &:hover { + .icon { + i { + opacity: 0.4; + @include transform(rotate(-32deg) scale(1.4)); + } + } + } +} + +.info-box-2.hover-expand-effect { + &:after { + background-color: rgba(0, 0, 0, 0.05); + content: "."; + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + color: transparent; + @include transition(all 0.95s); + } + + &:hover { + &:after { + width: 100%; + } + } +} + +.info-box-3 { + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + height: 80px; + display: flex; + cursor: default; + background-color: #fff; + position: relative; + overflow: hidden; + margin-bottom: 30px; + + .icon { + position: absolute; + right: 10px; + bottom: 2px; + text-align: center; + + i { + color: rgba(0, 0, 0, 0.15); + font-size: 60px; + } + } + + .chart { + margin-right: 5px; + } + + .chart.chart-bar { + height: 100%; + line-height: 50px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-pie { + height: 100%; + line-height: 34px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-line { + height: 100%; + line-height: 40px; + + canvas { + vertical-align: baseline !important; + } + } + + .content { + display: inline-block; + padding: 7px 16px; + + .text { + font-size: 13px; + margin-top: 11px; + color: #555; + } + + .number { + font-weight: normal; + font-size: 26px; + margin-top: -4px; + color: #555; + } + } +} + +.info-box-3.hover-zoom-effect { + .icon { + i { + @include transition(all 0.3s ease); + } + } + + &:hover { + .icon { + i { + opacity: 0.4; + @include transform(rotate(-32deg) scale(1.4)); + } + } + } +} + +.info-box-3.hover-expand-effect { + &:after { + background-color: rgba(0, 0, 0, 0.05); + content: "."; + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + color: transparent; + @include transition(all 0.95s); + } + + &:hover { + &:after { + width: 100%; + } + } +} + +.info-box-4 { + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + height: 80px; + display: flex; + cursor: default; + background-color: #fff; + position: relative; + overflow: hidden; + margin-bottom: 30px; + + .icon { + position: absolute; + right: 10px; + bottom: 2px; + text-align: center; + + i { + color: rgba(0, 0, 0, 0.15); + font-size: 60px; + } + } + + .chart { + margin-right: 5px; + } + + .chart.chart-bar { + height: 100%; + line-height: 50px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-pie { + height: 100%; + line-height: 34px; + + canvas { + vertical-align: baseline !important; + } + } + + .chart.chart-line { + height: 100%; + line-height: 40px; + + canvas { + vertical-align: baseline !important; + } + } + + .content { + display: inline-block; + padding: 7px 16px; + + .text { + font-size: 13px; + margin-top: 11px; + color: #555; + } + + .number { + font-weight: normal; + font-size: 26px; + margin-top: -4px; + color: #555; + } + } +} + +.info-box-4.hover-zoom-effect { + .icon { + i { + @include transition(all 0.3s ease); + } + } + + &:hover { + .icon { + i { + opacity: 0.4; + @include transform(rotate(-32deg) scale(1.4)); + } + } + } +} + +.info-box-4.hover-expand-effect { + &:after { + background-color: rgba(0, 0, 0, 0.05); + content: "."; + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + color: transparent; + @include transition(all 0.95s); + } + + &:hover { + &:after { + width: 100%; + } + } +} +.info-box-new { + background: #fff; + padding: 20px 20px 0px 20px; + color: #463f3f; + border-radius: 15px; + + .progress { + height: 10px; + border-radius: 20px; + } +} +.support-box { + padding: 15px; + color: #fff; + margin: 8px 0px 25px 0px; + border-radius: 10px; + min-height: 140px; +} +.counter-box { + padding: 15px; + color: #212529; + margin: 8px 0px 25px 0px; + border-radius: 10px; + min-height: 140px; + background-color: #ffffff; + box-shadow: 0 5px 25px rgba(0, 0, 0, 0.1); +} +.info-box1 .text-end h2 { + color: #44e229; +} +.info-box2 .text-end h2 { + color: #e66c2f; +} +.info-box3 .text-end h2 { + color: #58b5f5; +} +.info-box4 .text-end h2 { + color: #ab92d4; +} + +.info-box5 { + width: 100%; + box-shadow: 0 5px 25px rgba(0, 0, 0, 0.1); + margin-bottom: 25px; + padding: 0px 20px 0 20px; + border-radius: 25px; + height: 110px; + display: flex; + cursor: default; + background-color: #fff; + position: relative; + overflow: hidden; + small { + font-size: 14px; + } + .progress { + background: rgba(0, 0, 0, 0.2); + margin: 5px -10px 5px 0; + height: 8px; + background: #e3e3e3; + border-radius: 20px; + box-shadow: none; + overflow: visible; + .progress-bar { + border-radius: 20px; + background: #fff; + } + } + .knob-icon { + margin-top: 16px; + } + .info-box-content { + margin-top: 24px; + margin-left: 10px; + } + .progress-bar { + position: relative; + animation: animate-positive 4s; + line-height: 8px; + } +} +.info-box6 { + box-shadow: 2px 2px 10px #dadada; + margin: 8px 0px 25px 0px; + padding: 20px 10px; + background-color: #fff; + height: 100px; + border-radius: 5px; + transition: 0.3s linear all; + &:hover { + //Instead of the line below you could use @include box-shadow($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10) + box-shadow: 4px 4px 20px #dadada; + //Instead of the line below you could use @include transition($transition-1, $transition-2, $transition-3, $transition-4, $transition-5, $transition-6, $transition-7, $transition-8, $transition-9, $transition-10) + transition: 0.3s linear all; + } + &.primary { + background-color: #007bff; + color: #fff; + } + &.danger { + background-color: #ef5350; + color: #fff; + } + &.success { + background-color: #66bb6a; + color: #fff; + } + &.info { + background-color: #26c6da; + color: #fff; + } + i { + font-size: 5em; + opacity: 0.2; + } + .count-numbers { + position: absolute; + right: 35px; + top: 20px; + font-size: 32px; + display: block; + } + .count-name { + position: absolute; + right: 35px; + top: 65px; + font-style: italic; + text-transform: capitalize; + opacity: 0.5; + display: block; + font-size: 18px; + } +} +.bg-c-blue { + background: linear-gradient(to right, #5b73e8, #44c4fa); +} +.bg-c-green { + background: linear-gradient(to right, #1d976c, #2fd38a); +} +.bg-c-yellow { + background: linear-gradient(45deg, #ffb64d, #ffcb80); +} +.bg-c-pink { + background: linear-gradient(45deg, #ff5370, #ff869a); +} +.bg-c-purple { + background: linear-gradient(to right, #664dc9, #9884ea); +} +.bg-c-orange { + background: linear-gradient(to right, #fa5420, #f6a800); +} +.info-box7 { + border-radius: 5px; + color: #fff; + box-shadow: 0 1px 2.94px 0.06px rgba(4, 26, 55, 0.16); + border: none; + margin: 8px 0px 25px 0px; + transition: all 0.3s ease-in-out; + .info-box7-block { + padding: 25px; + } +} +.order-info-box7 i { + font-size: 30px; +} +.box-part { + background: #fff; + border-radius: 10px; + padding: 30px 15px; + margin: 5px 0 23px; +} +.box-part { + background: #fff; + border-radius: 10px; + padding: 30px 15px; + margin: 5px 0 23px; +} +.infobox-5 { + .card-icon { + i { + font-size: 4rem; + } + } +} +.card-statistic-4 { + position: relative; + color: #000000; + padding: 15px; + border-radius: 3px; + overflow: hidden; + + .card-icon-large { + font-size: 110px; + width: 110px; + height: 50px; + text-shadow: 3px 7px rgba(0, 0, 0, 0.3); + } + + .card-icon { + text-align: center; + line-height: 50px; + margin-left: 15px; + color: #000; + position: absolute; + right: -5px; + top: 20px; + opacity: 0.1; + } + + .banner-img img { + max-width: 100%; + float: right; + } +} + +.info-card { + margin-top: 20px; + text-align: right; + + .info-box8 { + padding: 15px 20px; + } + .card1-icon { + width: 50px; + height: 50px; + position: absolute; + top: -15px; + font-size: 35px; + border-radius: 8px; + display: flex; + color: #fff; + align-items: center; + justify-content: center; + transition: all 0.3s ease-in-out; + } + .card-block > span { + color: #919aa3; + } + :hover .card1-icon { + top: -25px; + } +} + +@-webkit-keyframes animate-positive { + 0% { + width: 0; + } +} +@keyframes animate-positive { + 0% { + width: 0; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss b/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss new file mode 100644 index 0000000..1baa625 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_inputformgroup.scss @@ -0,0 +1,456 @@ +/* + * Document : _inputformgroup.scss + * Author : RedStar Template + * Description: This scss file for input form style classes + */ +%extend_check { + font-size: 13px; + line-height: 1.42857; + color: #414244; + font-weight: 400; +} + +.input-group { + width: 100%; + margin-bottom: 20px; + display: table; + + .form-line { + display: inline-block; + width: 100%; + //border-bottom: 1px solid #ddd; + position: relative; + + &:after { + content: ""; + position: absolute; + left: 0; + width: 100%; + bottom: 0px; + @include transform(scaleX(0)); + @include transition(0.25s ease-in); + border-bottom: 2px solid #1f91f3; + } + + +.input-group-addon { + padding-right: 0; + padding-left: 10px; + } + } + + .help-info { + float: right; + font-size: 12px; + margin-top: 5px; + color: #999; + } + + label.error { + font-size: 12px; + display: block; + margin-top: 5px; + font-weight: normal; + color: #f44336; + } + + .form-line.error { + &:after { + border-bottom: 2px solid #f44336; + } + } + + .form-line.success { + &:after { + border-bottom: 2px solid #4caf50; + } + } + + .form-line.warning { + &:after { + border-bottom: 2px solid #ffc107; + } + } + + .form-line.focused { + &:after { + @include transform(scaleX(1)); + } + + .form-label { + bottom: 25px; + left: 0; + font-size: 12px; + } + } + + .input-group-addon { + border: none; + background-color: transparent; + padding-left: 0; + font-weight: bold; + display: table-cell; + + .material-icons { + font-size: 18px; + color: #555; + } + } + + input[type="text"], + .form-control { + //border: none; + box-shadow: none; + padding-left: 0; + margin: 0; + font-size: 13px; + } + + .form-control { + &:focus { + @include box-shadow(none !important); + } + } +} + +.input-group.input-group-sm { + .input-group-addon { + i { + font-size: 14px; + } + } + + .form-control { + font-size: 12px !important; + } +} + +.input-group.input-group-lg { + .input-group-addon { + i { + font-size: 26px; + } + } + + .form-control { + font-size: 18px !important; + } +} + +.input-field { + >label:not(.label-icon).active { + font-size: 15px !important; + transform: translateY(-5px) scale(0.8); + } + + input, + textarea { + font-size: 13px !important; + } + + >label { + font-size: 13px !important; + } +} + +.form-control-label { + text-align: right; + + label { + margin-top: 8px; + } +} + +.form-horizontal { + .form-group { + margin-bottom: 0; + } +} + +.form-group { + width: 100%; + margin-bottom: 25px; + + .form-control { + width: 100%; + /* border: none; */ + box-shadow: none; + /* border-bottom: 1px solid #9e9e9e;*/ + @include border-radius(0); + padding-left: 0; + } + + input.form-control { + margin: 0; + font-size: 13px; + } + + .help-info { + float: right; + font-size: 12px; + margin-top: 5px; + color: #999; + } + + label.error { + font-size: 12px; + display: block; + margin-top: 5px; + font-weight: normal; + color: #f44336; + } + + .form-line { + width: 100%; + position: relative; + //border-bottom: 1px solid #ddd; + + &:after { + content: ""; + position: absolute; + left: 0; + width: 100%; + height: 0; + bottom: -1px; + @include transform(scaleX(0)); + @include transition(0.25s ease-in); + border-bottom: 2px solid #1f91f3; + } + + .form-label { + font-weight: normal; + color: #aaa; + position: absolute; + top: 10px; + left: 0; + cursor: text; + @include transition(0.2s); + } + } + + .form-line.error { + &:after { + border-bottom: 2px solid #f44336; + } + } + + .form-line.success { + &:after { + border-bottom: 2px solid #4caf50; + } + } + + .form-line.warning { + &:after { + border-bottom: 2px solid #ffc107; + } + } + + .form-line.focused { + &:after { + @include transform(scaleX(1)); + } + + .form-label { + top: -10px; + left: 0; + font-size: 12px; + } + } +} + +.form-group-sm { + .form-label { + font-size: 12px; + } + + .form-line.focused { + .form-label { + bottom: 20px; + font-size: 10px; + } + } +} + +.form-group-lg { + .form-label { + font-size: 18px; + } + + .form-line.focused { + .form-label { + bottom: 35px; + font-size: 12px; + } + } +} + +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: transparent; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} + +.show>.dropdown-menu { + display: block; +} + +.spinner { + .input-group-addon { + /*position: relative;*/ + position: absolute; + top: 10px; + right: 0; + + .spin-up i { + position: absolute; + left: 0; + } + + .spin-down i { + position: absolute; + left: 0; + bottom: -15px; + } + } +} + +.bootstrap-select { + .btn { + color: #333; + } +} + +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} + +.form-check { + @extend %extend_check; + margin-bottom: 0.5rem; + padding-left: 0; + + .form-check-label { + cursor: pointer; + padding-left: 25px; + position: relative; + padding-right: 15px; + + span { + display: block; + position: absolute; + left: -1px; + top: -1px; + transition-duration: 0.2s; + padding-left: 0; + } + } + + .form-check-input { + opacity: 0; + height: 0; + width: 0; + overflow: hidden; + position: absolute; + margin: 0; + z-index: -1; + left: 0; + pointer-events: none; + + &:checked+.form-check-sign { + &:before { + animation: rippleOn 0.5s; + } + + .check { + background: #9c27b0; + + &:before { + color: #ffffff; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, + 0 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + animation: checkboxOn 0.3s forwards; + } + } + } + } + + .form-check-sign { + vertical-align: middle; + position: relative; + top: -2px; + float: left; + padding-right: 10px; + display: inline-block; + + &:before { + display: block; + position: absolute; + left: 0; + content: ""; + background-color: rgba(0, 0, 0, 0.84); + height: 20px; + width: 20px; + border-radius: 100%; + z-index: 1; + opacity: 0; + margin: 0; + top: 0; + transform: scale3d(2.3, 2.3, 1); + } + + .check { + position: relative; + display: inline-block; + width: 20px; + height: 20px; + border: 1px solid rgba(0, 0, 0, 0.54); + overflow: hidden; + z-index: 1; + border-radius: 3px; + + &:before { + position: absolute; + content: ""; + transform: rotate(45deg); + display: block; + margin-top: -3px; + margin-left: 7px; + width: 0; + color: #ffffff; + height: 0; + animation: checkboxOff 0.3s forwards; + } + } + } +} + +label { + @extend %extend_check; +} + +.default-select { + select { + width: 100px; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + } + + .select-wrapper input.select-dropdown { + display: none; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_labels.scss b/MyOffice.SPA/src/assets/scss/components/_labels.scss new file mode 100644 index 0000000..8a2f508 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_labels.scss @@ -0,0 +1,35 @@ +/* + * Document : _labels.scss + * Author : RedStar Template + * Description: This scss file for label style classes + */ +.label { + @include border-radius(10px); + padding: 2px 10px; + color: #fff; + display: inline-block; +} + +.label-default { + background-color: #777; +} + +.label-primary { + background-color: #1f91f3; +} + +.label-success { + background-color: #2b982b; +} + +.label-info { + background-color: #00b0e4; +} + +.label-warning { + background-color: #ff9600; +} + +.label-danger { + background-color: #fb483a; +} diff --git a/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss b/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss new file mode 100644 index 0000000..3bc0b9e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_leftsidebaroverlay.scss @@ -0,0 +1,950 @@ +/* + * Document : _leftsidebaroverlay.scss + * Author : RedStar Template + * Description: This scss file for left side bar style classes + */ +.overlay { + position: fixed; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + z-index: 10; +} + +.overlay-open { + .sidebar { + margin-left: 0; + z-index: 99999999; + } +} + +.sidebar { + @include transition(all 0.5s); + font-family: $sidebar-font-family; + background: #ffffff; + width: 260px; + overflow: hidden; + display: inline-block; + height: calc(100vh - 0px); + position: fixed; + top: 0px; + left: 0; + border-right: 1px solid #f2f4f9; + -webkit-box-shadow: 0 8px 10px 0 rgba(183, 192, 206, 0.2); + box-shadow: 0 8px 10px 0 rgba(183, 192, 206, 0.2); + z-index: 999 !important; + + .user-info { + padding: 13px 15px 12px 15px; + white-space: nowrap; + position: relative; + border-bottom: 1px solid #e9e9e9; + height: 135px; + + .image { + margin-right: 12px; + display: inline-block; + + img { + @include border-radius(50%); + vertical-align: bottom !important; + } + } + + .info-container { + cursor: default; + display: block; + position: relative; + top: 25px; + + .name { + @include three-dots-overflow(); + font-size: 14px; + max-width: 200px; + color: #fff; + } + + .email { + @include three-dots-overflow(); + font-size: 12px; + max-width: 200px; + color: #fff; + } + + .user-helper-dropdown { + position: absolute; + right: -3px; + bottom: -12px; + @include box-shadow(none); + cursor: pointer; + color: #fff; + } + } + } + + .menu { + position: relative; + overflow-y: auto; + height: 100vh; + clear: left; + + .list { + list-style: none; + padding-left: 0; + + li { + &.active { + .menu-top { + background-color: #f0f3fb; + border-radius: 5px; + } + > :first-child { + span { + font-weight: 500; + } + } + } + &.active-top { + .menu-top { + background-color: #f0f3fb; + } + } + } + + .header { + font-size: 12px; + margin: 15px 0px 5px 23px; + text-transform: uppercase; + letter-spacing: 0.5px; + color: #000000; + } + + i.material-icons { + font-size: 15px; + } + + i.fas { + font-size: 15px; + } + + i.far { + font-size: 15px; + } + + i.fab { + font-size: 15px; + } + + i.fa { + font-size: 15px; + } + + .tooltips .sidebarQuickIcon { + font-size: 18px; + margin-top: 10px; + } + + .active { + .menu-toggle { + background: rgba(146, 144, 144, 0.28); + } + + .ml-menu { + display: block; + } + .ml-sub-menu { + display: block; + } + .ml-sub-menu2 { + display: block; + } + .ml-sub-menu3 { + display: block; + } + } + + .menu-toggle { + &:after, + &:before { + position: absolute; + top: calc(50% - 13px); + right: 17px; + font-size: 19px; + @include transform(scale(0)); + @include transition(all 0.3s); + } + + &:before { + content: "\f054"; + transform: scale(1); + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + @include transform(scale(1)); + } + + &:after { + content: "\f078"; + transform: scale(1); + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + @include transform(scale(0)); + } + } + + .material-icons-two-tone { + vertical-align: middle; + filter: invert(43%) sepia(4%) saturate(19%) hue-rotate(342deg) + brightness(94%) contrast(88%); + } + + .active .menu-toggle { + &:before { + @include transform(scale(0)); + } + + &:after { + @include transform(scale(1)); + } + } + + .ml-sub-menu { + &:after, + &:before { + position: absolute; + top: calc(50% - 13px); + right: 17px; + font-size: 19px; + @include transition(all 0.3s); + } + + &:before { + content: "\f054"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // @include transform(scale(1)); + } + + &:after { + content: "\f078"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // content: "\2013"; + // @include transform(scale(0)); + } + } + .ml-sub-menu2 { + &:after, + &:before { + position: absolute; + top: calc(50% - 13px); + right: 17px; + font-size: 19px; + // @include transform(scale(0)); + @include transition(all 0.3s); + } + + &:before { + content: "\f054"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // @include transform(scale(1)); + } + + &:after { + content: "\f078"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // @include transform(scale(0)); + } + } + .ml-sub-menu3 { + &:after, + &:before { + position: absolute; + top: calc(50% - 13px); + right: 17px; + font-size: 19px; + // @include transform(scale(0)); + @include transition(all 0.3s); + } + + &:before { + content: "\f054"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // @include transform(scale(1)); + } + + &:after { + content: "\f078"; + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + // @include transform(scale(0)); + } + } + + a { + color: #000000; + position: relative; + font-size: 15px !important; + display: block; + overflow: hidden; + line-height: 2rem; + padding: 9px 9px 9px 9px; + margin: 8px 11px 0px 11px; + &:hover, + &:active { + text-decoration: none !important; + background-color: #f0f3fb; + } + + small { + position: absolute; + top: calc(50% - 7.5px); + right: 15px; + } + + span { + margin: 7px 0 7px 7px; + color: rgba(0, 0, 0, 0.85); + // font-weight: bold; + font-size: 16px; + overflow: hidden; + } + } + + .ml-menu { + list-style: none; + display: none; + padding-left: 0; + + span { + font-weight: normal; + font-size: 14px; + margin: 3px 0 1px 6px; + } + + li { + a { + padding-left: 40px; + padding-top: 4px; + padding-bottom: 4px; + } + + &.active { + a.toggled:not(.menu-toggle) { + &:before { + content: ""; + display: block; + width: 7px; + height: 7px; + border-radius: 50%; + position: absolute; + left: 18%; + top: 50%; + transform: translate(-10px, -50%); + opacity: 1; + transition: all 0.2s ease; + } + } + + .ml-menu { + &:before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 13px; + display: block; + width: 7px; + height: 7px; + position: absolute; + transition: 0.5s; + left: 6%; + font-weight: 900; + top: calc(50% - 15px); + } + // &:hover:before { + // font-weight: 600; + // left: 25px; + // } + } + .ml-menu-2 { + display: block; + } + .ml-menu { + color: #5668f3; + font-weight: 500; + } + .ml-sub-sub-menu { + color: #5668f3; + font-weight: 500; + } + } + a { + &.ml-sub-sub-menu { + &:before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 13px; + display: block; + width: 7px; + height: 7px; + position: absolute; + transition: 0.5s; + left: 18%; + font-weight: 900; + top: calc(50% - 15px); + } + &:hover:before { + font-weight: 600; + left: 50px; + } + } + } + + .ml-menu { + li { + a { + padding-left: 80px; + } + } + + .ml-menu { + li { + a { + padding-left: 95px; + } + } + } + } + } + .activeSub { + .ml-menu-2 { + display: block; + } + .ml-menu-3 { + display: block; + } + } + } + .ml-menu-2 { + list-style: none; + display: none; + padding-left: 0; + + span { + font-weight: normal; + font-size: 14px; + margin: 3px 0 1px 6px; + } + + li { + a { + padding-left: 55px; + padding-top: 4px; + padding-bottom: 4px; + } + } + li.active .ml-menu-3 { + display: block; + } + li.active .ml-menu2:before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 13px; + display: block; + width: 7px; + height: 7px; + position: absolute; + left: 17%; + font-weight: 900; + top: calc(50% - 15px); + } + } + .ml-menu-3 { + list-style: none; + display: none; + padding-left: 0; + + span { + font-weight: normal; + font-size: 14px; + margin: 3px 0 1px 6px; + } + + li { + a { + padding-left: 70px; + padding-top: 4px; + padding-bottom: 4px; + } + } + li.active .ml-menu3:before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 13px; + display: block; + width: 7px; + height: 7px; + position: absolute; + left: 24%; + font-weight: 900; + top: calc(50% - 15px); + } + } + } + } + .sidebar-badge { + position: absolute; + right: 35px; + padding: 3px 6px; + margin-top: 5px !important; + border-radius: 15px; + color: #ffffff !important; + font-size: 12px !important; + border: none; + font-weight: 300 !important; + } +} +.ml-menu { + .ml-sub-menu { + &:before { + @include transform(scale(1)); + } + &:after { + @include transform(scale(0)); + } + } + + .ml-sub-menu2 { + &:before { + @include transform(scale(1)); + } + &:after { + @include transform(scale(0)); + } + } + + .ml-sub-menu3 { + &:before { + @include transform(scale(1)); + } + &:after { + @include transform(scale(0)); + } + } + + .active .ml-sub-menu { + &:after { + @include transform(scale(1)); + } + + &:before { + @include transform(scale(0)); + } + } + + .ml-menu-2 { + li.active .ml-sub-menu2 { + &:after { + @include transform(scale(1)); + } + + &:before { + @include transform(scale(0)); + } + } + } + + .ml-menu-3 { + li.active .ml-sub-menu3 { + &:after { + @include transform(scale(1)); + } + + &:before { + @include transform(scale(0)); + } + } + } +} +.right-sidebar { + width: 280px; + height: calc(100vh - 60px); + position: fixed; + right: -300px; + top: 60px; + background: #fdfdfd; + z-index: 999 !important; + @include box-shadow(-2px 2px 5px rgba(0, 0, 0, 0.1)); + overflow: hidden; + @include transition(0.5s); + + &.open { + right: 0; + } + + .nav-tabs { + font-weight: 600; + font-size: 13px; + width: 100%; + margin-left: 2px; + + li { + text-align: center; + + > a { + margin-right: 0; + } + + &:first-child { + width: 45%; + } + + &:last-child { + width: 55%; + } + } + } + + .rightSidebarClose { + position: absolute; + top: 8px; + left: 8px; + z-index: 99; + cursor: pointer; + } +} + +.boxed-layout { + .sidebar { + left: auto; + } + + &.side-closed .sidebar { + left: 0; + } +} + +.horizontal-menu { + width: 100%; + text-align: center; +} + +.top-sidebar { + float: left; + width: 100%; + position: fixed; + z-index: 9; + top: 60px; + background-color: #ffffff; + -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + + ul.horizontal-list { + overflow: visible !important; + margin: 0; + display: inline-block; + height: 60px; + + a { + color: #747474; + float: left; + width: 100%; + } + + li { + float: left; + position: relative; + padding: 20px 20px; + + &:hover > ul { + display: block !important; + position: absolute; + top: 63px; + background-color: #fff; + border-radius: 5px; + z-index: 9; + -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); + + &:after { + position: absolute; + bottom: 100%; + left: 1.8rem; + width: 0; + height: 0; + margin-left: -16px; + content: " "; + pointer-events: none; + border: solid transparent; + border-width: 9px; + border-color: rgba(136, 183, 213, 0); + border-bottom-color: #fff; + } + + &:before { + position: absolute; + bottom: 100%; + left: 1.8rem; + width: 0; + height: 0; + margin-left: -16px; + content: " "; + pointer-events: none; + border: solid transparent; + border-width: 9px; + border-color: rgba(136, 183, 213, 0); + border-bottom-color: #ad5454; + } + + &.mega-ml-menu { + position: relative; + top: 0; + } + } + + ul li { + width: 100%; + padding: 10px 15px; + text-align: left; + } + } + + ul.ml-menu { + display: none !important; + width: 200px; + + li:hover ul { + top: 0; + left: 100%; + } + + .menu-toggle { + position: relative; + + &:after { + content: "\2023"; + position: absolute; + right: 0; + font-size: 25px; + top: 0; + line-height: 22px; + } + } + } + + i.material-icons { + margin-top: 1px; + margin-right: 3px; + float: left; + font-size: 20px; + } + + // .menu-toggle::after{ + // content: "\2304"; + // position: absolute; + // top: 15px; + // right: 0; + // } + } + + .slimScrollDiv { + overflow: visible !important; + } +} + +// Dark left sidebar style +.menu_dark .sidebar { + background: #1a202e; + border-right: 1px solid #2f3a44; + font-weight: 500; + + .menu .list { + a { + color: #cfd8e3; + span { + color: #cfd8e3; + } + } + + a:hover { + background-color: rgba(0, 0, 0, 0.2); + } + + .header { + background: transparent; + color: #9babf1; + font-size: 12px; + margin: 15px 0px 5px 23px; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .active { + .menu-toggle { + background-color: rgba(0, 0, 0, 0.4); + } + } + + .menu-toggle::after { + color: #b8babb; + } + + .menu-toggle::before { + color: #b8babb; + } + + .material-icons-two-tone { + filter: invert(86%) sepia(3%) saturate(2995%) hue-rotate(185deg) + brightness(79%) contrast(78%); + } + + .ml-menu { + li a { + color: #dadada; + } + } + + li { + &.active { + .menu-top { + background-color: rgba(0, 0, 0, 0.4); + } + } + &.active-top { + .menu-top { + background-color: rgba(0, 0, 0, 0.4); + } + } + } + } + + .menu .list .ml-menu .active a::before { + content: "\f105"; + font-family: "Font Awesome 5 Free"; + font-size: 13px; + display: block; + width: 7px; + height: 7px; + position: absolute; + left: 10%; + font-weight: 900; + } +} + +.menu_dark { + .sidebar-userpic-name { + color: #e6e6e6; + } + + .profile-usertitle-job { + color: #e6e6e6; + } +} + +.user-panel { + float: left; + width: 100%; + color: #ccc; + padding: 25px 0px 10px 0; + .image { + width: 35%; + max-width: 75px; + margin: 0 auto; + + img { + max-width: 100%; + } + } +} + +.user-img-circle { + background: #fff; + z-index: 1000; + position: inherit; + box-shadow: 10px 10px 13px 0px rgba(78, 78, 78, 0.15); +} + +.img-circle { + border-radius: 15%; +} + +.profile-usertitle { + text-align: center; + color: #060606; +} + +.profile-usertitle-job { + font-size: 11px; + color: #000000; +} + +.sidebar-userpic-btn { + display: flex; + place-content: space-around; + margin: auto; + line-height: 2rem; + padding: 9px 9px 9px 9px; + margin: 8px 13px 0px 13px; + + a { + padding: 0px !important; + margin: 0px !important; + height: 30px; + width: 30px; + + &:hover { + cursor: pointer; + } + + .mat-button-wrapper { + margin-left: 0px !important; + } + + &:hover { + background-color: transparent !important; + } + } +} + +.collapse.in { + display: block; + list-style-type: none; +} +.sidebarIcon { + height: 18px !important; + width: 18px !important; + text-align: center; + fill: rgba(75, 75, 90, 0.12) !important; +} +.headerShadow { + width: 100%; + height: 100px; + position: fixed; + top: 0; + z-index: 1; + background: linear-gradient(180deg, #f8f8f8e6 44%, #f7f7f780 73%, #ffffff00); +} diff --git a/MyOffice.SPA/src/assets/scss/components/_navbar.scss b/MyOffice.SPA/src/assets/scss/components/_navbar.scss new file mode 100644 index 0000000..35ed72f --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_navbar.scss @@ -0,0 +1,654 @@ +/* + * Document : _navbar.scss + * Author : RedStar Template + * Description: This scss file for navbar style classes + */ +.navbar { + font-family: $navbar-font-family; + @include border-radius(0); + box-shadow: none; + // @include box-shadow(0px 0px 20px 0px rgba(0,0,0,0.15)); + border: none; + position: fixed; + top: 0; + left: 0; + z-index: 999; + width: 100%; + padding: 0; + + .navbar-brand { + @include three-dots-overflow(); + } + + .navbar-custom-right-menu { + float: right; + } + + .navbar-toggle { + text-decoration: none; + color: #fff; + width: 20px; + height: 20px; + margin-top: -7px; + line-height: 60px; + margin-right: 17px; + + &:before { + content: "\E8D5"; + font-family: "Material Icons"; + font-size: 26px; + } + } + + .navbar-collapse { + &.in { + overflow: visible; + } + } + .nav.navbar-nav { + display: block; + } + .container-fluid, + .container { + display: block; + box-shadow: 0 4px 24px 0 rgb(35 42 48 / 10%); + } + .dropdown-menu ul.menu li { + width: 100%; + } + .nav-left-menu { + margin: 3px 15px; + } + .collapse-menu-icon { + margin-bottom: 0px; + line-height: 60px; + display: none; + } + .header-icon { + vertical-align: top !important; + .feather { + height: 20px; + width: 20px; + } + } +} +.ls-closed { + .sidebar { + margin-left: -300px; + } + + section.content { + margin-left: 15px; + } + + .bars { + &:after, + &:before { + font-family: "Material Icons"; + font-size: 24px; + position: absolute; + left: 10px; + top: 0px; + line-height: 60px; + margin-right: 10px; + @include transform(scale(0)); + @include transition(all 0.3s); + } + + &:before { + content: "\E5D2"; + @include transform(scale(1)); + } + + // &:after { + // content: "\E5C4"; + // @include transform(scale(0)); + // } + } + + .navbar-brand { + margin-left: 30px; + } +} + +.overlay-open { + .bars { + &:before { + @include transform(scale(0)); + } + + &:after { + @include transform(scale(1)); + } + } + &.ls-closed { + .sidebar { + margin-left: 0; + } + } +} + +.navbar-header { + padding: 8px; + background-color: #000; + width: 260px; + float: left; + @include transition(all 0.5s); + + .bars { + float: left; + text-decoration: none; + } +} +.navbar-icon { + list-style-type: none; + padding-left: 20px; +} +.logo-name { + color: white; + font-size: 24px; + font-weight: 400; +} +.navbar-nav { + > li { + > a { + padding: 7px 7px 2px 7px; + } + .js-right-sidebar { + margin-right: 5px; + } + } + &.navbar-left { + margin-right: 10px; + line-height: 60px; + } + + &.navbar-right { + float: right !important; + margin-right: 10px; + line-height: 60px; + // .nav-item { + // margin: 0px 4px; + // } + + .user_profile { + .dropdown-toggle { + cursor: pointer; + } + .user_img { + float: right; + margin: 13px 0px 0px 10px; + border-radius: 50%; + } + span { + font-weight: 500; + color: #fff; + } + } + } + .langSelItem .dropdown-menu { + margin-top: 35px !important; + } + + .app-dropdown { + right: unset !important; + left: 0 !important; + &::before { + left: 19px !important; + right: unset !important; + } + &::after { + left: 20px !important; + right: unset !important; + } + } + .dropdown-menu { + margin-top: 60px !important; + width: 325px; + right: 0; + left: auto; + position: absolute !important; + top: 0; + padding: 0; + border-radius: 5px; + &::before { + content: ""; + position: absolute; + top: -7px; + right: 19px; + display: inline-block !important; + border-right: 7px solid transparent; + border-bottom: 7px solid #eee; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + } + &::after { + content: ""; + position: absolute; + top: -6px; + right: 20px; + display: inline-block !important; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + } + ul.menu .menu-info p { + line-height: 1; + .material-icons { + display: inline-block; + } + } + li.footer { + width: 100%; + height: 45px; + } + .header { + line-height: 2; + } + } + .material-icons { + line-height: 1; + height: 24px; + font-size: 27px; + } + .fas { + line-height: 1; + height: 24px; + font-size: 18px; + } + .far { + line-height: 1; + height: 24px; + font-size: 18px; + } + .fab { + line-height: 1; + height: 24px; + font-size: 18px; + } + .fa { + line-height: 1; + height: 24px; + font-size: 18px; + } + .user_profile { + .user_dw_menu { + list-style-type: none; + padding-left: 0px; + li { + width: 100%; + border-bottom: 1px solid #eee; + height: 45px; + a { + line-height: 24px; + color: #333333; + display: inline-flex; + } + i { + float: left; + padding-right: 5px; + } + &:last-child { + border-bottom: 0; + } + } + } + .dropdown-menu { + width: 200px; + right: -10px; + } + } +} +.nav-notification-icons { + min-width: 0 !important; + flex-shrink: 0; + line-height: 40px !important; + border-radius: 50% !important; + margin: 0px 4px; + &:after { + display: none; + } + .material-icons-outlined { + display: flex; + vertical-align: middle; + } +} +.lang-dropdown { + cursor: pointer; + // margin: 14px 20px 0px 10px; + .country-name { + margin-left: 5px; + vertical-align: middle; + } + &::after { + display: none; + } + img { + height: 17px; + border-radius: 3px; + } +} +.lang-item { + width: 175px !important; + .lang-item-list { + line-height: 30px; + &.active { + background-color: #eef1f9; + color: #000000; + } + &:active { + background-color: #eef1f9; + color: #000000; + } + .flag-img { + margin: 0px 5px; + } + } +} + +.label-count { + position: absolute; + top: 5px; + right: 10px; + font-size: 10px; + line-height: 15px; + background-color: #000; + padding: 3px 3px; + border-radius: 3px; +} +.navbar-brand { + float: left; + height: 45px; + padding: 6px 25px; + margin-left: 20px; + font-size: 18px; + line-height: 20px; + text-align: center; + width: 100%; + img { + /*float: left;*/ + vertical-align: top; + } + span { + line-height: 32px; + padding-left: 10px; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); +} +.collapse { + display: none; +} +.navbar-nav { + float: none; + > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; + } +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; + > li { + position: relative; + display: block; + > a { + position: relative; + display: block; + padding: 5px 0px; + } + } + .fullscreen { + // margin: 0px 10px; + } + .langSelItem { + margin: 15px 10px 0px 10px; + } + .btnNotification { + margin: 0px 10px; + } + .btnUserDropdown { + margin: 0px 8px; + } + .btnHeaderSetting { + margin: 0px 8px; + .settingBtn { + vertical-align: top; + } + } + .user-menu-icons { + margin: 0px 5px; + .feather { + height: 18px !important; + width: 18px !important; + vertical-align: middle; + } + } + + .menuIcon { + line-height: 20px !important; + height: 20px; + font-size: 20px; + } + .logo { + margin-right: auto; + } +} +nav.navbar { + min-height: 60px; + position: fixed; + width: calc(100% - 4rem - 257px); + z-index: 12; + right: 0; + left: unset; + margin: 1.3rem 2rem 0; + border-radius: 0.428rem; + box-shadow: 0 -18px 1px 5px rgb(241 240 244); + top: 0; +} + +@each $key, $val in $colors { + .col-#{$key} { + .navbar { + @include navbar-link-color(#fff, #000, 0.95); + // @include navbar-link-color(rgba(0,0,0,0.85), #000, .95); + } + } +} +.side-closed { + .sidebar { + /*margin-left: -300px;*/ + width: 60px; + .menu { + .list { + li { + .menu-toggle { + &:before, + &:after { + content: ""; + } + } + span { + display: none; + } + a { + line-height: 1rem; + padding-left: 9px; + &:after { + top: calc(50% - 7px); + } + } + } + } + } + } + &.submenu-closed { + .sidebar .menu .list { + li .ml-menu, + .header { + display: none !important; + } + } + .navbar-header { + width: 65px; + .navbar-brand { + padding-right: 0; + padding-left: 0; + // margin: 0; + span { + display: none; + } + } + .navbar-nav { + .sidemenu-collapse { + display: none; + } + } + } + .sidebar-user-panel { + display: none; + } + } + + section.content { + margin-left: 58px; + transition: all 1s, width 1s; + } + nav.navbar { + width: calc(100% - 4rem - 55px); + transition: all 1s, width 1s; + } + + .navbar-brand { + margin-left: 5px; + } + &.side-closed-hover { + .sidebar { + width: 260px; + transition: all 1s, width 1s; + .menu { + .list { + li { + .menu-toggle { + &:before { + content: "\f054"; + transform: scale(1); + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + top: calc(50% - 7px); + @include transform(scale(1)); + } + &:after { + content: "\f078"; + transform: scale(1); + font-family: "Font Awesome 5 Free"; + font-weight: 600; + font-size: 12px; + color: gray; + @include transform(scale(0)); + } + } + span { + display: block; + float: left; + } + a { + padding: 9px 9px 9px 9px; + } + i { + float: left; + line-height: 2rem; + } + .sidebarIcon { + float: left; + line-height: 2rem; + } + } + .ml-menu { + li { + a { + padding-left: 45px; + padding-top: 7px; + padding-bottom: 7px; + line-height: 2rem; + } + } + .ml-menu-2 { + li { + a { + padding-left: 65px; + padding-top: 4px; + padding-bottom: 4px; + } + } + } + .ml-menu-3 { + li { + a { + padding-left: 85px; + padding-top: 4px; + padding-bottom: 4px; + } + } + } + } + .active .menu-toggle { + &:before { + @include transform(scale(0)); + } + + &:after { + @include transform(scale(1)); + } + } + } + } + } + section.content { + margin-left: 260px; + transition: all 1s, width 1s; + } + nav.navbar { + width: calc(100% - 4rem - 257px); + transition: all 1s, width 1s; + } + } +} +.sidemenu-collapse { + height: 50px; + padding: 0px 20px 0px 44px; + &:hover { + text-decoration: none; + color: #fff; + background-color: transparent; + } + .fas { + line-height: 1; + height: 24px; + font-size: 18px; + color: #3a2c70; + } +} +nav, +nav .nav-wrapper i, +nav a.button-collapse, +nav a.button-collapse i { + @media screen and (min-width: 601px) { + // height: 60px; + // line-height: 60px; + } +} +.boxed-layout { + .container > .navbar-header { + margin-left: 0; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_navtabs.scss b/MyOffice.SPA/src/assets/scss/components/_navtabs.scss new file mode 100644 index 0000000..1e52768 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_navtabs.scss @@ -0,0 +1,76 @@ +/* + * Document : _navtabs.scss + * Author : RedStar Template + * Description: This scss file for navbar tabs style classes + */ +.nav-tabs { + border-bottom: 2px solid #eee; + + > li { + position: relative; + top: 3px; + left: -2px; + + > a { + border: none !important; + color: #999 !important; + @include border-radius(0); + + &:hover, + &:active, + &:focus { + background-color: transparent !important; + } + + &:before { + content: ""; + position: absolute; + left: 0; + width: 100%; + height: 0; + border-bottom: 2px solid #2196f3; + bottom: 2px; + @include transform(scaleX(0)); + @include transition(0.1s ease-in); + } + + .material-icons { + position: relative; + top: 7px; + margin-bottom: 8px; + } + } + } + + li { + a.active { + color: #222 !important; + + &:hover, + &:active, + &:focus { + background-color: transparent !important; + } + + &:before { + @include transform(scaleX(1)); + } + } + } + + + .tab-content { + padding: 15px 0; + } +} + +@each $key, $val in $colors { + .nav-tabs.tab-col-#{$key} { + > li { + > a { + &:before { + border-bottom: 2px solid $val; + } + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss b/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss new file mode 100644 index 0000000..cf4603c --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_noticeboard.scss @@ -0,0 +1,18 @@ +.notice-board { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-align: start; + -webkit-box-align: start; + align-items: flex-start; + .notice-body { + font-size: 13px; + padding: 0px 0px 5px 10px; + p { + margin-bottom: 0px; + } + .notice-heading { + margin: 5px 0px 0px 0px; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss b/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss new file mode 100644 index 0000000..45b3ac3 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_rightsidebar.scss @@ -0,0 +1,22 @@ +.rightSetting { + padding: 20px 25px 0px 25px; + p { + font-weight: bold; + margin: 0; + border-bottom: 1px solid #eee; + font-size: 12px; + text-align: left; + } + .mat-button-toggle-checked { + background-color: #6e68c1; + color: #ffffff !important; + } + .mat-button-toggle { + width: 60px; + height: 30px; + font-size: 14px; + } + .mat-button-toggle-appearance-standard .mat-button-toggle-label-content { + line-height: 30px !important; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_searchbar.scss b/MyOffice.SPA/src/assets/scss/components/_searchbar.scss new file mode 100644 index 0000000..26c5770 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_searchbar.scss @@ -0,0 +1,70 @@ +/* + * Document : _noUISlider.scss + * Author : RedStar Template + * Description: This scss file for noUISlider component style classes + */ +%extend_search { + outline: none; + opacity: 1; + margin-left: -43px; +} + +.search-box { + overflow: hidden; + width: 270px; + vertical-align: middle; + white-space: nowrap; + input { + &#search { + width: 250px; + height: 40px; + background: rgb(255, 255, 255); + border: none; + font-size: 10pt; + float: left; + color: #fff; + padding-left: 15px; + margin-bottom: 0; + margin-top: 10px; + border-radius: 50px; + &:-moz-placeholder { + color: #65737e; + } + &:-ms-input-placeholder { + color: #65737e; + } + } + &#search::-webkit-input-placeholder { + color: #65737e; + } + &#search::-moz-placeholder { + color: #65737e; + } + } + button.icon { + border: none; + background: transparent; + height: 50px; + width: 0px; + color: #4f5b66; + opacity: 0; + font-size: 10pt; + transition: all 0.55s ease; + + .fa { + font-size: 18px; + } + } + &:hover button.icon { + @extend %extend_search; + &:hover { + background: transparent; + } + } + &:active button.icon { + @extend %extend_search; + } + &:focus button.icon { + @extend %extend_search; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss b/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss new file mode 100644 index 0000000..a14bed5 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_settingSidebar.scss @@ -0,0 +1,196 @@ +.settingSidebar { + background: #fff; + position: fixed; + height: 100%; + width: 280px; + top: 62px; + right: -280px; + z-index: 999; + transition: 0.3s ease-in; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.16), 0 2px 10px rgba(0, 0, 0, 0.12); + + .settingPanelToggle { + background: #6777ef; + padding: 13px 13px; + color: #fff; + position: absolute; + top: 30%; + left: -40px; + width: 40px; + border-radius: 10px 0 0 10px; + .setting-sidebar-icon .feather { + height: 17px; + width: 17px; + } + } + + &.showSettingPanel { + right: 0; + } + + .settingSidebar-body { + position: relative; + height: 100%; + } + + .settingSidebar-tab { + display: flex; + + .nav-item { + width: 33.33%; + text-align: center; + + .nav-link { + padding: 15px 12px; + color: #6a7a8c; + border-bottom: 3px solid transparent; + + &.active { + border-bottom: 3px solid #2962ff; + color: #2962ff; + } + + &:hover { + border-bottom: 3px solid #2962ff; + color: #2962ff; + } + } + } + } + + ul.choose-theme li { + display: inline-block; + + &:hover { + cursor: pointer; + } + } + + ul.choose-theme li div { + border-radius: 15px; + display: inline-block; + vertical-align: middle; + height: 25px; + width: 25px; + overflow: hidden; + position: relative; + margin: 4px; + } + + ul.choose-theme li div.purple { + background: #6777ef; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.orange { + background: #ffa117; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.cyan { + background: #3dc7be; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.green { + background: #4caf4f; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.red { + background: #ea5455; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.white { + background: #ece8e8; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li div.black { + background: #343a40; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + ul.choose-theme li div.blue { + background: #03a9f3; + -webkit-box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + + ul.choose-theme li.active div::after { + content: "\f00c"; + color: #fff; + top: 4px; + left: 7px; + font-family: "Font Awesome 5 Free"; + font-weight: 900; + font-size: 12px; + position: absolute; + -webkit-transition: 0.5s; + transition: 0.5s; + } + + .setting-panel-header { + display: block; + padding: 15px 20px; + color: #212529; + font-size: 15px; + border: 1px solid #eae9e9; + background: #e9ecef; + } + + .disk-server-setting { + .progress { + height: 8px; + } + + p { + font-weight: bold; + margin: 0; + border-bottom: 1px solid #eee; + font-size: 14px; + text-align: left; + padding-bottom: 5px; + } + } + + .rt-sidebar-last-ele { + margin-bottom: 70px !important; + } +} +.hiddenradio { + padding: 0px 20px 0px 0px; + margin: 0px 20px 0px 0px; +} +.hiddenradio [type="radio"] { + position: absolute; + opacity: 0; + width: 0; + height: 0; +} + +/* IMAGE STYLES */ +.hiddenradio [type="radio"] + img { + cursor: pointer; + height: auto; + width: 100%; + border: 3px solid #d5e0ec; +} + +/* CHECKED STYLES */ +.hiddenradio [type="radio"]:checked + img { + outline: 2px solid #6777ef; +} + +@media only screen and (max-width: 1024px) { + .settingSidebar { + display: none; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_switch.scss b/MyOffice.SPA/src/assets/scss/components/_switch.scss new file mode 100644 index 0000000..6324216 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_switch.scss @@ -0,0 +1,40 @@ +/* + * Document : _switch.scss + * Author : RedStar Template + * Description: This scss file switch button style classes + */ +.switch { + label { + font-weight: normal; + font-size: 13px; + + .lever { + margin: 0 14px; + } + + input[type="checkbox"] { + &:checked { + @each $key, $val in $colors { + &:not(:disabled) { + ~ .lever.switch-col-#{$key} { + &:active { + &:after { + box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), + 0 0 0 15px rgba($val, 0.1); + } + } + } + } + + + .lever.switch-col-#{$key} { + background-color: rgba($val, 0.5); + + &:after { + background-color: $val; + } + } + } + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss b/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss new file mode 100644 index 0000000..b229ed0 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_thumbnails.scss @@ -0,0 +1,18 @@ +/* + * Document : _thumbnail.scss + * Author : RedStar Template + * Description: This scss file for thumbnail style classes + */ +.thumbnail { + @include border-radius(0); + + p:not(button) { + color: #999999; + font-size: 14px; + } + + h3 { + font-weight: bold; + font-size: 17px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/components/_todo.scss b/MyOffice.SPA/src/assets/scss/components/_todo.scss new file mode 100644 index 0000000..fa5536f --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/components/_todo.scss @@ -0,0 +1,85 @@ +/* + * Document : _todo.scss + * Author : RedStar Template + * Description: This scss file for todo style classes + */ +.to-do-list { + padding-left: 0; + margin-top: -10px; + font-size: 12px; + min-height: 311px; + float: left; + width: 100%; + li { + padding: 15px 0; + border-radius: 3px; + position: relative; + cursor: move; + list-style: none; + font-size: 14px; + background: #fff; + border-bottom: 1px dotted rgba(0, 0, 0, 0.2); + p { + margin: 0; + padding-left: 50px; + } + .todo-check input[type="checkbox"] { + visibility: hidden; + } + } +} +.todo-actionlist { + position: absolute; + right: -5px; + top: 22px; + a { + height: 24px; + width: 24px; + display: inline-block; + float: left; + i { + height: 24px; + width: 24px; + display: inline-block; + text-align: center; + line-height: 24px; + color: #ccc; + } + &:hover i { + color: #666; + } + } +} +.line-through { + text-decoration: line-through; +} +.todo-action-bar { + margin-top: 20px; +} +.todo-check { + width: 20px; + position: relative; + margin-right: 10px; + margin-left: 10px; + input[type="checkbox"] { + visibility: hidden; + } + label { + cursor: pointer; + position: absolute; + width: 20px; + height: 20px; + top: 0; + left: 0; + border-radius: 2px; + } +} +.todo-done i { + font-size: 14px; +} +.todo-remove i { + font-size: 10px; +} +.inbox-small-cells .todo-check input[type="checkbox"] { + visibility: hidden; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/_material.scss b/MyOffice.SPA/src/assets/scss/fonts/_material.scss new file mode 100644 index 0000000..f509cf2 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/_material.scss @@ -0,0 +1,56 @@ +/* + * Document : _material.scss + * Author : RedStar Template + * Description: This scss file for import material design icons classes + */ +@font-face { + font-family: "Material Icons"; + font-style: normal; + font-weight: 400; + src: url(../fonts/iconfont/MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local("Material Icons"), local("MaterialIcons-Regular"), + url(../fonts/iconfont/MaterialIcons-Regular.woff2) format("woff2"), + url(../fonts/iconfont/MaterialIcons-Regular.woff) format("woff"), + url(../fonts/iconfont/MaterialIcons-Regular.ttf) format("truetype"); +} + +.material-icons { + font-family: Material Icons; + font-weight: normal; + font-style: normal; + font-size: 24px; + display: inline-block; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + text-rendering: optimizeLegibility; + font-feature-settings: "liga"; + line-height: 1; + height: 24px; + &.md-18 { + font-size: 18px; + } + &.md-24 { + font-size: 24px; + } + &.md-26 { + font-size: 26px; + } + &.md-28 { + font-size: 28px; + } + &.md-30 { + font-size: 30px; + } + &.md-32 { + font-size: 32px; + } + &.md-36 { + font-size: 36px; + } + &.md-48 { + font-size: 48px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss new file mode 100644 index 0000000..7c7c0e1 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_animated.scss @@ -0,0 +1,20 @@ +// Animated Icons +// -------------------------- + +.#{$fa-css-prefix}-spin { + animation: fa-spin 2s infinite linear; +} + +.#{$fa-css-prefix}-pulse { + animation: fa-spin 1s infinite steps(8); +} + +@keyframes fa-spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss new file mode 100644 index 0000000..c8c4274 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_bordered-pulled.scss @@ -0,0 +1,20 @@ +// Bordered & Pulled +// ------------------------- + +.#{$fa-css-prefix}-border { + border: solid .08em $fa-border-color; + border-radius: .1em; + padding: .2em .25em .15em; +} + +.#{$fa-css-prefix}-pull-left { float: left; } +.#{$fa-css-prefix}-pull-right { float: right; } + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fab { + &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } + &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss new file mode 100644 index 0000000..cbd4cf7 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_core.scss @@ -0,0 +1,21 @@ +// Base Class Definition +// ------------------------- + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fad, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; +} + +%fa-icon { + @include fa-icon; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss new file mode 100644 index 0000000..970641f --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_fixed-width.scss @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.#{$fa-css-prefix}-fw { + text-align: center; + width: $fa-fw-width; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss new file mode 100644 index 0000000..fa3ac07 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_icons.scss @@ -0,0 +1,1451 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ + +.#{$fa-css-prefix}-500px:before { content: fa-content($fa-var-500px); } +.#{$fa-css-prefix}-accessible-icon:before { content: fa-content($fa-var-accessible-icon); } +.#{$fa-css-prefix}-accusoft:before { content: fa-content($fa-var-accusoft); } +.#{$fa-css-prefix}-acquisitions-incorporated:before { content: fa-content($fa-var-acquisitions-incorporated); } +.#{$fa-css-prefix}-ad:before { content: fa-content($fa-var-ad); } +.#{$fa-css-prefix}-address-book:before { content: fa-content($fa-var-address-book); } +.#{$fa-css-prefix}-address-card:before { content: fa-content($fa-var-address-card); } +.#{$fa-css-prefix}-adjust:before { content: fa-content($fa-var-adjust); } +.#{$fa-css-prefix}-adn:before { content: fa-content($fa-var-adn); } +.#{$fa-css-prefix}-adobe:before { content: fa-content($fa-var-adobe); } +.#{$fa-css-prefix}-adversal:before { content: fa-content($fa-var-adversal); } +.#{$fa-css-prefix}-affiliatetheme:before { content: fa-content($fa-var-affiliatetheme); } +.#{$fa-css-prefix}-air-freshener:before { content: fa-content($fa-var-air-freshener); } +.#{$fa-css-prefix}-airbnb:before { content: fa-content($fa-var-airbnb); } +.#{$fa-css-prefix}-algolia:before { content: fa-content($fa-var-algolia); } +.#{$fa-css-prefix}-align-center:before { content: fa-content($fa-var-align-center); } +.#{$fa-css-prefix}-align-justify:before { content: fa-content($fa-var-align-justify); } +.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); } +.#{$fa-css-prefix}-align-right:before { content: fa-content($fa-var-align-right); } +.#{$fa-css-prefix}-alipay:before { content: fa-content($fa-var-alipay); } +.#{$fa-css-prefix}-allergies:before { content: fa-content($fa-var-allergies); } +.#{$fa-css-prefix}-amazon:before { content: fa-content($fa-var-amazon); } +.#{$fa-css-prefix}-amazon-pay:before { content: fa-content($fa-var-amazon-pay); } +.#{$fa-css-prefix}-ambulance:before { content: fa-content($fa-var-ambulance); } +.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } +.#{$fa-css-prefix}-amilia:before { content: fa-content($fa-var-amilia); } +.#{$fa-css-prefix}-anchor:before { content: fa-content($fa-var-anchor); } +.#{$fa-css-prefix}-android:before { content: fa-content($fa-var-android); } +.#{$fa-css-prefix}-angellist:before { content: fa-content($fa-var-angellist); } +.#{$fa-css-prefix}-angle-double-down:before { content: fa-content($fa-var-angle-double-down); } +.#{$fa-css-prefix}-angle-double-left:before { content: fa-content($fa-var-angle-double-left); } +.#{$fa-css-prefix}-angle-double-right:before { content: fa-content($fa-var-angle-double-right); } +.#{$fa-css-prefix}-angle-double-up:before { content: fa-content($fa-var-angle-double-up); } +.#{$fa-css-prefix}-angle-down:before { content: fa-content($fa-var-angle-down); } +.#{$fa-css-prefix}-angle-left:before { content: fa-content($fa-var-angle-left); } +.#{$fa-css-prefix}-angle-right:before { content: fa-content($fa-var-angle-right); } +.#{$fa-css-prefix}-angle-up:before { content: fa-content($fa-var-angle-up); } +.#{$fa-css-prefix}-angry:before { content: fa-content($fa-var-angry); } +.#{$fa-css-prefix}-angrycreative:before { content: fa-content($fa-var-angrycreative); } +.#{$fa-css-prefix}-angular:before { content: fa-content($fa-var-angular); } +.#{$fa-css-prefix}-ankh:before { content: fa-content($fa-var-ankh); } +.#{$fa-css-prefix}-app-store:before { content: fa-content($fa-var-app-store); } +.#{$fa-css-prefix}-app-store-ios:before { content: fa-content($fa-var-app-store-ios); } +.#{$fa-css-prefix}-apper:before { content: fa-content($fa-var-apper); } +.#{$fa-css-prefix}-apple:before { content: fa-content($fa-var-apple); } +.#{$fa-css-prefix}-apple-alt:before { content: fa-content($fa-var-apple-alt); } +.#{$fa-css-prefix}-apple-pay:before { content: fa-content($fa-var-apple-pay); } +.#{$fa-css-prefix}-archive:before { content: fa-content($fa-var-archive); } +.#{$fa-css-prefix}-archway:before { content: fa-content($fa-var-archway); } +.#{$fa-css-prefix}-arrow-alt-circle-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } +.#{$fa-css-prefix}-arrow-alt-circle-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } +.#{$fa-css-prefix}-arrow-alt-circle-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } +.#{$fa-css-prefix}-arrow-alt-circle-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } +.#{$fa-css-prefix}-arrow-circle-down:before { content: fa-content($fa-var-arrow-circle-down); } +.#{$fa-css-prefix}-arrow-circle-left:before { content: fa-content($fa-var-arrow-circle-left); } +.#{$fa-css-prefix}-arrow-circle-right:before { content: fa-content($fa-var-arrow-circle-right); } +.#{$fa-css-prefix}-arrow-circle-up:before { content: fa-content($fa-var-arrow-circle-up); } +.#{$fa-css-prefix}-arrow-down:before { content: fa-content($fa-var-arrow-down); } +.#{$fa-css-prefix}-arrow-left:before { content: fa-content($fa-var-arrow-left); } +.#{$fa-css-prefix}-arrow-right:before { content: fa-content($fa-var-arrow-right); } +.#{$fa-css-prefix}-arrow-up:before { content: fa-content($fa-var-arrow-up); } +.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-arrows-alt); } +.#{$fa-css-prefix}-arrows-alt-h:before { content: fa-content($fa-var-arrows-alt-h); } +.#{$fa-css-prefix}-arrows-alt-v:before { content: fa-content($fa-var-arrows-alt-v); } +.#{$fa-css-prefix}-artstation:before { content: fa-content($fa-var-artstation); } +.#{$fa-css-prefix}-assistive-listening-systems:before { content: fa-content($fa-var-assistive-listening-systems); } +.#{$fa-css-prefix}-asterisk:before { content: fa-content($fa-var-asterisk); } +.#{$fa-css-prefix}-asymmetrik:before { content: fa-content($fa-var-asymmetrik); } +.#{$fa-css-prefix}-at:before { content: fa-content($fa-var-at); } +.#{$fa-css-prefix}-atlas:before { content: fa-content($fa-var-atlas); } +.#{$fa-css-prefix}-atlassian:before { content: fa-content($fa-var-atlassian); } +.#{$fa-css-prefix}-atom:before { content: fa-content($fa-var-atom); } +.#{$fa-css-prefix}-audible:before { content: fa-content($fa-var-audible); } +.#{$fa-css-prefix}-audio-description:before { content: fa-content($fa-var-audio-description); } +.#{$fa-css-prefix}-autoprefixer:before { content: fa-content($fa-var-autoprefixer); } +.#{$fa-css-prefix}-avianex:before { content: fa-content($fa-var-avianex); } +.#{$fa-css-prefix}-aviato:before { content: fa-content($fa-var-aviato); } +.#{$fa-css-prefix}-award:before { content: fa-content($fa-var-award); } +.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); } +.#{$fa-css-prefix}-baby:before { content: fa-content($fa-var-baby); } +.#{$fa-css-prefix}-baby-carriage:before { content: fa-content($fa-var-baby-carriage); } +.#{$fa-css-prefix}-backspace:before { content: fa-content($fa-var-backspace); } +.#{$fa-css-prefix}-backward:before { content: fa-content($fa-var-backward); } +.#{$fa-css-prefix}-bacon:before { content: fa-content($fa-var-bacon); } +.#{$fa-css-prefix}-bacteria:before { content: fa-content($fa-var-bacteria); } +.#{$fa-css-prefix}-bacterium:before { content: fa-content($fa-var-bacterium); } +.#{$fa-css-prefix}-bahai:before { content: fa-content($fa-var-bahai); } +.#{$fa-css-prefix}-balance-scale:before { content: fa-content($fa-var-balance-scale); } +.#{$fa-css-prefix}-balance-scale-left:before { content: fa-content($fa-var-balance-scale-left); } +.#{$fa-css-prefix}-balance-scale-right:before { content: fa-content($fa-var-balance-scale-right); } +.#{$fa-css-prefix}-ban:before { content: fa-content($fa-var-ban); } +.#{$fa-css-prefix}-band-aid:before { content: fa-content($fa-var-band-aid); } +.#{$fa-css-prefix}-bandcamp:before { content: fa-content($fa-var-bandcamp); } +.#{$fa-css-prefix}-barcode:before { content: fa-content($fa-var-barcode); } +.#{$fa-css-prefix}-bars:before { content: fa-content($fa-var-bars); } +.#{$fa-css-prefix}-baseball-ball:before { content: fa-content($fa-var-baseball-ball); } +.#{$fa-css-prefix}-basketball-ball:before { content: fa-content($fa-var-basketball-ball); } +.#{$fa-css-prefix}-bath:before { content: fa-content($fa-var-bath); } +.#{$fa-css-prefix}-battery-empty:before { content: fa-content($fa-var-battery-empty); } +.#{$fa-css-prefix}-battery-full:before { content: fa-content($fa-var-battery-full); } +.#{$fa-css-prefix}-battery-half:before { content: fa-content($fa-var-battery-half); } +.#{$fa-css-prefix}-battery-quarter:before { content: fa-content($fa-var-battery-quarter); } +.#{$fa-css-prefix}-battery-three-quarters:before { content: fa-content($fa-var-battery-three-quarters); } +.#{$fa-css-prefix}-battle-net:before { content: fa-content($fa-var-battle-net); } +.#{$fa-css-prefix}-bed:before { content: fa-content($fa-var-bed); } +.#{$fa-css-prefix}-beer:before { content: fa-content($fa-var-beer); } +.#{$fa-css-prefix}-behance:before { content: fa-content($fa-var-behance); } +.#{$fa-css-prefix}-behance-square:before { content: fa-content($fa-var-behance-square); } +.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); } +.#{$fa-css-prefix}-bell-slash:before { content: fa-content($fa-var-bell-slash); } +.#{$fa-css-prefix}-bezier-curve:before { content: fa-content($fa-var-bezier-curve); } +.#{$fa-css-prefix}-bible:before { content: fa-content($fa-var-bible); } +.#{$fa-css-prefix}-bicycle:before { content: fa-content($fa-var-bicycle); } +.#{$fa-css-prefix}-biking:before { content: fa-content($fa-var-biking); } +.#{$fa-css-prefix}-bimobject:before { content: fa-content($fa-var-bimobject); } +.#{$fa-css-prefix}-binoculars:before { content: fa-content($fa-var-binoculars); } +.#{$fa-css-prefix}-biohazard:before { content: fa-content($fa-var-biohazard); } +.#{$fa-css-prefix}-birthday-cake:before { content: fa-content($fa-var-birthday-cake); } +.#{$fa-css-prefix}-bitbucket:before { content: fa-content($fa-var-bitbucket); } +.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-bitcoin); } +.#{$fa-css-prefix}-bity:before { content: fa-content($fa-var-bity); } +.#{$fa-css-prefix}-black-tie:before { content: fa-content($fa-var-black-tie); } +.#{$fa-css-prefix}-blackberry:before { content: fa-content($fa-var-blackberry); } +.#{$fa-css-prefix}-blender:before { content: fa-content($fa-var-blender); } +.#{$fa-css-prefix}-blender-phone:before { content: fa-content($fa-var-blender-phone); } +.#{$fa-css-prefix}-blind:before { content: fa-content($fa-var-blind); } +.#{$fa-css-prefix}-blog:before { content: fa-content($fa-var-blog); } +.#{$fa-css-prefix}-blogger:before { content: fa-content($fa-var-blogger); } +.#{$fa-css-prefix}-blogger-b:before { content: fa-content($fa-var-blogger-b); } +.#{$fa-css-prefix}-bluetooth:before { content: fa-content($fa-var-bluetooth); } +.#{$fa-css-prefix}-bluetooth-b:before { content: fa-content($fa-var-bluetooth-b); } +.#{$fa-css-prefix}-bold:before { content: fa-content($fa-var-bold); } +.#{$fa-css-prefix}-bolt:before { content: fa-content($fa-var-bolt); } +.#{$fa-css-prefix}-bomb:before { content: fa-content($fa-var-bomb); } +.#{$fa-css-prefix}-bone:before { content: fa-content($fa-var-bone); } +.#{$fa-css-prefix}-bong:before { content: fa-content($fa-var-bong); } +.#{$fa-css-prefix}-book:before { content: fa-content($fa-var-book); } +.#{$fa-css-prefix}-book-dead:before { content: fa-content($fa-var-book-dead); } +.#{$fa-css-prefix}-book-medical:before { content: fa-content($fa-var-book-medical); } +.#{$fa-css-prefix}-book-open:before { content: fa-content($fa-var-book-open); } +.#{$fa-css-prefix}-book-reader:before { content: fa-content($fa-var-book-reader); } +.#{$fa-css-prefix}-bookmark:before { content: fa-content($fa-var-bookmark); } +.#{$fa-css-prefix}-bootstrap:before { content: fa-content($fa-var-bootstrap); } +.#{$fa-css-prefix}-border-all:before { content: fa-content($fa-var-border-all); } +.#{$fa-css-prefix}-border-none:before { content: fa-content($fa-var-border-none); } +.#{$fa-css-prefix}-border-style:before { content: fa-content($fa-var-border-style); } +.#{$fa-css-prefix}-bowling-ball:before { content: fa-content($fa-var-bowling-ball); } +.#{$fa-css-prefix}-box:before { content: fa-content($fa-var-box); } +.#{$fa-css-prefix}-box-open:before { content: fa-content($fa-var-box-open); } +.#{$fa-css-prefix}-box-tissue:before { content: fa-content($fa-var-box-tissue); } +.#{$fa-css-prefix}-boxes:before { content: fa-content($fa-var-boxes); } +.#{$fa-css-prefix}-braille:before { content: fa-content($fa-var-braille); } +.#{$fa-css-prefix}-brain:before { content: fa-content($fa-var-brain); } +.#{$fa-css-prefix}-bread-slice:before { content: fa-content($fa-var-bread-slice); } +.#{$fa-css-prefix}-briefcase:before { content: fa-content($fa-var-briefcase); } +.#{$fa-css-prefix}-briefcase-medical:before { content: fa-content($fa-var-briefcase-medical); } +.#{$fa-css-prefix}-broadcast-tower:before { content: fa-content($fa-var-broadcast-tower); } +.#{$fa-css-prefix}-broom:before { content: fa-content($fa-var-broom); } +.#{$fa-css-prefix}-brush:before { content: fa-content($fa-var-brush); } +.#{$fa-css-prefix}-btc:before { content: fa-content($fa-var-btc); } +.#{$fa-css-prefix}-buffer:before { content: fa-content($fa-var-buffer); } +.#{$fa-css-prefix}-bug:before { content: fa-content($fa-var-bug); } +.#{$fa-css-prefix}-building:before { content: fa-content($fa-var-building); } +.#{$fa-css-prefix}-bullhorn:before { content: fa-content($fa-var-bullhorn); } +.#{$fa-css-prefix}-bullseye:before { content: fa-content($fa-var-bullseye); } +.#{$fa-css-prefix}-burn:before { content: fa-content($fa-var-burn); } +.#{$fa-css-prefix}-buromobelexperte:before { content: fa-content($fa-var-buromobelexperte); } +.#{$fa-css-prefix}-bus:before { content: fa-content($fa-var-bus); } +.#{$fa-css-prefix}-bus-alt:before { content: fa-content($fa-var-bus-alt); } +.#{$fa-css-prefix}-business-time:before { content: fa-content($fa-var-business-time); } +.#{$fa-css-prefix}-buy-n-large:before { content: fa-content($fa-var-buy-n-large); } +.#{$fa-css-prefix}-buysellads:before { content: fa-content($fa-var-buysellads); } +.#{$fa-css-prefix}-calculator:before { content: fa-content($fa-var-calculator); } +.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar); } +.#{$fa-css-prefix}-calendar-alt:before { content: fa-content($fa-var-calendar-alt); } +.#{$fa-css-prefix}-calendar-check:before { content: fa-content($fa-var-calendar-check); } +.#{$fa-css-prefix}-calendar-day:before { content: fa-content($fa-var-calendar-day); } +.#{$fa-css-prefix}-calendar-minus:before { content: fa-content($fa-var-calendar-minus); } +.#{$fa-css-prefix}-calendar-plus:before { content: fa-content($fa-var-calendar-plus); } +.#{$fa-css-prefix}-calendar-times:before { content: fa-content($fa-var-calendar-times); } +.#{$fa-css-prefix}-calendar-week:before { content: fa-content($fa-var-calendar-week); } +.#{$fa-css-prefix}-camera:before { content: fa-content($fa-var-camera); } +.#{$fa-css-prefix}-camera-retro:before { content: fa-content($fa-var-camera-retro); } +.#{$fa-css-prefix}-campground:before { content: fa-content($fa-var-campground); } +.#{$fa-css-prefix}-canadian-maple-leaf:before { content: fa-content($fa-var-canadian-maple-leaf); } +.#{$fa-css-prefix}-candy-cane:before { content: fa-content($fa-var-candy-cane); } +.#{$fa-css-prefix}-cannabis:before { content: fa-content($fa-var-cannabis); } +.#{$fa-css-prefix}-capsules:before { content: fa-content($fa-var-capsules); } +.#{$fa-css-prefix}-car:before { content: fa-content($fa-var-car); } +.#{$fa-css-prefix}-car-alt:before { content: fa-content($fa-var-car-alt); } +.#{$fa-css-prefix}-car-battery:before { content: fa-content($fa-var-car-battery); } +.#{$fa-css-prefix}-car-crash:before { content: fa-content($fa-var-car-crash); } +.#{$fa-css-prefix}-car-side:before { content: fa-content($fa-var-car-side); } +.#{$fa-css-prefix}-caravan:before { content: fa-content($fa-var-caravan); } +.#{$fa-css-prefix}-caret-down:before { content: fa-content($fa-var-caret-down); } +.#{$fa-css-prefix}-caret-left:before { content: fa-content($fa-var-caret-left); } +.#{$fa-css-prefix}-caret-right:before { content: fa-content($fa-var-caret-right); } +.#{$fa-css-prefix}-caret-square-down:before { content: fa-content($fa-var-caret-square-down); } +.#{$fa-css-prefix}-caret-square-left:before { content: fa-content($fa-var-caret-square-left); } +.#{$fa-css-prefix}-caret-square-right:before { content: fa-content($fa-var-caret-square-right); } +.#{$fa-css-prefix}-caret-square-up:before { content: fa-content($fa-var-caret-square-up); } +.#{$fa-css-prefix}-caret-up:before { content: fa-content($fa-var-caret-up); } +.#{$fa-css-prefix}-carrot:before { content: fa-content($fa-var-carrot); } +.#{$fa-css-prefix}-cart-arrow-down:before { content: fa-content($fa-var-cart-arrow-down); } +.#{$fa-css-prefix}-cart-plus:before { content: fa-content($fa-var-cart-plus); } +.#{$fa-css-prefix}-cash-register:before { content: fa-content($fa-var-cash-register); } +.#{$fa-css-prefix}-cat:before { content: fa-content($fa-var-cat); } +.#{$fa-css-prefix}-cc-amazon-pay:before { content: fa-content($fa-var-cc-amazon-pay); } +.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); } +.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); } +.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); } +.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); } +.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); } +.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); } +.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); } +.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); } +.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); } +.#{$fa-css-prefix}-centercode:before { content: fa-content($fa-var-centercode); } +.#{$fa-css-prefix}-centos:before { content: fa-content($fa-var-centos); } +.#{$fa-css-prefix}-certificate:before { content: fa-content($fa-var-certificate); } +.#{$fa-css-prefix}-chair:before { content: fa-content($fa-var-chair); } +.#{$fa-css-prefix}-chalkboard:before { content: fa-content($fa-var-chalkboard); } +.#{$fa-css-prefix}-chalkboard-teacher:before { content: fa-content($fa-var-chalkboard-teacher); } +.#{$fa-css-prefix}-charging-station:before { content: fa-content($fa-var-charging-station); } +.#{$fa-css-prefix}-chart-area:before { content: fa-content($fa-var-chart-area); } +.#{$fa-css-prefix}-chart-bar:before { content: fa-content($fa-var-chart-bar); } +.#{$fa-css-prefix}-chart-line:before { content: fa-content($fa-var-chart-line); } +.#{$fa-css-prefix}-chart-pie:before { content: fa-content($fa-var-chart-pie); } +.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); } +.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); } +.#{$fa-css-prefix}-check-double:before { content: fa-content($fa-var-check-double); } +.#{$fa-css-prefix}-check-square:before { content: fa-content($fa-var-check-square); } +.#{$fa-css-prefix}-cheese:before { content: fa-content($fa-var-cheese); } +.#{$fa-css-prefix}-chess:before { content: fa-content($fa-var-chess); } +.#{$fa-css-prefix}-chess-bishop:before { content: fa-content($fa-var-chess-bishop); } +.#{$fa-css-prefix}-chess-board:before { content: fa-content($fa-var-chess-board); } +.#{$fa-css-prefix}-chess-king:before { content: fa-content($fa-var-chess-king); } +.#{$fa-css-prefix}-chess-knight:before { content: fa-content($fa-var-chess-knight); } +.#{$fa-css-prefix}-chess-pawn:before { content: fa-content($fa-var-chess-pawn); } +.#{$fa-css-prefix}-chess-queen:before { content: fa-content($fa-var-chess-queen); } +.#{$fa-css-prefix}-chess-rook:before { content: fa-content($fa-var-chess-rook); } +.#{$fa-css-prefix}-chevron-circle-down:before { content: fa-content($fa-var-chevron-circle-down); } +.#{$fa-css-prefix}-chevron-circle-left:before { content: fa-content($fa-var-chevron-circle-left); } +.#{$fa-css-prefix}-chevron-circle-right:before { content: fa-content($fa-var-chevron-circle-right); } +.#{$fa-css-prefix}-chevron-circle-up:before { content: fa-content($fa-var-chevron-circle-up); } +.#{$fa-css-prefix}-chevron-down:before { content: fa-content($fa-var-chevron-down); } +.#{$fa-css-prefix}-chevron-left:before { content: fa-content($fa-var-chevron-left); } +.#{$fa-css-prefix}-chevron-right:before { content: fa-content($fa-var-chevron-right); } +.#{$fa-css-prefix}-chevron-up:before { content: fa-content($fa-var-chevron-up); } +.#{$fa-css-prefix}-child:before { content: fa-content($fa-var-child); } +.#{$fa-css-prefix}-chrome:before { content: fa-content($fa-var-chrome); } +.#{$fa-css-prefix}-chromecast:before { content: fa-content($fa-var-chromecast); } +.#{$fa-css-prefix}-church:before { content: fa-content($fa-var-church); } +.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); } +.#{$fa-css-prefix}-circle-notch:before { content: fa-content($fa-var-circle-notch); } +.#{$fa-css-prefix}-city:before { content: fa-content($fa-var-city); } +.#{$fa-css-prefix}-clinic-medical:before { content: fa-content($fa-var-clinic-medical); } +.#{$fa-css-prefix}-clipboard:before { content: fa-content($fa-var-clipboard); } +.#{$fa-css-prefix}-clipboard-check:before { content: fa-content($fa-var-clipboard-check); } +.#{$fa-css-prefix}-clipboard-list:before { content: fa-content($fa-var-clipboard-list); } +.#{$fa-css-prefix}-clock:before { content: fa-content($fa-var-clock); } +.#{$fa-css-prefix}-clone:before { content: fa-content($fa-var-clone); } +.#{$fa-css-prefix}-closed-captioning:before { content: fa-content($fa-var-closed-captioning); } +.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); } +.#{$fa-css-prefix}-cloud-download-alt:before { content: fa-content($fa-var-cloud-download-alt); } +.#{$fa-css-prefix}-cloud-meatball:before { content: fa-content($fa-var-cloud-meatball); } +.#{$fa-css-prefix}-cloud-moon:before { content: fa-content($fa-var-cloud-moon); } +.#{$fa-css-prefix}-cloud-moon-rain:before { content: fa-content($fa-var-cloud-moon-rain); } +.#{$fa-css-prefix}-cloud-rain:before { content: fa-content($fa-var-cloud-rain); } +.#{$fa-css-prefix}-cloud-showers-heavy:before { content: fa-content($fa-var-cloud-showers-heavy); } +.#{$fa-css-prefix}-cloud-sun:before { content: fa-content($fa-var-cloud-sun); } +.#{$fa-css-prefix}-cloud-sun-rain:before { content: fa-content($fa-var-cloud-sun-rain); } +.#{$fa-css-prefix}-cloud-upload-alt:before { content: fa-content($fa-var-cloud-upload-alt); } +.#{$fa-css-prefix}-cloudscale:before { content: fa-content($fa-var-cloudscale); } +.#{$fa-css-prefix}-cloudsmith:before { content: fa-content($fa-var-cloudsmith); } +.#{$fa-css-prefix}-cloudversify:before { content: fa-content($fa-var-cloudversify); } +.#{$fa-css-prefix}-cocktail:before { content: fa-content($fa-var-cocktail); } +.#{$fa-css-prefix}-code:before { content: fa-content($fa-var-code); } +.#{$fa-css-prefix}-code-branch:before { content: fa-content($fa-var-code-branch); } +.#{$fa-css-prefix}-codepen:before { content: fa-content($fa-var-codepen); } +.#{$fa-css-prefix}-codiepie:before { content: fa-content($fa-var-codiepie); } +.#{$fa-css-prefix}-coffee:before { content: fa-content($fa-var-coffee); } +.#{$fa-css-prefix}-cog:before { content: fa-content($fa-var-cog); } +.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); } +.#{$fa-css-prefix}-coins:before { content: fa-content($fa-var-coins); } +.#{$fa-css-prefix}-columns:before { content: fa-content($fa-var-columns); } +.#{$fa-css-prefix}-comment:before { content: fa-content($fa-var-comment); } +.#{$fa-css-prefix}-comment-alt:before { content: fa-content($fa-var-comment-alt); } +.#{$fa-css-prefix}-comment-dollar:before { content: fa-content($fa-var-comment-dollar); } +.#{$fa-css-prefix}-comment-dots:before { content: fa-content($fa-var-comment-dots); } +.#{$fa-css-prefix}-comment-medical:before { content: fa-content($fa-var-comment-medical); } +.#{$fa-css-prefix}-comment-slash:before { content: fa-content($fa-var-comment-slash); } +.#{$fa-css-prefix}-comments:before { content: fa-content($fa-var-comments); } +.#{$fa-css-prefix}-comments-dollar:before { content: fa-content($fa-var-comments-dollar); } +.#{$fa-css-prefix}-compact-disc:before { content: fa-content($fa-var-compact-disc); } +.#{$fa-css-prefix}-compass:before { content: fa-content($fa-var-compass); } +.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress); } +.#{$fa-css-prefix}-compress-alt:before { content: fa-content($fa-var-compress-alt); } +.#{$fa-css-prefix}-compress-arrows-alt:before { content: fa-content($fa-var-compress-arrows-alt); } +.#{$fa-css-prefix}-concierge-bell:before { content: fa-content($fa-var-concierge-bell); } +.#{$fa-css-prefix}-confluence:before { content: fa-content($fa-var-confluence); } +.#{$fa-css-prefix}-connectdevelop:before { content: fa-content($fa-var-connectdevelop); } +.#{$fa-css-prefix}-contao:before { content: fa-content($fa-var-contao); } +.#{$fa-css-prefix}-cookie:before { content: fa-content($fa-var-cookie); } +.#{$fa-css-prefix}-cookie-bite:before { content: fa-content($fa-var-cookie-bite); } +.#{$fa-css-prefix}-copy:before { content: fa-content($fa-var-copy); } +.#{$fa-css-prefix}-copyright:before { content: fa-content($fa-var-copyright); } +.#{$fa-css-prefix}-cotton-bureau:before { content: fa-content($fa-var-cotton-bureau); } +.#{$fa-css-prefix}-couch:before { content: fa-content($fa-var-couch); } +.#{$fa-css-prefix}-cpanel:before { content: fa-content($fa-var-cpanel); } +.#{$fa-css-prefix}-creative-commons:before { content: fa-content($fa-var-creative-commons); } +.#{$fa-css-prefix}-creative-commons-by:before { content: fa-content($fa-var-creative-commons-by); } +.#{$fa-css-prefix}-creative-commons-nc:before { content: fa-content($fa-var-creative-commons-nc); } +.#{$fa-css-prefix}-creative-commons-nc-eu:before { content: fa-content($fa-var-creative-commons-nc-eu); } +.#{$fa-css-prefix}-creative-commons-nc-jp:before { content: fa-content($fa-var-creative-commons-nc-jp); } +.#{$fa-css-prefix}-creative-commons-nd:before { content: fa-content($fa-var-creative-commons-nd); } +.#{$fa-css-prefix}-creative-commons-pd:before { content: fa-content($fa-var-creative-commons-pd); } +.#{$fa-css-prefix}-creative-commons-pd-alt:before { content: fa-content($fa-var-creative-commons-pd-alt); } +.#{$fa-css-prefix}-creative-commons-remix:before { content: fa-content($fa-var-creative-commons-remix); } +.#{$fa-css-prefix}-creative-commons-sa:before { content: fa-content($fa-var-creative-commons-sa); } +.#{$fa-css-prefix}-creative-commons-sampling:before { content: fa-content($fa-var-creative-commons-sampling); } +.#{$fa-css-prefix}-creative-commons-sampling-plus:before { content: fa-content($fa-var-creative-commons-sampling-plus); } +.#{$fa-css-prefix}-creative-commons-share:before { content: fa-content($fa-var-creative-commons-share); } +.#{$fa-css-prefix}-creative-commons-zero:before { content: fa-content($fa-var-creative-commons-zero); } +.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); } +.#{$fa-css-prefix}-critical-role:before { content: fa-content($fa-var-critical-role); } +.#{$fa-css-prefix}-crop:before { content: fa-content($fa-var-crop); } +.#{$fa-css-prefix}-crop-alt:before { content: fa-content($fa-var-crop-alt); } +.#{$fa-css-prefix}-cross:before { content: fa-content($fa-var-cross); } +.#{$fa-css-prefix}-crosshairs:before { content: fa-content($fa-var-crosshairs); } +.#{$fa-css-prefix}-crow:before { content: fa-content($fa-var-crow); } +.#{$fa-css-prefix}-crown:before { content: fa-content($fa-var-crown); } +.#{$fa-css-prefix}-crutch:before { content: fa-content($fa-var-crutch); } +.#{$fa-css-prefix}-css3:before { content: fa-content($fa-var-css3); } +.#{$fa-css-prefix}-css3-alt:before { content: fa-content($fa-var-css3-alt); } +.#{$fa-css-prefix}-cube:before { content: fa-content($fa-var-cube); } +.#{$fa-css-prefix}-cubes:before { content: fa-content($fa-var-cubes); } +.#{$fa-css-prefix}-cut:before { content: fa-content($fa-var-cut); } +.#{$fa-css-prefix}-cuttlefish:before { content: fa-content($fa-var-cuttlefish); } +.#{$fa-css-prefix}-d-and-d:before { content: fa-content($fa-var-d-and-d); } +.#{$fa-css-prefix}-d-and-d-beyond:before { content: fa-content($fa-var-d-and-d-beyond); } +.#{$fa-css-prefix}-dailymotion:before { content: fa-content($fa-var-dailymotion); } +.#{$fa-css-prefix}-dashcube:before { content: fa-content($fa-var-dashcube); } +.#{$fa-css-prefix}-database:before { content: fa-content($fa-var-database); } +.#{$fa-css-prefix}-deaf:before { content: fa-content($fa-var-deaf); } +.#{$fa-css-prefix}-deezer:before { content: fa-content($fa-var-deezer); } +.#{$fa-css-prefix}-delicious:before { content: fa-content($fa-var-delicious); } +.#{$fa-css-prefix}-democrat:before { content: fa-content($fa-var-democrat); } +.#{$fa-css-prefix}-deploydog:before { content: fa-content($fa-var-deploydog); } +.#{$fa-css-prefix}-deskpro:before { content: fa-content($fa-var-deskpro); } +.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); } +.#{$fa-css-prefix}-dev:before { content: fa-content($fa-var-dev); } +.#{$fa-css-prefix}-deviantart:before { content: fa-content($fa-var-deviantart); } +.#{$fa-css-prefix}-dharmachakra:before { content: fa-content($fa-var-dharmachakra); } +.#{$fa-css-prefix}-dhl:before { content: fa-content($fa-var-dhl); } +.#{$fa-css-prefix}-diagnoses:before { content: fa-content($fa-var-diagnoses); } +.#{$fa-css-prefix}-diaspora:before { content: fa-content($fa-var-diaspora); } +.#{$fa-css-prefix}-dice:before { content: fa-content($fa-var-dice); } +.#{$fa-css-prefix}-dice-d20:before { content: fa-content($fa-var-dice-d20); } +.#{$fa-css-prefix}-dice-d6:before { content: fa-content($fa-var-dice-d6); } +.#{$fa-css-prefix}-dice-five:before { content: fa-content($fa-var-dice-five); } +.#{$fa-css-prefix}-dice-four:before { content: fa-content($fa-var-dice-four); } +.#{$fa-css-prefix}-dice-one:before { content: fa-content($fa-var-dice-one); } +.#{$fa-css-prefix}-dice-six:before { content: fa-content($fa-var-dice-six); } +.#{$fa-css-prefix}-dice-three:before { content: fa-content($fa-var-dice-three); } +.#{$fa-css-prefix}-dice-two:before { content: fa-content($fa-var-dice-two); } +.#{$fa-css-prefix}-digg:before { content: fa-content($fa-var-digg); } +.#{$fa-css-prefix}-digital-ocean:before { content: fa-content($fa-var-digital-ocean); } +.#{$fa-css-prefix}-digital-tachograph:before { content: fa-content($fa-var-digital-tachograph); } +.#{$fa-css-prefix}-directions:before { content: fa-content($fa-var-directions); } +.#{$fa-css-prefix}-discord:before { content: fa-content($fa-var-discord); } +.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); } +.#{$fa-css-prefix}-disease:before { content: fa-content($fa-var-disease); } +.#{$fa-css-prefix}-divide:before { content: fa-content($fa-var-divide); } +.#{$fa-css-prefix}-dizzy:before { content: fa-content($fa-var-dizzy); } +.#{$fa-css-prefix}-dna:before { content: fa-content($fa-var-dna); } +.#{$fa-css-prefix}-dochub:before { content: fa-content($fa-var-dochub); } +.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); } +.#{$fa-css-prefix}-dog:before { content: fa-content($fa-var-dog); } +.#{$fa-css-prefix}-dollar-sign:before { content: fa-content($fa-var-dollar-sign); } +.#{$fa-css-prefix}-dolly:before { content: fa-content($fa-var-dolly); } +.#{$fa-css-prefix}-dolly-flatbed:before { content: fa-content($fa-var-dolly-flatbed); } +.#{$fa-css-prefix}-donate:before { content: fa-content($fa-var-donate); } +.#{$fa-css-prefix}-door-closed:before { content: fa-content($fa-var-door-closed); } +.#{$fa-css-prefix}-door-open:before { content: fa-content($fa-var-door-open); } +.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); } +.#{$fa-css-prefix}-dove:before { content: fa-content($fa-var-dove); } +.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-download); } +.#{$fa-css-prefix}-draft2digital:before { content: fa-content($fa-var-draft2digital); } +.#{$fa-css-prefix}-drafting-compass:before { content: fa-content($fa-var-drafting-compass); } +.#{$fa-css-prefix}-dragon:before { content: fa-content($fa-var-dragon); } +.#{$fa-css-prefix}-draw-polygon:before { content: fa-content($fa-var-draw-polygon); } +.#{$fa-css-prefix}-dribbble:before { content: fa-content($fa-var-dribbble); } +.#{$fa-css-prefix}-dribbble-square:before { content: fa-content($fa-var-dribbble-square); } +.#{$fa-css-prefix}-dropbox:before { content: fa-content($fa-var-dropbox); } +.#{$fa-css-prefix}-drum:before { content: fa-content($fa-var-drum); } +.#{$fa-css-prefix}-drum-steelpan:before { content: fa-content($fa-var-drum-steelpan); } +.#{$fa-css-prefix}-drumstick-bite:before { content: fa-content($fa-var-drumstick-bite); } +.#{$fa-css-prefix}-drupal:before { content: fa-content($fa-var-drupal); } +.#{$fa-css-prefix}-dumbbell:before { content: fa-content($fa-var-dumbbell); } +.#{$fa-css-prefix}-dumpster:before { content: fa-content($fa-var-dumpster); } +.#{$fa-css-prefix}-dumpster-fire:before { content: fa-content($fa-var-dumpster-fire); } +.#{$fa-css-prefix}-dungeon:before { content: fa-content($fa-var-dungeon); } +.#{$fa-css-prefix}-dyalog:before { content: fa-content($fa-var-dyalog); } +.#{$fa-css-prefix}-earlybirds:before { content: fa-content($fa-var-earlybirds); } +.#{$fa-css-prefix}-ebay:before { content: fa-content($fa-var-ebay); } +.#{$fa-css-prefix}-edge:before { content: fa-content($fa-var-edge); } +.#{$fa-css-prefix}-edge-legacy:before { content: fa-content($fa-var-edge-legacy); } +.#{$fa-css-prefix}-edit:before { content: fa-content($fa-var-edit); } +.#{$fa-css-prefix}-egg:before { content: fa-content($fa-var-egg); } +.#{$fa-css-prefix}-eject:before { content: fa-content($fa-var-eject); } +.#{$fa-css-prefix}-elementor:before { content: fa-content($fa-var-elementor); } +.#{$fa-css-prefix}-ellipsis-h:before { content: fa-content($fa-var-ellipsis-h); } +.#{$fa-css-prefix}-ellipsis-v:before { content: fa-content($fa-var-ellipsis-v); } +.#{$fa-css-prefix}-ello:before { content: fa-content($fa-var-ello); } +.#{$fa-css-prefix}-ember:before { content: fa-content($fa-var-ember); } +.#{$fa-css-prefix}-empire:before { content: fa-content($fa-var-empire); } +.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); } +.#{$fa-css-prefix}-envelope-open:before { content: fa-content($fa-var-envelope-open); } +.#{$fa-css-prefix}-envelope-open-text:before { content: fa-content($fa-var-envelope-open-text); } +.#{$fa-css-prefix}-envelope-square:before { content: fa-content($fa-var-envelope-square); } +.#{$fa-css-prefix}-envira:before { content: fa-content($fa-var-envira); } +.#{$fa-css-prefix}-equals:before { content: fa-content($fa-var-equals); } +.#{$fa-css-prefix}-eraser:before { content: fa-content($fa-var-eraser); } +.#{$fa-css-prefix}-erlang:before { content: fa-content($fa-var-erlang); } +.#{$fa-css-prefix}-ethereum:before { content: fa-content($fa-var-ethereum); } +.#{$fa-css-prefix}-ethernet:before { content: fa-content($fa-var-ethernet); } +.#{$fa-css-prefix}-etsy:before { content: fa-content($fa-var-etsy); } +.#{$fa-css-prefix}-euro-sign:before { content: fa-content($fa-var-euro-sign); } +.#{$fa-css-prefix}-evernote:before { content: fa-content($fa-var-evernote); } +.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); } +.#{$fa-css-prefix}-exclamation:before { content: fa-content($fa-var-exclamation); } +.#{$fa-css-prefix}-exclamation-circle:before { content: fa-content($fa-var-exclamation-circle); } +.#{$fa-css-prefix}-exclamation-triangle:before { content: fa-content($fa-var-exclamation-triangle); } +.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand); } +.#{$fa-css-prefix}-expand-alt:before { content: fa-content($fa-var-expand-alt); } +.#{$fa-css-prefix}-expand-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } +.#{$fa-css-prefix}-expeditedssl:before { content: fa-content($fa-var-expeditedssl); } +.#{$fa-css-prefix}-external-link-alt:before { content: fa-content($fa-var-external-link-alt); } +.#{$fa-css-prefix}-external-link-square-alt:before { content: fa-content($fa-var-external-link-square-alt); } +.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); } +.#{$fa-css-prefix}-eye-dropper:before { content: fa-content($fa-var-eye-dropper); } +.#{$fa-css-prefix}-eye-slash:before { content: fa-content($fa-var-eye-slash); } +.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook); } +.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } +.#{$fa-css-prefix}-facebook-messenger:before { content: fa-content($fa-var-facebook-messenger); } +.#{$fa-css-prefix}-facebook-square:before { content: fa-content($fa-var-facebook-square); } +.#{$fa-css-prefix}-fan:before { content: fa-content($fa-var-fan); } +.#{$fa-css-prefix}-fantasy-flight-games:before { content: fa-content($fa-var-fantasy-flight-games); } +.#{$fa-css-prefix}-fast-backward:before { content: fa-content($fa-var-fast-backward); } +.#{$fa-css-prefix}-fast-forward:before { content: fa-content($fa-var-fast-forward); } +.#{$fa-css-prefix}-faucet:before { content: fa-content($fa-var-faucet); } +.#{$fa-css-prefix}-fax:before { content: fa-content($fa-var-fax); } +.#{$fa-css-prefix}-feather:before { content: fa-content($fa-var-feather); } +.#{$fa-css-prefix}-feather-alt:before { content: fa-content($fa-var-feather-alt); } +.#{$fa-css-prefix}-fedex:before { content: fa-content($fa-var-fedex); } +.#{$fa-css-prefix}-fedora:before { content: fa-content($fa-var-fedora); } +.#{$fa-css-prefix}-female:before { content: fa-content($fa-var-female); } +.#{$fa-css-prefix}-fighter-jet:before { content: fa-content($fa-var-fighter-jet); } +.#{$fa-css-prefix}-figma:before { content: fa-content($fa-var-figma); } +.#{$fa-css-prefix}-file:before { content: fa-content($fa-var-file); } +.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); } +.#{$fa-css-prefix}-file-archive:before { content: fa-content($fa-var-file-archive); } +.#{$fa-css-prefix}-file-audio:before { content: fa-content($fa-var-file-audio); } +.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); } +.#{$fa-css-prefix}-file-contract:before { content: fa-content($fa-var-file-contract); } +.#{$fa-css-prefix}-file-csv:before { content: fa-content($fa-var-file-csv); } +.#{$fa-css-prefix}-file-download:before { content: fa-content($fa-var-file-download); } +.#{$fa-css-prefix}-file-excel:before { content: fa-content($fa-var-file-excel); } +.#{$fa-css-prefix}-file-export:before { content: fa-content($fa-var-file-export); } +.#{$fa-css-prefix}-file-image:before { content: fa-content($fa-var-file-image); } +.#{$fa-css-prefix}-file-import:before { content: fa-content($fa-var-file-import); } +.#{$fa-css-prefix}-file-invoice:before { content: fa-content($fa-var-file-invoice); } +.#{$fa-css-prefix}-file-invoice-dollar:before { content: fa-content($fa-var-file-invoice-dollar); } +.#{$fa-css-prefix}-file-medical:before { content: fa-content($fa-var-file-medical); } +.#{$fa-css-prefix}-file-medical-alt:before { content: fa-content($fa-var-file-medical-alt); } +.#{$fa-css-prefix}-file-pdf:before { content: fa-content($fa-var-file-pdf); } +.#{$fa-css-prefix}-file-powerpoint:before { content: fa-content($fa-var-file-powerpoint); } +.#{$fa-css-prefix}-file-prescription:before { content: fa-content($fa-var-file-prescription); } +.#{$fa-css-prefix}-file-signature:before { content: fa-content($fa-var-file-signature); } +.#{$fa-css-prefix}-file-upload:before { content: fa-content($fa-var-file-upload); } +.#{$fa-css-prefix}-file-video:before { content: fa-content($fa-var-file-video); } +.#{$fa-css-prefix}-file-word:before { content: fa-content($fa-var-file-word); } +.#{$fa-css-prefix}-fill:before { content: fa-content($fa-var-fill); } +.#{$fa-css-prefix}-fill-drip:before { content: fa-content($fa-var-fill-drip); } +.#{$fa-css-prefix}-film:before { content: fa-content($fa-var-film); } +.#{$fa-css-prefix}-filter:before { content: fa-content($fa-var-filter); } +.#{$fa-css-prefix}-fingerprint:before { content: fa-content($fa-var-fingerprint); } +.#{$fa-css-prefix}-fire:before { content: fa-content($fa-var-fire); } +.#{$fa-css-prefix}-fire-alt:before { content: fa-content($fa-var-fire-alt); } +.#{$fa-css-prefix}-fire-extinguisher:before { content: fa-content($fa-var-fire-extinguisher); } +.#{$fa-css-prefix}-firefox:before { content: fa-content($fa-var-firefox); } +.#{$fa-css-prefix}-firefox-browser:before { content: fa-content($fa-var-firefox-browser); } +.#{$fa-css-prefix}-first-aid:before { content: fa-content($fa-var-first-aid); } +.#{$fa-css-prefix}-first-order:before { content: fa-content($fa-var-first-order); } +.#{$fa-css-prefix}-first-order-alt:before { content: fa-content($fa-var-first-order-alt); } +.#{$fa-css-prefix}-firstdraft:before { content: fa-content($fa-var-firstdraft); } +.#{$fa-css-prefix}-fish:before { content: fa-content($fa-var-fish); } +.#{$fa-css-prefix}-fist-raised:before { content: fa-content($fa-var-fist-raised); } +.#{$fa-css-prefix}-flag:before { content: fa-content($fa-var-flag); } +.#{$fa-css-prefix}-flag-checkered:before { content: fa-content($fa-var-flag-checkered); } +.#{$fa-css-prefix}-flag-usa:before { content: fa-content($fa-var-flag-usa); } +.#{$fa-css-prefix}-flask:before { content: fa-content($fa-var-flask); } +.#{$fa-css-prefix}-flickr:before { content: fa-content($fa-var-flickr); } +.#{$fa-css-prefix}-flipboard:before { content: fa-content($fa-var-flipboard); } +.#{$fa-css-prefix}-flushed:before { content: fa-content($fa-var-flushed); } +.#{$fa-css-prefix}-fly:before { content: fa-content($fa-var-fly); } +.#{$fa-css-prefix}-folder:before { content: fa-content($fa-var-folder); } +.#{$fa-css-prefix}-folder-minus:before { content: fa-content($fa-var-folder-minus); } +.#{$fa-css-prefix}-folder-open:before { content: fa-content($fa-var-folder-open); } +.#{$fa-css-prefix}-folder-plus:before { content: fa-content($fa-var-folder-plus); } +.#{$fa-css-prefix}-font:before { content: fa-content($fa-var-font); } +.#{$fa-css-prefix}-font-awesome:before { content: fa-content($fa-var-font-awesome); } +.#{$fa-css-prefix}-font-awesome-alt:before { content: fa-content($fa-var-font-awesome-alt); } +.#{$fa-css-prefix}-font-awesome-flag:before { content: fa-content($fa-var-font-awesome-flag); } +.#{$fa-css-prefix}-font-awesome-logo-full:before { content: fa-content($fa-var-font-awesome-logo-full); } +.#{$fa-css-prefix}-fonticons:before { content: fa-content($fa-var-fonticons); } +.#{$fa-css-prefix}-fonticons-fi:before { content: fa-content($fa-var-fonticons-fi); } +.#{$fa-css-prefix}-football-ball:before { content: fa-content($fa-var-football-ball); } +.#{$fa-css-prefix}-fort-awesome:before { content: fa-content($fa-var-fort-awesome); } +.#{$fa-css-prefix}-fort-awesome-alt:before { content: fa-content($fa-var-fort-awesome-alt); } +.#{$fa-css-prefix}-forumbee:before { content: fa-content($fa-var-forumbee); } +.#{$fa-css-prefix}-forward:before { content: fa-content($fa-var-forward); } +.#{$fa-css-prefix}-foursquare:before { content: fa-content($fa-var-foursquare); } +.#{$fa-css-prefix}-free-code-camp:before { content: fa-content($fa-var-free-code-camp); } +.#{$fa-css-prefix}-freebsd:before { content: fa-content($fa-var-freebsd); } +.#{$fa-css-prefix}-frog:before { content: fa-content($fa-var-frog); } +.#{$fa-css-prefix}-frown:before { content: fa-content($fa-var-frown); } +.#{$fa-css-prefix}-frown-open:before { content: fa-content($fa-var-frown-open); } +.#{$fa-css-prefix}-fulcrum:before { content: fa-content($fa-var-fulcrum); } +.#{$fa-css-prefix}-funnel-dollar:before { content: fa-content($fa-var-funnel-dollar); } +.#{$fa-css-prefix}-futbol:before { content: fa-content($fa-var-futbol); } +.#{$fa-css-prefix}-galactic-republic:before { content: fa-content($fa-var-galactic-republic); } +.#{$fa-css-prefix}-galactic-senate:before { content: fa-content($fa-var-galactic-senate); } +.#{$fa-css-prefix}-gamepad:before { content: fa-content($fa-var-gamepad); } +.#{$fa-css-prefix}-gas-pump:before { content: fa-content($fa-var-gas-pump); } +.#{$fa-css-prefix}-gavel:before { content: fa-content($fa-var-gavel); } +.#{$fa-css-prefix}-gem:before { content: fa-content($fa-var-gem); } +.#{$fa-css-prefix}-genderless:before { content: fa-content($fa-var-genderless); } +.#{$fa-css-prefix}-get-pocket:before { content: fa-content($fa-var-get-pocket); } +.#{$fa-css-prefix}-gg:before { content: fa-content($fa-var-gg); } +.#{$fa-css-prefix}-gg-circle:before { content: fa-content($fa-var-gg-circle); } +.#{$fa-css-prefix}-ghost:before { content: fa-content($fa-var-ghost); } +.#{$fa-css-prefix}-gift:before { content: fa-content($fa-var-gift); } +.#{$fa-css-prefix}-gifts:before { content: fa-content($fa-var-gifts); } +.#{$fa-css-prefix}-git:before { content: fa-content($fa-var-git); } +.#{$fa-css-prefix}-git-alt:before { content: fa-content($fa-var-git-alt); } +.#{$fa-css-prefix}-git-square:before { content: fa-content($fa-var-git-square); } +.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); } +.#{$fa-css-prefix}-github-alt:before { content: fa-content($fa-var-github-alt); } +.#{$fa-css-prefix}-github-square:before { content: fa-content($fa-var-github-square); } +.#{$fa-css-prefix}-gitkraken:before { content: fa-content($fa-var-gitkraken); } +.#{$fa-css-prefix}-gitlab:before { content: fa-content($fa-var-gitlab); } +.#{$fa-css-prefix}-gitter:before { content: fa-content($fa-var-gitter); } +.#{$fa-css-prefix}-glass-cheers:before { content: fa-content($fa-var-glass-cheers); } +.#{$fa-css-prefix}-glass-martini:before { content: fa-content($fa-var-glass-martini); } +.#{$fa-css-prefix}-glass-martini-alt:before { content: fa-content($fa-var-glass-martini-alt); } +.#{$fa-css-prefix}-glass-whiskey:before { content: fa-content($fa-var-glass-whiskey); } +.#{$fa-css-prefix}-glasses:before { content: fa-content($fa-var-glasses); } +.#{$fa-css-prefix}-glide:before { content: fa-content($fa-var-glide); } +.#{$fa-css-prefix}-glide-g:before { content: fa-content($fa-var-glide-g); } +.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); } +.#{$fa-css-prefix}-globe-africa:before { content: fa-content($fa-var-globe-africa); } +.#{$fa-css-prefix}-globe-americas:before { content: fa-content($fa-var-globe-americas); } +.#{$fa-css-prefix}-globe-asia:before { content: fa-content($fa-var-globe-asia); } +.#{$fa-css-prefix}-globe-europe:before { content: fa-content($fa-var-globe-europe); } +.#{$fa-css-prefix}-gofore:before { content: fa-content($fa-var-gofore); } +.#{$fa-css-prefix}-golf-ball:before { content: fa-content($fa-var-golf-ball); } +.#{$fa-css-prefix}-goodreads:before { content: fa-content($fa-var-goodreads); } +.#{$fa-css-prefix}-goodreads-g:before { content: fa-content($fa-var-goodreads-g); } +.#{$fa-css-prefix}-google:before { content: fa-content($fa-var-google); } +.#{$fa-css-prefix}-google-drive:before { content: fa-content($fa-var-google-drive); } +.#{$fa-css-prefix}-google-pay:before { content: fa-content($fa-var-google-pay); } +.#{$fa-css-prefix}-google-play:before { content: fa-content($fa-var-google-play); } +.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus); } +.#{$fa-css-prefix}-google-plus-g:before { content: fa-content($fa-var-google-plus-g); } +.#{$fa-css-prefix}-google-plus-square:before { content: fa-content($fa-var-google-plus-square); } +.#{$fa-css-prefix}-google-wallet:before { content: fa-content($fa-var-google-wallet); } +.#{$fa-css-prefix}-gopuram:before { content: fa-content($fa-var-gopuram); } +.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); } +.#{$fa-css-prefix}-gratipay:before { content: fa-content($fa-var-gratipay); } +.#{$fa-css-prefix}-grav:before { content: fa-content($fa-var-grav); } +.#{$fa-css-prefix}-greater-than:before { content: fa-content($fa-var-greater-than); } +.#{$fa-css-prefix}-greater-than-equal:before { content: fa-content($fa-var-greater-than-equal); } +.#{$fa-css-prefix}-grimace:before { content: fa-content($fa-var-grimace); } +.#{$fa-css-prefix}-grin:before { content: fa-content($fa-var-grin); } +.#{$fa-css-prefix}-grin-alt:before { content: fa-content($fa-var-grin-alt); } +.#{$fa-css-prefix}-grin-beam:before { content: fa-content($fa-var-grin-beam); } +.#{$fa-css-prefix}-grin-beam-sweat:before { content: fa-content($fa-var-grin-beam-sweat); } +.#{$fa-css-prefix}-grin-hearts:before { content: fa-content($fa-var-grin-hearts); } +.#{$fa-css-prefix}-grin-squint:before { content: fa-content($fa-var-grin-squint); } +.#{$fa-css-prefix}-grin-squint-tears:before { content: fa-content($fa-var-grin-squint-tears); } +.#{$fa-css-prefix}-grin-stars:before { content: fa-content($fa-var-grin-stars); } +.#{$fa-css-prefix}-grin-tears:before { content: fa-content($fa-var-grin-tears); } +.#{$fa-css-prefix}-grin-tongue:before { content: fa-content($fa-var-grin-tongue); } +.#{$fa-css-prefix}-grin-tongue-squint:before { content: fa-content($fa-var-grin-tongue-squint); } +.#{$fa-css-prefix}-grin-tongue-wink:before { content: fa-content($fa-var-grin-tongue-wink); } +.#{$fa-css-prefix}-grin-wink:before { content: fa-content($fa-var-grin-wink); } +.#{$fa-css-prefix}-grip-horizontal:before { content: fa-content($fa-var-grip-horizontal); } +.#{$fa-css-prefix}-grip-lines:before { content: fa-content($fa-var-grip-lines); } +.#{$fa-css-prefix}-grip-lines-vertical:before { content: fa-content($fa-var-grip-lines-vertical); } +.#{$fa-css-prefix}-grip-vertical:before { content: fa-content($fa-var-grip-vertical); } +.#{$fa-css-prefix}-gripfire:before { content: fa-content($fa-var-gripfire); } +.#{$fa-css-prefix}-grunt:before { content: fa-content($fa-var-grunt); } +.#{$fa-css-prefix}-guitar:before { content: fa-content($fa-var-guitar); } +.#{$fa-css-prefix}-gulp:before { content: fa-content($fa-var-gulp); } +.#{$fa-css-prefix}-h-square:before { content: fa-content($fa-var-h-square); } +.#{$fa-css-prefix}-hacker-news:before { content: fa-content($fa-var-hacker-news); } +.#{$fa-css-prefix}-hacker-news-square:before { content: fa-content($fa-var-hacker-news-square); } +.#{$fa-css-prefix}-hackerrank:before { content: fa-content($fa-var-hackerrank); } +.#{$fa-css-prefix}-hamburger:before { content: fa-content($fa-var-hamburger); } +.#{$fa-css-prefix}-hammer:before { content: fa-content($fa-var-hammer); } +.#{$fa-css-prefix}-hamsa:before { content: fa-content($fa-var-hamsa); } +.#{$fa-css-prefix}-hand-holding:before { content: fa-content($fa-var-hand-holding); } +.#{$fa-css-prefix}-hand-holding-heart:before { content: fa-content($fa-var-hand-holding-heart); } +.#{$fa-css-prefix}-hand-holding-medical:before { content: fa-content($fa-var-hand-holding-medical); } +.#{$fa-css-prefix}-hand-holding-usd:before { content: fa-content($fa-var-hand-holding-usd); } +.#{$fa-css-prefix}-hand-holding-water:before { content: fa-content($fa-var-hand-holding-water); } +.#{$fa-css-prefix}-hand-lizard:before { content: fa-content($fa-var-hand-lizard); } +.#{$fa-css-prefix}-hand-middle-finger:before { content: fa-content($fa-var-hand-middle-finger); } +.#{$fa-css-prefix}-hand-paper:before { content: fa-content($fa-var-hand-paper); } +.#{$fa-css-prefix}-hand-peace:before { content: fa-content($fa-var-hand-peace); } +.#{$fa-css-prefix}-hand-point-down:before { content: fa-content($fa-var-hand-point-down); } +.#{$fa-css-prefix}-hand-point-left:before { content: fa-content($fa-var-hand-point-left); } +.#{$fa-css-prefix}-hand-point-right:before { content: fa-content($fa-var-hand-point-right); } +.#{$fa-css-prefix}-hand-point-up:before { content: fa-content($fa-var-hand-point-up); } +.#{$fa-css-prefix}-hand-pointer:before { content: fa-content($fa-var-hand-pointer); } +.#{$fa-css-prefix}-hand-rock:before { content: fa-content($fa-var-hand-rock); } +.#{$fa-css-prefix}-hand-scissors:before { content: fa-content($fa-var-hand-scissors); } +.#{$fa-css-prefix}-hand-sparkles:before { content: fa-content($fa-var-hand-sparkles); } +.#{$fa-css-prefix}-hand-spock:before { content: fa-content($fa-var-hand-spock); } +.#{$fa-css-prefix}-hands:before { content: fa-content($fa-var-hands); } +.#{$fa-css-prefix}-hands-helping:before { content: fa-content($fa-var-hands-helping); } +.#{$fa-css-prefix}-hands-wash:before { content: fa-content($fa-var-hands-wash); } +.#{$fa-css-prefix}-handshake:before { content: fa-content($fa-var-handshake); } +.#{$fa-css-prefix}-handshake-alt-slash:before { content: fa-content($fa-var-handshake-alt-slash); } +.#{$fa-css-prefix}-handshake-slash:before { content: fa-content($fa-var-handshake-slash); } +.#{$fa-css-prefix}-hanukiah:before { content: fa-content($fa-var-hanukiah); } +.#{$fa-css-prefix}-hard-hat:before { content: fa-content($fa-var-hard-hat); } +.#{$fa-css-prefix}-hashtag:before { content: fa-content($fa-var-hashtag); } +.#{$fa-css-prefix}-hat-cowboy:before { content: fa-content($fa-var-hat-cowboy); } +.#{$fa-css-prefix}-hat-cowboy-side:before { content: fa-content($fa-var-hat-cowboy-side); } +.#{$fa-css-prefix}-hat-wizard:before { content: fa-content($fa-var-hat-wizard); } +.#{$fa-css-prefix}-hdd:before { content: fa-content($fa-var-hdd); } +.#{$fa-css-prefix}-head-side-cough:before { content: fa-content($fa-var-head-side-cough); } +.#{$fa-css-prefix}-head-side-cough-slash:before { content: fa-content($fa-var-head-side-cough-slash); } +.#{$fa-css-prefix}-head-side-mask:before { content: fa-content($fa-var-head-side-mask); } +.#{$fa-css-prefix}-head-side-virus:before { content: fa-content($fa-var-head-side-virus); } +.#{$fa-css-prefix}-heading:before { content: fa-content($fa-var-heading); } +.#{$fa-css-prefix}-headphones:before { content: fa-content($fa-var-headphones); } +.#{$fa-css-prefix}-headphones-alt:before { content: fa-content($fa-var-headphones-alt); } +.#{$fa-css-prefix}-headset:before { content: fa-content($fa-var-headset); } +.#{$fa-css-prefix}-heart:before { content: fa-content($fa-var-heart); } +.#{$fa-css-prefix}-heart-broken:before { content: fa-content($fa-var-heart-broken); } +.#{$fa-css-prefix}-heartbeat:before { content: fa-content($fa-var-heartbeat); } +.#{$fa-css-prefix}-helicopter:before { content: fa-content($fa-var-helicopter); } +.#{$fa-css-prefix}-highlighter:before { content: fa-content($fa-var-highlighter); } +.#{$fa-css-prefix}-hiking:before { content: fa-content($fa-var-hiking); } +.#{$fa-css-prefix}-hippo:before { content: fa-content($fa-var-hippo); } +.#{$fa-css-prefix}-hips:before { content: fa-content($fa-var-hips); } +.#{$fa-css-prefix}-hire-a-helper:before { content: fa-content($fa-var-hire-a-helper); } +.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); } +.#{$fa-css-prefix}-hockey-puck:before { content: fa-content($fa-var-hockey-puck); } +.#{$fa-css-prefix}-holly-berry:before { content: fa-content($fa-var-holly-berry); } +.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); } +.#{$fa-css-prefix}-hooli:before { content: fa-content($fa-var-hooli); } +.#{$fa-css-prefix}-hornbill:before { content: fa-content($fa-var-hornbill); } +.#{$fa-css-prefix}-horse:before { content: fa-content($fa-var-horse); } +.#{$fa-css-prefix}-horse-head:before { content: fa-content($fa-var-horse-head); } +.#{$fa-css-prefix}-hospital:before { content: fa-content($fa-var-hospital); } +.#{$fa-css-prefix}-hospital-alt:before { content: fa-content($fa-var-hospital-alt); } +.#{$fa-css-prefix}-hospital-symbol:before { content: fa-content($fa-var-hospital-symbol); } +.#{$fa-css-prefix}-hospital-user:before { content: fa-content($fa-var-hospital-user); } +.#{$fa-css-prefix}-hot-tub:before { content: fa-content($fa-var-hot-tub); } +.#{$fa-css-prefix}-hotdog:before { content: fa-content($fa-var-hotdog); } +.#{$fa-css-prefix}-hotel:before { content: fa-content($fa-var-hotel); } +.#{$fa-css-prefix}-hotjar:before { content: fa-content($fa-var-hotjar); } +.#{$fa-css-prefix}-hourglass:before { content: fa-content($fa-var-hourglass); } +.#{$fa-css-prefix}-hourglass-end:before { content: fa-content($fa-var-hourglass-end); } +.#{$fa-css-prefix}-hourglass-half:before { content: fa-content($fa-var-hourglass-half); } +.#{$fa-css-prefix}-hourglass-start:before { content: fa-content($fa-var-hourglass-start); } +.#{$fa-css-prefix}-house-damage:before { content: fa-content($fa-var-house-damage); } +.#{$fa-css-prefix}-house-user:before { content: fa-content($fa-var-house-user); } +.#{$fa-css-prefix}-houzz:before { content: fa-content($fa-var-houzz); } +.#{$fa-css-prefix}-hryvnia:before { content: fa-content($fa-var-hryvnia); } +.#{$fa-css-prefix}-html5:before { content: fa-content($fa-var-html5); } +.#{$fa-css-prefix}-hubspot:before { content: fa-content($fa-var-hubspot); } +.#{$fa-css-prefix}-i-cursor:before { content: fa-content($fa-var-i-cursor); } +.#{$fa-css-prefix}-ice-cream:before { content: fa-content($fa-var-ice-cream); } +.#{$fa-css-prefix}-icicles:before { content: fa-content($fa-var-icicles); } +.#{$fa-css-prefix}-icons:before { content: fa-content($fa-var-icons); } +.#{$fa-css-prefix}-id-badge:before { content: fa-content($fa-var-id-badge); } +.#{$fa-css-prefix}-id-card:before { content: fa-content($fa-var-id-card); } +.#{$fa-css-prefix}-id-card-alt:before { content: fa-content($fa-var-id-card-alt); } +.#{$fa-css-prefix}-ideal:before { content: fa-content($fa-var-ideal); } +.#{$fa-css-prefix}-igloo:before { content: fa-content($fa-var-igloo); } +.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } +.#{$fa-css-prefix}-images:before { content: fa-content($fa-var-images); } +.#{$fa-css-prefix}-imdb:before { content: fa-content($fa-var-imdb); } +.#{$fa-css-prefix}-inbox:before { content: fa-content($fa-var-inbox); } +.#{$fa-css-prefix}-indent:before { content: fa-content($fa-var-indent); } +.#{$fa-css-prefix}-industry:before { content: fa-content($fa-var-industry); } +.#{$fa-css-prefix}-infinity:before { content: fa-content($fa-var-infinity); } +.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); } +.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); } +.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); } +.#{$fa-css-prefix}-instagram-square:before { content: fa-content($fa-var-instagram-square); } +.#{$fa-css-prefix}-intercom:before { content: fa-content($fa-var-intercom); } +.#{$fa-css-prefix}-internet-explorer:before { content: fa-content($fa-var-internet-explorer); } +.#{$fa-css-prefix}-invision:before { content: fa-content($fa-var-invision); } +.#{$fa-css-prefix}-ioxhost:before { content: fa-content($fa-var-ioxhost); } +.#{$fa-css-prefix}-italic:before { content: fa-content($fa-var-italic); } +.#{$fa-css-prefix}-itch-io:before { content: fa-content($fa-var-itch-io); } +.#{$fa-css-prefix}-itunes:before { content: fa-content($fa-var-itunes); } +.#{$fa-css-prefix}-itunes-note:before { content: fa-content($fa-var-itunes-note); } +.#{$fa-css-prefix}-java:before { content: fa-content($fa-var-java); } +.#{$fa-css-prefix}-jedi:before { content: fa-content($fa-var-jedi); } +.#{$fa-css-prefix}-jedi-order:before { content: fa-content($fa-var-jedi-order); } +.#{$fa-css-prefix}-jenkins:before { content: fa-content($fa-var-jenkins); } +.#{$fa-css-prefix}-jira:before { content: fa-content($fa-var-jira); } +.#{$fa-css-prefix}-joget:before { content: fa-content($fa-var-joget); } +.#{$fa-css-prefix}-joint:before { content: fa-content($fa-var-joint); } +.#{$fa-css-prefix}-joomla:before { content: fa-content($fa-var-joomla); } +.#{$fa-css-prefix}-journal-whills:before { content: fa-content($fa-var-journal-whills); } +.#{$fa-css-prefix}-js:before { content: fa-content($fa-var-js); } +.#{$fa-css-prefix}-js-square:before { content: fa-content($fa-var-js-square); } +.#{$fa-css-prefix}-jsfiddle:before { content: fa-content($fa-var-jsfiddle); } +.#{$fa-css-prefix}-kaaba:before { content: fa-content($fa-var-kaaba); } +.#{$fa-css-prefix}-kaggle:before { content: fa-content($fa-var-kaggle); } +.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); } +.#{$fa-css-prefix}-keybase:before { content: fa-content($fa-var-keybase); } +.#{$fa-css-prefix}-keyboard:before { content: fa-content($fa-var-keyboard); } +.#{$fa-css-prefix}-keycdn:before { content: fa-content($fa-var-keycdn); } +.#{$fa-css-prefix}-khanda:before { content: fa-content($fa-var-khanda); } +.#{$fa-css-prefix}-kickstarter:before { content: fa-content($fa-var-kickstarter); } +.#{$fa-css-prefix}-kickstarter-k:before { content: fa-content($fa-var-kickstarter-k); } +.#{$fa-css-prefix}-kiss:before { content: fa-content($fa-var-kiss); } +.#{$fa-css-prefix}-kiss-beam:before { content: fa-content($fa-var-kiss-beam); } +.#{$fa-css-prefix}-kiss-wink-heart:before { content: fa-content($fa-var-kiss-wink-heart); } +.#{$fa-css-prefix}-kiwi-bird:before { content: fa-content($fa-var-kiwi-bird); } +.#{$fa-css-prefix}-korvue:before { content: fa-content($fa-var-korvue); } +.#{$fa-css-prefix}-landmark:before { content: fa-content($fa-var-landmark); } +.#{$fa-css-prefix}-language:before { content: fa-content($fa-var-language); } +.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); } +.#{$fa-css-prefix}-laptop-code:before { content: fa-content($fa-var-laptop-code); } +.#{$fa-css-prefix}-laptop-house:before { content: fa-content($fa-var-laptop-house); } +.#{$fa-css-prefix}-laptop-medical:before { content: fa-content($fa-var-laptop-medical); } +.#{$fa-css-prefix}-laravel:before { content: fa-content($fa-var-laravel); } +.#{$fa-css-prefix}-lastfm:before { content: fa-content($fa-var-lastfm); } +.#{$fa-css-prefix}-lastfm-square:before { content: fa-content($fa-var-lastfm-square); } +.#{$fa-css-prefix}-laugh:before { content: fa-content($fa-var-laugh); } +.#{$fa-css-prefix}-laugh-beam:before { content: fa-content($fa-var-laugh-beam); } +.#{$fa-css-prefix}-laugh-squint:before { content: fa-content($fa-var-laugh-squint); } +.#{$fa-css-prefix}-laugh-wink:before { content: fa-content($fa-var-laugh-wink); } +.#{$fa-css-prefix}-layer-group:before { content: fa-content($fa-var-layer-group); } +.#{$fa-css-prefix}-leaf:before { content: fa-content($fa-var-leaf); } +.#{$fa-css-prefix}-leanpub:before { content: fa-content($fa-var-leanpub); } +.#{$fa-css-prefix}-lemon:before { content: fa-content($fa-var-lemon); } +.#{$fa-css-prefix}-less:before { content: fa-content($fa-var-less); } +.#{$fa-css-prefix}-less-than:before { content: fa-content($fa-var-less-than); } +.#{$fa-css-prefix}-less-than-equal:before { content: fa-content($fa-var-less-than-equal); } +.#{$fa-css-prefix}-level-down-alt:before { content: fa-content($fa-var-level-down-alt); } +.#{$fa-css-prefix}-level-up-alt:before { content: fa-content($fa-var-level-up-alt); } +.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); } +.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); } +.#{$fa-css-prefix}-line:before { content: fa-content($fa-var-line); } +.#{$fa-css-prefix}-link:before { content: fa-content($fa-var-link); } +.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin); } +.#{$fa-css-prefix}-linkedin-in:before { content: fa-content($fa-var-linkedin-in); } +.#{$fa-css-prefix}-linode:before { content: fa-content($fa-var-linode); } +.#{$fa-css-prefix}-linux:before { content: fa-content($fa-var-linux); } +.#{$fa-css-prefix}-lira-sign:before { content: fa-content($fa-var-lira-sign); } +.#{$fa-css-prefix}-list:before { content: fa-content($fa-var-list); } +.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); } +.#{$fa-css-prefix}-list-ol:before { content: fa-content($fa-var-list-ol); } +.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); } +.#{$fa-css-prefix}-location-arrow:before { content: fa-content($fa-var-location-arrow); } +.#{$fa-css-prefix}-lock:before { content: fa-content($fa-var-lock); } +.#{$fa-css-prefix}-lock-open:before { content: fa-content($fa-var-lock-open); } +.#{$fa-css-prefix}-long-arrow-alt-down:before { content: fa-content($fa-var-long-arrow-alt-down); } +.#{$fa-css-prefix}-long-arrow-alt-left:before { content: fa-content($fa-var-long-arrow-alt-left); } +.#{$fa-css-prefix}-long-arrow-alt-right:before { content: fa-content($fa-var-long-arrow-alt-right); } +.#{$fa-css-prefix}-long-arrow-alt-up:before { content: fa-content($fa-var-long-arrow-alt-up); } +.#{$fa-css-prefix}-low-vision:before { content: fa-content($fa-var-low-vision); } +.#{$fa-css-prefix}-luggage-cart:before { content: fa-content($fa-var-luggage-cart); } +.#{$fa-css-prefix}-lungs:before { content: fa-content($fa-var-lungs); } +.#{$fa-css-prefix}-lungs-virus:before { content: fa-content($fa-var-lungs-virus); } +.#{$fa-css-prefix}-lyft:before { content: fa-content($fa-var-lyft); } +.#{$fa-css-prefix}-magento:before { content: fa-content($fa-var-magento); } +.#{$fa-css-prefix}-magic:before { content: fa-content($fa-var-magic); } +.#{$fa-css-prefix}-magnet:before { content: fa-content($fa-var-magnet); } +.#{$fa-css-prefix}-mail-bulk:before { content: fa-content($fa-var-mail-bulk); } +.#{$fa-css-prefix}-mailchimp:before { content: fa-content($fa-var-mailchimp); } +.#{$fa-css-prefix}-male:before { content: fa-content($fa-var-male); } +.#{$fa-css-prefix}-mandalorian:before { content: fa-content($fa-var-mandalorian); } +.#{$fa-css-prefix}-map:before { content: fa-content($fa-var-map); } +.#{$fa-css-prefix}-map-marked:before { content: fa-content($fa-var-map-marked); } +.#{$fa-css-prefix}-map-marked-alt:before { content: fa-content($fa-var-map-marked-alt); } +.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker); } +.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); } +.#{$fa-css-prefix}-map-pin:before { content: fa-content($fa-var-map-pin); } +.#{$fa-css-prefix}-map-signs:before { content: fa-content($fa-var-map-signs); } +.#{$fa-css-prefix}-markdown:before { content: fa-content($fa-var-markdown); } +.#{$fa-css-prefix}-marker:before { content: fa-content($fa-var-marker); } +.#{$fa-css-prefix}-mars:before { content: fa-content($fa-var-mars); } +.#{$fa-css-prefix}-mars-double:before { content: fa-content($fa-var-mars-double); } +.#{$fa-css-prefix}-mars-stroke:before { content: fa-content($fa-var-mars-stroke); } +.#{$fa-css-prefix}-mars-stroke-h:before { content: fa-content($fa-var-mars-stroke-h); } +.#{$fa-css-prefix}-mars-stroke-v:before { content: fa-content($fa-var-mars-stroke-v); } +.#{$fa-css-prefix}-mask:before { content: fa-content($fa-var-mask); } +.#{$fa-css-prefix}-mastodon:before { content: fa-content($fa-var-mastodon); } +.#{$fa-css-prefix}-maxcdn:before { content: fa-content($fa-var-maxcdn); } +.#{$fa-css-prefix}-mdb:before { content: fa-content($fa-var-mdb); } +.#{$fa-css-prefix}-medal:before { content: fa-content($fa-var-medal); } +.#{$fa-css-prefix}-medapps:before { content: fa-content($fa-var-medapps); } +.#{$fa-css-prefix}-medium:before { content: fa-content($fa-var-medium); } +.#{$fa-css-prefix}-medium-m:before { content: fa-content($fa-var-medium-m); } +.#{$fa-css-prefix}-medkit:before { content: fa-content($fa-var-medkit); } +.#{$fa-css-prefix}-medrt:before { content: fa-content($fa-var-medrt); } +.#{$fa-css-prefix}-meetup:before { content: fa-content($fa-var-meetup); } +.#{$fa-css-prefix}-megaport:before { content: fa-content($fa-var-megaport); } +.#{$fa-css-prefix}-meh:before { content: fa-content($fa-var-meh); } +.#{$fa-css-prefix}-meh-blank:before { content: fa-content($fa-var-meh-blank); } +.#{$fa-css-prefix}-meh-rolling-eyes:before { content: fa-content($fa-var-meh-rolling-eyes); } +.#{$fa-css-prefix}-memory:before { content: fa-content($fa-var-memory); } +.#{$fa-css-prefix}-mendeley:before { content: fa-content($fa-var-mendeley); } +.#{$fa-css-prefix}-menorah:before { content: fa-content($fa-var-menorah); } +.#{$fa-css-prefix}-mercury:before { content: fa-content($fa-var-mercury); } +.#{$fa-css-prefix}-meteor:before { content: fa-content($fa-var-meteor); } +.#{$fa-css-prefix}-microblog:before { content: fa-content($fa-var-microblog); } +.#{$fa-css-prefix}-microchip:before { content: fa-content($fa-var-microchip); } +.#{$fa-css-prefix}-microphone:before { content: fa-content($fa-var-microphone); } +.#{$fa-css-prefix}-microphone-alt:before { content: fa-content($fa-var-microphone-alt); } +.#{$fa-css-prefix}-microphone-alt-slash:before { content: fa-content($fa-var-microphone-alt-slash); } +.#{$fa-css-prefix}-microphone-slash:before { content: fa-content($fa-var-microphone-slash); } +.#{$fa-css-prefix}-microscope:before { content: fa-content($fa-var-microscope); } +.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); } +.#{$fa-css-prefix}-minus:before { content: fa-content($fa-var-minus); } +.#{$fa-css-prefix}-minus-circle:before { content: fa-content($fa-var-minus-circle); } +.#{$fa-css-prefix}-minus-square:before { content: fa-content($fa-var-minus-square); } +.#{$fa-css-prefix}-mitten:before { content: fa-content($fa-var-mitten); } +.#{$fa-css-prefix}-mix:before { content: fa-content($fa-var-mix); } +.#{$fa-css-prefix}-mixcloud:before { content: fa-content($fa-var-mixcloud); } +.#{$fa-css-prefix}-mixer:before { content: fa-content($fa-var-mixer); } +.#{$fa-css-prefix}-mizuni:before { content: fa-content($fa-var-mizuni); } +.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile); } +.#{$fa-css-prefix}-mobile-alt:before { content: fa-content($fa-var-mobile-alt); } +.#{$fa-css-prefix}-modx:before { content: fa-content($fa-var-modx); } +.#{$fa-css-prefix}-monero:before { content: fa-content($fa-var-monero); } +.#{$fa-css-prefix}-money-bill:before { content: fa-content($fa-var-money-bill); } +.#{$fa-css-prefix}-money-bill-alt:before { content: fa-content($fa-var-money-bill-alt); } +.#{$fa-css-prefix}-money-bill-wave:before { content: fa-content($fa-var-money-bill-wave); } +.#{$fa-css-prefix}-money-bill-wave-alt:before { content: fa-content($fa-var-money-bill-wave-alt); } +.#{$fa-css-prefix}-money-check:before { content: fa-content($fa-var-money-check); } +.#{$fa-css-prefix}-money-check-alt:before { content: fa-content($fa-var-money-check-alt); } +.#{$fa-css-prefix}-monument:before { content: fa-content($fa-var-monument); } +.#{$fa-css-prefix}-moon:before { content: fa-content($fa-var-moon); } +.#{$fa-css-prefix}-mortar-pestle:before { content: fa-content($fa-var-mortar-pestle); } +.#{$fa-css-prefix}-mosque:before { content: fa-content($fa-var-mosque); } +.#{$fa-css-prefix}-motorcycle:before { content: fa-content($fa-var-motorcycle); } +.#{$fa-css-prefix}-mountain:before { content: fa-content($fa-var-mountain); } +.#{$fa-css-prefix}-mouse:before { content: fa-content($fa-var-mouse); } +.#{$fa-css-prefix}-mouse-pointer:before { content: fa-content($fa-var-mouse-pointer); } +.#{$fa-css-prefix}-mug-hot:before { content: fa-content($fa-var-mug-hot); } +.#{$fa-css-prefix}-music:before { content: fa-content($fa-var-music); } +.#{$fa-css-prefix}-napster:before { content: fa-content($fa-var-napster); } +.#{$fa-css-prefix}-neos:before { content: fa-content($fa-var-neos); } +.#{$fa-css-prefix}-network-wired:before { content: fa-content($fa-var-network-wired); } +.#{$fa-css-prefix}-neuter:before { content: fa-content($fa-var-neuter); } +.#{$fa-css-prefix}-newspaper:before { content: fa-content($fa-var-newspaper); } +.#{$fa-css-prefix}-nimblr:before { content: fa-content($fa-var-nimblr); } +.#{$fa-css-prefix}-node:before { content: fa-content($fa-var-node); } +.#{$fa-css-prefix}-node-js:before { content: fa-content($fa-var-node-js); } +.#{$fa-css-prefix}-not-equal:before { content: fa-content($fa-var-not-equal); } +.#{$fa-css-prefix}-notes-medical:before { content: fa-content($fa-var-notes-medical); } +.#{$fa-css-prefix}-npm:before { content: fa-content($fa-var-npm); } +.#{$fa-css-prefix}-ns8:before { content: fa-content($fa-var-ns8); } +.#{$fa-css-prefix}-nutritionix:before { content: fa-content($fa-var-nutritionix); } +.#{$fa-css-prefix}-object-group:before { content: fa-content($fa-var-object-group); } +.#{$fa-css-prefix}-object-ungroup:before { content: fa-content($fa-var-object-ungroup); } +.#{$fa-css-prefix}-odnoklassniki:before { content: fa-content($fa-var-odnoklassniki); } +.#{$fa-css-prefix}-odnoklassniki-square:before { content: fa-content($fa-var-odnoklassniki-square); } +.#{$fa-css-prefix}-oil-can:before { content: fa-content($fa-var-oil-can); } +.#{$fa-css-prefix}-old-republic:before { content: fa-content($fa-var-old-republic); } +.#{$fa-css-prefix}-om:before { content: fa-content($fa-var-om); } +.#{$fa-css-prefix}-opencart:before { content: fa-content($fa-var-opencart); } +.#{$fa-css-prefix}-openid:before { content: fa-content($fa-var-openid); } +.#{$fa-css-prefix}-opera:before { content: fa-content($fa-var-opera); } +.#{$fa-css-prefix}-optin-monster:before { content: fa-content($fa-var-optin-monster); } +.#{$fa-css-prefix}-orcid:before { content: fa-content($fa-var-orcid); } +.#{$fa-css-prefix}-osi:before { content: fa-content($fa-var-osi); } +.#{$fa-css-prefix}-otter:before { content: fa-content($fa-var-otter); } +.#{$fa-css-prefix}-outdent:before { content: fa-content($fa-var-outdent); } +.#{$fa-css-prefix}-page4:before { content: fa-content($fa-var-page4); } +.#{$fa-css-prefix}-pagelines:before { content: fa-content($fa-var-pagelines); } +.#{$fa-css-prefix}-pager:before { content: fa-content($fa-var-pager); } +.#{$fa-css-prefix}-paint-brush:before { content: fa-content($fa-var-paint-brush); } +.#{$fa-css-prefix}-paint-roller:before { content: fa-content($fa-var-paint-roller); } +.#{$fa-css-prefix}-palette:before { content: fa-content($fa-var-palette); } +.#{$fa-css-prefix}-palfed:before { content: fa-content($fa-var-palfed); } +.#{$fa-css-prefix}-pallet:before { content: fa-content($fa-var-pallet); } +.#{$fa-css-prefix}-paper-plane:before { content: fa-content($fa-var-paper-plane); } +.#{$fa-css-prefix}-paperclip:before { content: fa-content($fa-var-paperclip); } +.#{$fa-css-prefix}-parachute-box:before { content: fa-content($fa-var-parachute-box); } +.#{$fa-css-prefix}-paragraph:before { content: fa-content($fa-var-paragraph); } +.#{$fa-css-prefix}-parking:before { content: fa-content($fa-var-parking); } +.#{$fa-css-prefix}-passport:before { content: fa-content($fa-var-passport); } +.#{$fa-css-prefix}-pastafarianism:before { content: fa-content($fa-var-pastafarianism); } +.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-paste); } +.#{$fa-css-prefix}-patreon:before { content: fa-content($fa-var-patreon); } +.#{$fa-css-prefix}-pause:before { content: fa-content($fa-var-pause); } +.#{$fa-css-prefix}-pause-circle:before { content: fa-content($fa-var-pause-circle); } +.#{$fa-css-prefix}-paw:before { content: fa-content($fa-var-paw); } +.#{$fa-css-prefix}-paypal:before { content: fa-content($fa-var-paypal); } +.#{$fa-css-prefix}-peace:before { content: fa-content($fa-var-peace); } +.#{$fa-css-prefix}-pen:before { content: fa-content($fa-var-pen); } +.#{$fa-css-prefix}-pen-alt:before { content: fa-content($fa-var-pen-alt); } +.#{$fa-css-prefix}-pen-fancy:before { content: fa-content($fa-var-pen-fancy); } +.#{$fa-css-prefix}-pen-nib:before { content: fa-content($fa-var-pen-nib); } +.#{$fa-css-prefix}-pen-square:before { content: fa-content($fa-var-pen-square); } +.#{$fa-css-prefix}-pencil-alt:before { content: fa-content($fa-var-pencil-alt); } +.#{$fa-css-prefix}-pencil-ruler:before { content: fa-content($fa-var-pencil-ruler); } +.#{$fa-css-prefix}-penny-arcade:before { content: fa-content($fa-var-penny-arcade); } +.#{$fa-css-prefix}-people-arrows:before { content: fa-content($fa-var-people-arrows); } +.#{$fa-css-prefix}-people-carry:before { content: fa-content($fa-var-people-carry); } +.#{$fa-css-prefix}-pepper-hot:before { content: fa-content($fa-var-pepper-hot); } +.#{$fa-css-prefix}-percent:before { content: fa-content($fa-var-percent); } +.#{$fa-css-prefix}-percentage:before { content: fa-content($fa-var-percentage); } +.#{$fa-css-prefix}-periscope:before { content: fa-content($fa-var-periscope); } +.#{$fa-css-prefix}-person-booth:before { content: fa-content($fa-var-person-booth); } +.#{$fa-css-prefix}-phabricator:before { content: fa-content($fa-var-phabricator); } +.#{$fa-css-prefix}-phoenix-framework:before { content: fa-content($fa-var-phoenix-framework); } +.#{$fa-css-prefix}-phoenix-squadron:before { content: fa-content($fa-var-phoenix-squadron); } +.#{$fa-css-prefix}-phone:before { content: fa-content($fa-var-phone); } +.#{$fa-css-prefix}-phone-alt:before { content: fa-content($fa-var-phone-alt); } +.#{$fa-css-prefix}-phone-slash:before { content: fa-content($fa-var-phone-slash); } +.#{$fa-css-prefix}-phone-square:before { content: fa-content($fa-var-phone-square); } +.#{$fa-css-prefix}-phone-square-alt:before { content: fa-content($fa-var-phone-square-alt); } +.#{$fa-css-prefix}-phone-volume:before { content: fa-content($fa-var-phone-volume); } +.#{$fa-css-prefix}-photo-video:before { content: fa-content($fa-var-photo-video); } +.#{$fa-css-prefix}-php:before { content: fa-content($fa-var-php); } +.#{$fa-css-prefix}-pied-piper:before { content: fa-content($fa-var-pied-piper); } +.#{$fa-css-prefix}-pied-piper-alt:before { content: fa-content($fa-var-pied-piper-alt); } +.#{$fa-css-prefix}-pied-piper-hat:before { content: fa-content($fa-var-pied-piper-hat); } +.#{$fa-css-prefix}-pied-piper-pp:before { content: fa-content($fa-var-pied-piper-pp); } +.#{$fa-css-prefix}-pied-piper-square:before { content: fa-content($fa-var-pied-piper-square); } +.#{$fa-css-prefix}-piggy-bank:before { content: fa-content($fa-var-piggy-bank); } +.#{$fa-css-prefix}-pills:before { content: fa-content($fa-var-pills); } +.#{$fa-css-prefix}-pinterest:before { content: fa-content($fa-var-pinterest); } +.#{$fa-css-prefix}-pinterest-p:before { content: fa-content($fa-var-pinterest-p); } +.#{$fa-css-prefix}-pinterest-square:before { content: fa-content($fa-var-pinterest-square); } +.#{$fa-css-prefix}-pizza-slice:before { content: fa-content($fa-var-pizza-slice); } +.#{$fa-css-prefix}-place-of-worship:before { content: fa-content($fa-var-place-of-worship); } +.#{$fa-css-prefix}-plane:before { content: fa-content($fa-var-plane); } +.#{$fa-css-prefix}-plane-arrival:before { content: fa-content($fa-var-plane-arrival); } +.#{$fa-css-prefix}-plane-departure:before { content: fa-content($fa-var-plane-departure); } +.#{$fa-css-prefix}-plane-slash:before { content: fa-content($fa-var-plane-slash); } +.#{$fa-css-prefix}-play:before { content: fa-content($fa-var-play); } +.#{$fa-css-prefix}-play-circle:before { content: fa-content($fa-var-play-circle); } +.#{$fa-css-prefix}-playstation:before { content: fa-content($fa-var-playstation); } +.#{$fa-css-prefix}-plug:before { content: fa-content($fa-var-plug); } +.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); } +.#{$fa-css-prefix}-plus-circle:before { content: fa-content($fa-var-plus-circle); } +.#{$fa-css-prefix}-plus-square:before { content: fa-content($fa-var-plus-square); } +.#{$fa-css-prefix}-podcast:before { content: fa-content($fa-var-podcast); } +.#{$fa-css-prefix}-poll:before { content: fa-content($fa-var-poll); } +.#{$fa-css-prefix}-poll-h:before { content: fa-content($fa-var-poll-h); } +.#{$fa-css-prefix}-poo:before { content: fa-content($fa-var-poo); } +.#{$fa-css-prefix}-poo-storm:before { content: fa-content($fa-var-poo-storm); } +.#{$fa-css-prefix}-poop:before { content: fa-content($fa-var-poop); } +.#{$fa-css-prefix}-portrait:before { content: fa-content($fa-var-portrait); } +.#{$fa-css-prefix}-pound-sign:before { content: fa-content($fa-var-pound-sign); } +.#{$fa-css-prefix}-power-off:before { content: fa-content($fa-var-power-off); } +.#{$fa-css-prefix}-pray:before { content: fa-content($fa-var-pray); } +.#{$fa-css-prefix}-praying-hands:before { content: fa-content($fa-var-praying-hands); } +.#{$fa-css-prefix}-prescription:before { content: fa-content($fa-var-prescription); } +.#{$fa-css-prefix}-prescription-bottle:before { content: fa-content($fa-var-prescription-bottle); } +.#{$fa-css-prefix}-prescription-bottle-alt:before { content: fa-content($fa-var-prescription-bottle-alt); } +.#{$fa-css-prefix}-print:before { content: fa-content($fa-var-print); } +.#{$fa-css-prefix}-procedures:before { content: fa-content($fa-var-procedures); } +.#{$fa-css-prefix}-product-hunt:before { content: fa-content($fa-var-product-hunt); } +.#{$fa-css-prefix}-project-diagram:before { content: fa-content($fa-var-project-diagram); } +.#{$fa-css-prefix}-pump-medical:before { content: fa-content($fa-var-pump-medical); } +.#{$fa-css-prefix}-pump-soap:before { content: fa-content($fa-var-pump-soap); } +.#{$fa-css-prefix}-pushed:before { content: fa-content($fa-var-pushed); } +.#{$fa-css-prefix}-puzzle-piece:before { content: fa-content($fa-var-puzzle-piece); } +.#{$fa-css-prefix}-python:before { content: fa-content($fa-var-python); } +.#{$fa-css-prefix}-qq:before { content: fa-content($fa-var-qq); } +.#{$fa-css-prefix}-qrcode:before { content: fa-content($fa-var-qrcode); } +.#{$fa-css-prefix}-question:before { content: fa-content($fa-var-question); } +.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); } +.#{$fa-css-prefix}-quidditch:before { content: fa-content($fa-var-quidditch); } +.#{$fa-css-prefix}-quinscape:before { content: fa-content($fa-var-quinscape); } +.#{$fa-css-prefix}-quora:before { content: fa-content($fa-var-quora); } +.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); } +.#{$fa-css-prefix}-quote-right:before { content: fa-content($fa-var-quote-right); } +.#{$fa-css-prefix}-quran:before { content: fa-content($fa-var-quran); } +.#{$fa-css-prefix}-r-project:before { content: fa-content($fa-var-r-project); } +.#{$fa-css-prefix}-radiation:before { content: fa-content($fa-var-radiation); } +.#{$fa-css-prefix}-radiation-alt:before { content: fa-content($fa-var-radiation-alt); } +.#{$fa-css-prefix}-rainbow:before { content: fa-content($fa-var-rainbow); } +.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); } +.#{$fa-css-prefix}-raspberry-pi:before { content: fa-content($fa-var-raspberry-pi); } +.#{$fa-css-prefix}-ravelry:before { content: fa-content($fa-var-ravelry); } +.#{$fa-css-prefix}-react:before { content: fa-content($fa-var-react); } +.#{$fa-css-prefix}-reacteurope:before { content: fa-content($fa-var-reacteurope); } +.#{$fa-css-prefix}-readme:before { content: fa-content($fa-var-readme); } +.#{$fa-css-prefix}-rebel:before { content: fa-content($fa-var-rebel); } +.#{$fa-css-prefix}-receipt:before { content: fa-content($fa-var-receipt); } +.#{$fa-css-prefix}-record-vinyl:before { content: fa-content($fa-var-record-vinyl); } +.#{$fa-css-prefix}-recycle:before { content: fa-content($fa-var-recycle); } +.#{$fa-css-prefix}-red-river:before { content: fa-content($fa-var-red-river); } +.#{$fa-css-prefix}-reddit:before { content: fa-content($fa-var-reddit); } +.#{$fa-css-prefix}-reddit-alien:before { content: fa-content($fa-var-reddit-alien); } +.#{$fa-css-prefix}-reddit-square:before { content: fa-content($fa-var-reddit-square); } +.#{$fa-css-prefix}-redhat:before { content: fa-content($fa-var-redhat); } +.#{$fa-css-prefix}-redo:before { content: fa-content($fa-var-redo); } +.#{$fa-css-prefix}-redo-alt:before { content: fa-content($fa-var-redo-alt); } +.#{$fa-css-prefix}-registered:before { content: fa-content($fa-var-registered); } +.#{$fa-css-prefix}-remove-format:before { content: fa-content($fa-var-remove-format); } +.#{$fa-css-prefix}-renren:before { content: fa-content($fa-var-renren); } +.#{$fa-css-prefix}-reply:before { content: fa-content($fa-var-reply); } +.#{$fa-css-prefix}-reply-all:before { content: fa-content($fa-var-reply-all); } +.#{$fa-css-prefix}-replyd:before { content: fa-content($fa-var-replyd); } +.#{$fa-css-prefix}-republican:before { content: fa-content($fa-var-republican); } +.#{$fa-css-prefix}-researchgate:before { content: fa-content($fa-var-researchgate); } +.#{$fa-css-prefix}-resolving:before { content: fa-content($fa-var-resolving); } +.#{$fa-css-prefix}-restroom:before { content: fa-content($fa-var-restroom); } +.#{$fa-css-prefix}-retweet:before { content: fa-content($fa-var-retweet); } +.#{$fa-css-prefix}-rev:before { content: fa-content($fa-var-rev); } +.#{$fa-css-prefix}-ribbon:before { content: fa-content($fa-var-ribbon); } +.#{$fa-css-prefix}-ring:before { content: fa-content($fa-var-ring); } +.#{$fa-css-prefix}-road:before { content: fa-content($fa-var-road); } +.#{$fa-css-prefix}-robot:before { content: fa-content($fa-var-robot); } +.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); } +.#{$fa-css-prefix}-rocketchat:before { content: fa-content($fa-var-rocketchat); } +.#{$fa-css-prefix}-rockrms:before { content: fa-content($fa-var-rockrms); } +.#{$fa-css-prefix}-route:before { content: fa-content($fa-var-route); } +.#{$fa-css-prefix}-rss:before { content: fa-content($fa-var-rss); } +.#{$fa-css-prefix}-rss-square:before { content: fa-content($fa-var-rss-square); } +.#{$fa-css-prefix}-ruble-sign:before { content: fa-content($fa-var-ruble-sign); } +.#{$fa-css-prefix}-ruler:before { content: fa-content($fa-var-ruler); } +.#{$fa-css-prefix}-ruler-combined:before { content: fa-content($fa-var-ruler-combined); } +.#{$fa-css-prefix}-ruler-horizontal:before { content: fa-content($fa-var-ruler-horizontal); } +.#{$fa-css-prefix}-ruler-vertical:before { content: fa-content($fa-var-ruler-vertical); } +.#{$fa-css-prefix}-running:before { content: fa-content($fa-var-running); } +.#{$fa-css-prefix}-rupee-sign:before { content: fa-content($fa-var-rupee-sign); } +.#{$fa-css-prefix}-rust:before { content: fa-content($fa-var-rust); } +.#{$fa-css-prefix}-sad-cry:before { content: fa-content($fa-var-sad-cry); } +.#{$fa-css-prefix}-sad-tear:before { content: fa-content($fa-var-sad-tear); } +.#{$fa-css-prefix}-safari:before { content: fa-content($fa-var-safari); } +.#{$fa-css-prefix}-salesforce:before { content: fa-content($fa-var-salesforce); } +.#{$fa-css-prefix}-sass:before { content: fa-content($fa-var-sass); } +.#{$fa-css-prefix}-satellite:before { content: fa-content($fa-var-satellite); } +.#{$fa-css-prefix}-satellite-dish:before { content: fa-content($fa-var-satellite-dish); } +.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); } +.#{$fa-css-prefix}-schlix:before { content: fa-content($fa-var-schlix); } +.#{$fa-css-prefix}-school:before { content: fa-content($fa-var-school); } +.#{$fa-css-prefix}-screwdriver:before { content: fa-content($fa-var-screwdriver); } +.#{$fa-css-prefix}-scribd:before { content: fa-content($fa-var-scribd); } +.#{$fa-css-prefix}-scroll:before { content: fa-content($fa-var-scroll); } +.#{$fa-css-prefix}-sd-card:before { content: fa-content($fa-var-sd-card); } +.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); } +.#{$fa-css-prefix}-search-dollar:before { content: fa-content($fa-var-search-dollar); } +.#{$fa-css-prefix}-search-location:before { content: fa-content($fa-var-search-location); } +.#{$fa-css-prefix}-search-minus:before { content: fa-content($fa-var-search-minus); } +.#{$fa-css-prefix}-search-plus:before { content: fa-content($fa-var-search-plus); } +.#{$fa-css-prefix}-searchengin:before { content: fa-content($fa-var-searchengin); } +.#{$fa-css-prefix}-seedling:before { content: fa-content($fa-var-seedling); } +.#{$fa-css-prefix}-sellcast:before { content: fa-content($fa-var-sellcast); } +.#{$fa-css-prefix}-sellsy:before { content: fa-content($fa-var-sellsy); } +.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); } +.#{$fa-css-prefix}-servicestack:before { content: fa-content($fa-var-servicestack); } +.#{$fa-css-prefix}-shapes:before { content: fa-content($fa-var-shapes); } +.#{$fa-css-prefix}-share:before { content: fa-content($fa-var-share); } +.#{$fa-css-prefix}-share-alt:before { content: fa-content($fa-var-share-alt); } +.#{$fa-css-prefix}-share-alt-square:before { content: fa-content($fa-var-share-alt-square); } +.#{$fa-css-prefix}-share-square:before { content: fa-content($fa-var-share-square); } +.#{$fa-css-prefix}-shekel-sign:before { content: fa-content($fa-var-shekel-sign); } +.#{$fa-css-prefix}-shield-alt:before { content: fa-content($fa-var-shield-alt); } +.#{$fa-css-prefix}-shield-virus:before { content: fa-content($fa-var-shield-virus); } +.#{$fa-css-prefix}-ship:before { content: fa-content($fa-var-ship); } +.#{$fa-css-prefix}-shipping-fast:before { content: fa-content($fa-var-shipping-fast); } +.#{$fa-css-prefix}-shirtsinbulk:before { content: fa-content($fa-var-shirtsinbulk); } +.#{$fa-css-prefix}-shoe-prints:before { content: fa-content($fa-var-shoe-prints); } +.#{$fa-css-prefix}-shopify:before { content: fa-content($fa-var-shopify); } +.#{$fa-css-prefix}-shopping-bag:before { content: fa-content($fa-var-shopping-bag); } +.#{$fa-css-prefix}-shopping-basket:before { content: fa-content($fa-var-shopping-basket); } +.#{$fa-css-prefix}-shopping-cart:before { content: fa-content($fa-var-shopping-cart); } +.#{$fa-css-prefix}-shopware:before { content: fa-content($fa-var-shopware); } +.#{$fa-css-prefix}-shower:before { content: fa-content($fa-var-shower); } +.#{$fa-css-prefix}-shuttle-van:before { content: fa-content($fa-var-shuttle-van); } +.#{$fa-css-prefix}-sign:before { content: fa-content($fa-var-sign); } +.#{$fa-css-prefix}-sign-in-alt:before { content: fa-content($fa-var-sign-in-alt); } +.#{$fa-css-prefix}-sign-language:before { content: fa-content($fa-var-sign-language); } +.#{$fa-css-prefix}-sign-out-alt:before { content: fa-content($fa-var-sign-out-alt); } +.#{$fa-css-prefix}-signal:before { content: fa-content($fa-var-signal); } +.#{$fa-css-prefix}-signature:before { content: fa-content($fa-var-signature); } +.#{$fa-css-prefix}-sim-card:before { content: fa-content($fa-var-sim-card); } +.#{$fa-css-prefix}-simplybuilt:before { content: fa-content($fa-var-simplybuilt); } +.#{$fa-css-prefix}-sink:before { content: fa-content($fa-var-sink); } +.#{$fa-css-prefix}-sistrix:before { content: fa-content($fa-var-sistrix); } +.#{$fa-css-prefix}-sitemap:before { content: fa-content($fa-var-sitemap); } +.#{$fa-css-prefix}-sith:before { content: fa-content($fa-var-sith); } +.#{$fa-css-prefix}-skating:before { content: fa-content($fa-var-skating); } +.#{$fa-css-prefix}-sketch:before { content: fa-content($fa-var-sketch); } +.#{$fa-css-prefix}-skiing:before { content: fa-content($fa-var-skiing); } +.#{$fa-css-prefix}-skiing-nordic:before { content: fa-content($fa-var-skiing-nordic); } +.#{$fa-css-prefix}-skull:before { content: fa-content($fa-var-skull); } +.#{$fa-css-prefix}-skull-crossbones:before { content: fa-content($fa-var-skull-crossbones); } +.#{$fa-css-prefix}-skyatlas:before { content: fa-content($fa-var-skyatlas); } +.#{$fa-css-prefix}-skype:before { content: fa-content($fa-var-skype); } +.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); } +.#{$fa-css-prefix}-slack-hash:before { content: fa-content($fa-var-slack-hash); } +.#{$fa-css-prefix}-slash:before { content: fa-content($fa-var-slash); } +.#{$fa-css-prefix}-sleigh:before { content: fa-content($fa-var-sleigh); } +.#{$fa-css-prefix}-sliders-h:before { content: fa-content($fa-var-sliders-h); } +.#{$fa-css-prefix}-slideshare:before { content: fa-content($fa-var-slideshare); } +.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); } +.#{$fa-css-prefix}-smile-beam:before { content: fa-content($fa-var-smile-beam); } +.#{$fa-css-prefix}-smile-wink:before { content: fa-content($fa-var-smile-wink); } +.#{$fa-css-prefix}-smog:before { content: fa-content($fa-var-smog); } +.#{$fa-css-prefix}-smoking:before { content: fa-content($fa-var-smoking); } +.#{$fa-css-prefix}-smoking-ban:before { content: fa-content($fa-var-smoking-ban); } +.#{$fa-css-prefix}-sms:before { content: fa-content($fa-var-sms); } +.#{$fa-css-prefix}-snapchat:before { content: fa-content($fa-var-snapchat); } +.#{$fa-css-prefix}-snapchat-ghost:before { content: fa-content($fa-var-snapchat-ghost); } +.#{$fa-css-prefix}-snapchat-square:before { content: fa-content($fa-var-snapchat-square); } +.#{$fa-css-prefix}-snowboarding:before { content: fa-content($fa-var-snowboarding); } +.#{$fa-css-prefix}-snowflake:before { content: fa-content($fa-var-snowflake); } +.#{$fa-css-prefix}-snowman:before { content: fa-content($fa-var-snowman); } +.#{$fa-css-prefix}-snowplow:before { content: fa-content($fa-var-snowplow); } +.#{$fa-css-prefix}-soap:before { content: fa-content($fa-var-soap); } +.#{$fa-css-prefix}-socks:before { content: fa-content($fa-var-socks); } +.#{$fa-css-prefix}-solar-panel:before { content: fa-content($fa-var-solar-panel); } +.#{$fa-css-prefix}-sort:before { content: fa-content($fa-var-sort); } +.#{$fa-css-prefix}-sort-alpha-down:before { content: fa-content($fa-var-sort-alpha-down); } +.#{$fa-css-prefix}-sort-alpha-down-alt:before { content: fa-content($fa-var-sort-alpha-down-alt); } +.#{$fa-css-prefix}-sort-alpha-up:before { content: fa-content($fa-var-sort-alpha-up); } +.#{$fa-css-prefix}-sort-alpha-up-alt:before { content: fa-content($fa-var-sort-alpha-up-alt); } +.#{$fa-css-prefix}-sort-amount-down:before { content: fa-content($fa-var-sort-amount-down); } +.#{$fa-css-prefix}-sort-amount-down-alt:before { content: fa-content($fa-var-sort-amount-down-alt); } +.#{$fa-css-prefix}-sort-amount-up:before { content: fa-content($fa-var-sort-amount-up); } +.#{$fa-css-prefix}-sort-amount-up-alt:before { content: fa-content($fa-var-sort-amount-up-alt); } +.#{$fa-css-prefix}-sort-down:before { content: fa-content($fa-var-sort-down); } +.#{$fa-css-prefix}-sort-numeric-down:before { content: fa-content($fa-var-sort-numeric-down); } +.#{$fa-css-prefix}-sort-numeric-down-alt:before { content: fa-content($fa-var-sort-numeric-down-alt); } +.#{$fa-css-prefix}-sort-numeric-up:before { content: fa-content($fa-var-sort-numeric-up); } +.#{$fa-css-prefix}-sort-numeric-up-alt:before { content: fa-content($fa-var-sort-numeric-up-alt); } +.#{$fa-css-prefix}-sort-up:before { content: fa-content($fa-var-sort-up); } +.#{$fa-css-prefix}-soundcloud:before { content: fa-content($fa-var-soundcloud); } +.#{$fa-css-prefix}-sourcetree:before { content: fa-content($fa-var-sourcetree); } +.#{$fa-css-prefix}-spa:before { content: fa-content($fa-var-spa); } +.#{$fa-css-prefix}-space-shuttle:before { content: fa-content($fa-var-space-shuttle); } +.#{$fa-css-prefix}-speakap:before { content: fa-content($fa-var-speakap); } +.#{$fa-css-prefix}-speaker-deck:before { content: fa-content($fa-var-speaker-deck); } +.#{$fa-css-prefix}-spell-check:before { content: fa-content($fa-var-spell-check); } +.#{$fa-css-prefix}-spider:before { content: fa-content($fa-var-spider); } +.#{$fa-css-prefix}-spinner:before { content: fa-content($fa-var-spinner); } +.#{$fa-css-prefix}-splotch:before { content: fa-content($fa-var-splotch); } +.#{$fa-css-prefix}-spotify:before { content: fa-content($fa-var-spotify); } +.#{$fa-css-prefix}-spray-can:before { content: fa-content($fa-var-spray-can); } +.#{$fa-css-prefix}-square:before { content: fa-content($fa-var-square); } +.#{$fa-css-prefix}-square-full:before { content: fa-content($fa-var-square-full); } +.#{$fa-css-prefix}-square-root-alt:before { content: fa-content($fa-var-square-root-alt); } +.#{$fa-css-prefix}-squarespace:before { content: fa-content($fa-var-squarespace); } +.#{$fa-css-prefix}-stack-exchange:before { content: fa-content($fa-var-stack-exchange); } +.#{$fa-css-prefix}-stack-overflow:before { content: fa-content($fa-var-stack-overflow); } +.#{$fa-css-prefix}-stackpath:before { content: fa-content($fa-var-stackpath); } +.#{$fa-css-prefix}-stamp:before { content: fa-content($fa-var-stamp); } +.#{$fa-css-prefix}-star:before { content: fa-content($fa-var-star); } +.#{$fa-css-prefix}-star-and-crescent:before { content: fa-content($fa-var-star-and-crescent); } +.#{$fa-css-prefix}-star-half:before { content: fa-content($fa-var-star-half); } +.#{$fa-css-prefix}-star-half-alt:before { content: fa-content($fa-var-star-half-alt); } +.#{$fa-css-prefix}-star-of-david:before { content: fa-content($fa-var-star-of-david); } +.#{$fa-css-prefix}-star-of-life:before { content: fa-content($fa-var-star-of-life); } +.#{$fa-css-prefix}-staylinked:before { content: fa-content($fa-var-staylinked); } +.#{$fa-css-prefix}-steam:before { content: fa-content($fa-var-steam); } +.#{$fa-css-prefix}-steam-square:before { content: fa-content($fa-var-steam-square); } +.#{$fa-css-prefix}-steam-symbol:before { content: fa-content($fa-var-steam-symbol); } +.#{$fa-css-prefix}-step-backward:before { content: fa-content($fa-var-step-backward); } +.#{$fa-css-prefix}-step-forward:before { content: fa-content($fa-var-step-forward); } +.#{$fa-css-prefix}-stethoscope:before { content: fa-content($fa-var-stethoscope); } +.#{$fa-css-prefix}-sticker-mule:before { content: fa-content($fa-var-sticker-mule); } +.#{$fa-css-prefix}-sticky-note:before { content: fa-content($fa-var-sticky-note); } +.#{$fa-css-prefix}-stop:before { content: fa-content($fa-var-stop); } +.#{$fa-css-prefix}-stop-circle:before { content: fa-content($fa-var-stop-circle); } +.#{$fa-css-prefix}-stopwatch:before { content: fa-content($fa-var-stopwatch); } +.#{$fa-css-prefix}-stopwatch-20:before { content: fa-content($fa-var-stopwatch-20); } +.#{$fa-css-prefix}-store:before { content: fa-content($fa-var-store); } +.#{$fa-css-prefix}-store-alt:before { content: fa-content($fa-var-store-alt); } +.#{$fa-css-prefix}-store-alt-slash:before { content: fa-content($fa-var-store-alt-slash); } +.#{$fa-css-prefix}-store-slash:before { content: fa-content($fa-var-store-slash); } +.#{$fa-css-prefix}-strava:before { content: fa-content($fa-var-strava); } +.#{$fa-css-prefix}-stream:before { content: fa-content($fa-var-stream); } +.#{$fa-css-prefix}-street-view:before { content: fa-content($fa-var-street-view); } +.#{$fa-css-prefix}-strikethrough:before { content: fa-content($fa-var-strikethrough); } +.#{$fa-css-prefix}-stripe:before { content: fa-content($fa-var-stripe); } +.#{$fa-css-prefix}-stripe-s:before { content: fa-content($fa-var-stripe-s); } +.#{$fa-css-prefix}-stroopwafel:before { content: fa-content($fa-var-stroopwafel); } +.#{$fa-css-prefix}-studiovinari:before { content: fa-content($fa-var-studiovinari); } +.#{$fa-css-prefix}-stumbleupon:before { content: fa-content($fa-var-stumbleupon); } +.#{$fa-css-prefix}-stumbleupon-circle:before { content: fa-content($fa-var-stumbleupon-circle); } +.#{$fa-css-prefix}-subscript:before { content: fa-content($fa-var-subscript); } +.#{$fa-css-prefix}-subway:before { content: fa-content($fa-var-subway); } +.#{$fa-css-prefix}-suitcase:before { content: fa-content($fa-var-suitcase); } +.#{$fa-css-prefix}-suitcase-rolling:before { content: fa-content($fa-var-suitcase-rolling); } +.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); } +.#{$fa-css-prefix}-superpowers:before { content: fa-content($fa-var-superpowers); } +.#{$fa-css-prefix}-superscript:before { content: fa-content($fa-var-superscript); } +.#{$fa-css-prefix}-supple:before { content: fa-content($fa-var-supple); } +.#{$fa-css-prefix}-surprise:before { content: fa-content($fa-var-surprise); } +.#{$fa-css-prefix}-suse:before { content: fa-content($fa-var-suse); } +.#{$fa-css-prefix}-swatchbook:before { content: fa-content($fa-var-swatchbook); } +.#{$fa-css-prefix}-swift:before { content: fa-content($fa-var-swift); } +.#{$fa-css-prefix}-swimmer:before { content: fa-content($fa-var-swimmer); } +.#{$fa-css-prefix}-swimming-pool:before { content: fa-content($fa-var-swimming-pool); } +.#{$fa-css-prefix}-symfony:before { content: fa-content($fa-var-symfony); } +.#{$fa-css-prefix}-synagogue:before { content: fa-content($fa-var-synagogue); } +.#{$fa-css-prefix}-sync:before { content: fa-content($fa-var-sync); } +.#{$fa-css-prefix}-sync-alt:before { content: fa-content($fa-var-sync-alt); } +.#{$fa-css-prefix}-syringe:before { content: fa-content($fa-var-syringe); } +.#{$fa-css-prefix}-table:before { content: fa-content($fa-var-table); } +.#{$fa-css-prefix}-table-tennis:before { content: fa-content($fa-var-table-tennis); } +.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet); } +.#{$fa-css-prefix}-tablet-alt:before { content: fa-content($fa-var-tablet-alt); } +.#{$fa-css-prefix}-tablets:before { content: fa-content($fa-var-tablets); } +.#{$fa-css-prefix}-tachometer-alt:before { content: fa-content($fa-var-tachometer-alt); } +.#{$fa-css-prefix}-tag:before { content: fa-content($fa-var-tag); } +.#{$fa-css-prefix}-tags:before { content: fa-content($fa-var-tags); } +.#{$fa-css-prefix}-tape:before { content: fa-content($fa-var-tape); } +.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); } +.#{$fa-css-prefix}-taxi:before { content: fa-content($fa-var-taxi); } +.#{$fa-css-prefix}-teamspeak:before { content: fa-content($fa-var-teamspeak); } +.#{$fa-css-prefix}-teeth:before { content: fa-content($fa-var-teeth); } +.#{$fa-css-prefix}-teeth-open:before { content: fa-content($fa-var-teeth-open); } +.#{$fa-css-prefix}-telegram:before { content: fa-content($fa-var-telegram); } +.#{$fa-css-prefix}-telegram-plane:before { content: fa-content($fa-var-telegram-plane); } +.#{$fa-css-prefix}-temperature-high:before { content: fa-content($fa-var-temperature-high); } +.#{$fa-css-prefix}-temperature-low:before { content: fa-content($fa-var-temperature-low); } +.#{$fa-css-prefix}-tencent-weibo:before { content: fa-content($fa-var-tencent-weibo); } +.#{$fa-css-prefix}-tenge:before { content: fa-content($fa-var-tenge); } +.#{$fa-css-prefix}-terminal:before { content: fa-content($fa-var-terminal); } +.#{$fa-css-prefix}-text-height:before { content: fa-content($fa-var-text-height); } +.#{$fa-css-prefix}-text-width:before { content: fa-content($fa-var-text-width); } +.#{$fa-css-prefix}-th:before { content: fa-content($fa-var-th); } +.#{$fa-css-prefix}-th-large:before { content: fa-content($fa-var-th-large); } +.#{$fa-css-prefix}-th-list:before { content: fa-content($fa-var-th-list); } +.#{$fa-css-prefix}-the-red-yeti:before { content: fa-content($fa-var-the-red-yeti); } +.#{$fa-css-prefix}-theater-masks:before { content: fa-content($fa-var-theater-masks); } +.#{$fa-css-prefix}-themeco:before { content: fa-content($fa-var-themeco); } +.#{$fa-css-prefix}-themeisle:before { content: fa-content($fa-var-themeisle); } +.#{$fa-css-prefix}-thermometer:before { content: fa-content($fa-var-thermometer); } +.#{$fa-css-prefix}-thermometer-empty:before { content: fa-content($fa-var-thermometer-empty); } +.#{$fa-css-prefix}-thermometer-full:before { content: fa-content($fa-var-thermometer-full); } +.#{$fa-css-prefix}-thermometer-half:before { content: fa-content($fa-var-thermometer-half); } +.#{$fa-css-prefix}-thermometer-quarter:before { content: fa-content($fa-var-thermometer-quarter); } +.#{$fa-css-prefix}-thermometer-three-quarters:before { content: fa-content($fa-var-thermometer-three-quarters); } +.#{$fa-css-prefix}-think-peaks:before { content: fa-content($fa-var-think-peaks); } +.#{$fa-css-prefix}-thumbs-down:before { content: fa-content($fa-var-thumbs-down); } +.#{$fa-css-prefix}-thumbs-up:before { content: fa-content($fa-var-thumbs-up); } +.#{$fa-css-prefix}-thumbtack:before { content: fa-content($fa-var-thumbtack); } +.#{$fa-css-prefix}-ticket-alt:before { content: fa-content($fa-var-ticket-alt); } +.#{$fa-css-prefix}-tiktok:before { content: fa-content($fa-var-tiktok); } +.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); } +.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); } +.#{$fa-css-prefix}-tint:before { content: fa-content($fa-var-tint); } +.#{$fa-css-prefix}-tint-slash:before { content: fa-content($fa-var-tint-slash); } +.#{$fa-css-prefix}-tired:before { content: fa-content($fa-var-tired); } +.#{$fa-css-prefix}-toggle-off:before { content: fa-content($fa-var-toggle-off); } +.#{$fa-css-prefix}-toggle-on:before { content: fa-content($fa-var-toggle-on); } +.#{$fa-css-prefix}-toilet:before { content: fa-content($fa-var-toilet); } +.#{$fa-css-prefix}-toilet-paper:before { content: fa-content($fa-var-toilet-paper); } +.#{$fa-css-prefix}-toilet-paper-slash:before { content: fa-content($fa-var-toilet-paper-slash); } +.#{$fa-css-prefix}-toolbox:before { content: fa-content($fa-var-toolbox); } +.#{$fa-css-prefix}-tools:before { content: fa-content($fa-var-tools); } +.#{$fa-css-prefix}-tooth:before { content: fa-content($fa-var-tooth); } +.#{$fa-css-prefix}-torah:before { content: fa-content($fa-var-torah); } +.#{$fa-css-prefix}-torii-gate:before { content: fa-content($fa-var-torii-gate); } +.#{$fa-css-prefix}-tractor:before { content: fa-content($fa-var-tractor); } +.#{$fa-css-prefix}-trade-federation:before { content: fa-content($fa-var-trade-federation); } +.#{$fa-css-prefix}-trademark:before { content: fa-content($fa-var-trademark); } +.#{$fa-css-prefix}-traffic-light:before { content: fa-content($fa-var-traffic-light); } +.#{$fa-css-prefix}-trailer:before { content: fa-content($fa-var-trailer); } +.#{$fa-css-prefix}-train:before { content: fa-content($fa-var-train); } +.#{$fa-css-prefix}-tram:before { content: fa-content($fa-var-tram); } +.#{$fa-css-prefix}-transgender:before { content: fa-content($fa-var-transgender); } +.#{$fa-css-prefix}-transgender-alt:before { content: fa-content($fa-var-transgender-alt); } +.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash); } +.#{$fa-css-prefix}-trash-alt:before { content: fa-content($fa-var-trash-alt); } +.#{$fa-css-prefix}-trash-restore:before { content: fa-content($fa-var-trash-restore); } +.#{$fa-css-prefix}-trash-restore-alt:before { content: fa-content($fa-var-trash-restore-alt); } +.#{$fa-css-prefix}-tree:before { content: fa-content($fa-var-tree); } +.#{$fa-css-prefix}-trello:before { content: fa-content($fa-var-trello); } +.#{$fa-css-prefix}-tripadvisor:before { content: fa-content($fa-var-tripadvisor); } +.#{$fa-css-prefix}-trophy:before { content: fa-content($fa-var-trophy); } +.#{$fa-css-prefix}-truck:before { content: fa-content($fa-var-truck); } +.#{$fa-css-prefix}-truck-loading:before { content: fa-content($fa-var-truck-loading); } +.#{$fa-css-prefix}-truck-monster:before { content: fa-content($fa-var-truck-monster); } +.#{$fa-css-prefix}-truck-moving:before { content: fa-content($fa-var-truck-moving); } +.#{$fa-css-prefix}-truck-pickup:before { content: fa-content($fa-var-truck-pickup); } +.#{$fa-css-prefix}-tshirt:before { content: fa-content($fa-var-tshirt); } +.#{$fa-css-prefix}-tty:before { content: fa-content($fa-var-tty); } +.#{$fa-css-prefix}-tumblr:before { content: fa-content($fa-var-tumblr); } +.#{$fa-css-prefix}-tumblr-square:before { content: fa-content($fa-var-tumblr-square); } +.#{$fa-css-prefix}-tv:before { content: fa-content($fa-var-tv); } +.#{$fa-css-prefix}-twitch:before { content: fa-content($fa-var-twitch); } +.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); } +.#{$fa-css-prefix}-twitter-square:before { content: fa-content($fa-var-twitter-square); } +.#{$fa-css-prefix}-typo3:before { content: fa-content($fa-var-typo3); } +.#{$fa-css-prefix}-uber:before { content: fa-content($fa-var-uber); } +.#{$fa-css-prefix}-ubuntu:before { content: fa-content($fa-var-ubuntu); } +.#{$fa-css-prefix}-uikit:before { content: fa-content($fa-var-uikit); } +.#{$fa-css-prefix}-umbraco:before { content: fa-content($fa-var-umbraco); } +.#{$fa-css-prefix}-umbrella:before { content: fa-content($fa-var-umbrella); } +.#{$fa-css-prefix}-umbrella-beach:before { content: fa-content($fa-var-umbrella-beach); } +.#{$fa-css-prefix}-underline:before { content: fa-content($fa-var-underline); } +.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); } +.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); } +.#{$fa-css-prefix}-uniregistry:before { content: fa-content($fa-var-uniregistry); } +.#{$fa-css-prefix}-unity:before { content: fa-content($fa-var-unity); } +.#{$fa-css-prefix}-universal-access:before { content: fa-content($fa-var-universal-access); } +.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); } +.#{$fa-css-prefix}-unlink:before { content: fa-content($fa-var-unlink); } +.#{$fa-css-prefix}-unlock:before { content: fa-content($fa-var-unlock); } +.#{$fa-css-prefix}-unlock-alt:before { content: fa-content($fa-var-unlock-alt); } +.#{$fa-css-prefix}-unsplash:before { content: fa-content($fa-var-unsplash); } +.#{$fa-css-prefix}-untappd:before { content: fa-content($fa-var-untappd); } +.#{$fa-css-prefix}-upload:before { content: fa-content($fa-var-upload); } +.#{$fa-css-prefix}-ups:before { content: fa-content($fa-var-ups); } +.#{$fa-css-prefix}-usb:before { content: fa-content($fa-var-usb); } +.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); } +.#{$fa-css-prefix}-user-alt:before { content: fa-content($fa-var-user-alt); } +.#{$fa-css-prefix}-user-alt-slash:before { content: fa-content($fa-var-user-alt-slash); } +.#{$fa-css-prefix}-user-astronaut:before { content: fa-content($fa-var-user-astronaut); } +.#{$fa-css-prefix}-user-check:before { content: fa-content($fa-var-user-check); } +.#{$fa-css-prefix}-user-circle:before { content: fa-content($fa-var-user-circle); } +.#{$fa-css-prefix}-user-clock:before { content: fa-content($fa-var-user-clock); } +.#{$fa-css-prefix}-user-cog:before { content: fa-content($fa-var-user-cog); } +.#{$fa-css-prefix}-user-edit:before { content: fa-content($fa-var-user-edit); } +.#{$fa-css-prefix}-user-friends:before { content: fa-content($fa-var-user-friends); } +.#{$fa-css-prefix}-user-graduate:before { content: fa-content($fa-var-user-graduate); } +.#{$fa-css-prefix}-user-injured:before { content: fa-content($fa-var-user-injured); } +.#{$fa-css-prefix}-user-lock:before { content: fa-content($fa-var-user-lock); } +.#{$fa-css-prefix}-user-md:before { content: fa-content($fa-var-user-md); } +.#{$fa-css-prefix}-user-minus:before { content: fa-content($fa-var-user-minus); } +.#{$fa-css-prefix}-user-ninja:before { content: fa-content($fa-var-user-ninja); } +.#{$fa-css-prefix}-user-nurse:before { content: fa-content($fa-var-user-nurse); } +.#{$fa-css-prefix}-user-plus:before { content: fa-content($fa-var-user-plus); } +.#{$fa-css-prefix}-user-secret:before { content: fa-content($fa-var-user-secret); } +.#{$fa-css-prefix}-user-shield:before { content: fa-content($fa-var-user-shield); } +.#{$fa-css-prefix}-user-slash:before { content: fa-content($fa-var-user-slash); } +.#{$fa-css-prefix}-user-tag:before { content: fa-content($fa-var-user-tag); } +.#{$fa-css-prefix}-user-tie:before { content: fa-content($fa-var-user-tie); } +.#{$fa-css-prefix}-user-times:before { content: fa-content($fa-var-user-times); } +.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); } +.#{$fa-css-prefix}-users-cog:before { content: fa-content($fa-var-users-cog); } +.#{$fa-css-prefix}-users-slash:before { content: fa-content($fa-var-users-slash); } +.#{$fa-css-prefix}-usps:before { content: fa-content($fa-var-usps); } +.#{$fa-css-prefix}-ussunnah:before { content: fa-content($fa-var-ussunnah); } +.#{$fa-css-prefix}-utensil-spoon:before { content: fa-content($fa-var-utensil-spoon); } +.#{$fa-css-prefix}-utensils:before { content: fa-content($fa-var-utensils); } +.#{$fa-css-prefix}-vaadin:before { content: fa-content($fa-var-vaadin); } +.#{$fa-css-prefix}-vector-square:before { content: fa-content($fa-var-vector-square); } +.#{$fa-css-prefix}-venus:before { content: fa-content($fa-var-venus); } +.#{$fa-css-prefix}-venus-double:before { content: fa-content($fa-var-venus-double); } +.#{$fa-css-prefix}-venus-mars:before { content: fa-content($fa-var-venus-mars); } +.#{$fa-css-prefix}-viacoin:before { content: fa-content($fa-var-viacoin); } +.#{$fa-css-prefix}-viadeo:before { content: fa-content($fa-var-viadeo); } +.#{$fa-css-prefix}-viadeo-square:before { content: fa-content($fa-var-viadeo-square); } +.#{$fa-css-prefix}-vial:before { content: fa-content($fa-var-vial); } +.#{$fa-css-prefix}-vials:before { content: fa-content($fa-var-vials); } +.#{$fa-css-prefix}-viber:before { content: fa-content($fa-var-viber); } +.#{$fa-css-prefix}-video:before { content: fa-content($fa-var-video); } +.#{$fa-css-prefix}-video-slash:before { content: fa-content($fa-var-video-slash); } +.#{$fa-css-prefix}-vihara:before { content: fa-content($fa-var-vihara); } +.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo); } +.#{$fa-css-prefix}-vimeo-square:before { content: fa-content($fa-var-vimeo-square); } +.#{$fa-css-prefix}-vimeo-v:before { content: fa-content($fa-var-vimeo-v); } +.#{$fa-css-prefix}-vine:before { content: fa-content($fa-var-vine); } +.#{$fa-css-prefix}-virus:before { content: fa-content($fa-var-virus); } +.#{$fa-css-prefix}-virus-slash:before { content: fa-content($fa-var-virus-slash); } +.#{$fa-css-prefix}-viruses:before { content: fa-content($fa-var-viruses); } +.#{$fa-css-prefix}-vk:before { content: fa-content($fa-var-vk); } +.#{$fa-css-prefix}-vnv:before { content: fa-content($fa-var-vnv); } +.#{$fa-css-prefix}-voicemail:before { content: fa-content($fa-var-voicemail); } +.#{$fa-css-prefix}-volleyball-ball:before { content: fa-content($fa-var-volleyball-ball); } +.#{$fa-css-prefix}-volume-down:before { content: fa-content($fa-var-volume-down); } +.#{$fa-css-prefix}-volume-mute:before { content: fa-content($fa-var-volume-mute); } +.#{$fa-css-prefix}-volume-off:before { content: fa-content($fa-var-volume-off); } +.#{$fa-css-prefix}-volume-up:before { content: fa-content($fa-var-volume-up); } +.#{$fa-css-prefix}-vote-yea:before { content: fa-content($fa-var-vote-yea); } +.#{$fa-css-prefix}-vr-cardboard:before { content: fa-content($fa-var-vr-cardboard); } +.#{$fa-css-prefix}-vuejs:before { content: fa-content($fa-var-vuejs); } +.#{$fa-css-prefix}-walking:before { content: fa-content($fa-var-walking); } +.#{$fa-css-prefix}-wallet:before { content: fa-content($fa-var-wallet); } +.#{$fa-css-prefix}-warehouse:before { content: fa-content($fa-var-warehouse); } +.#{$fa-css-prefix}-water:before { content: fa-content($fa-var-water); } +.#{$fa-css-prefix}-wave-square:before { content: fa-content($fa-var-wave-square); } +.#{$fa-css-prefix}-waze:before { content: fa-content($fa-var-waze); } +.#{$fa-css-prefix}-weebly:before { content: fa-content($fa-var-weebly); } +.#{$fa-css-prefix}-weibo:before { content: fa-content($fa-var-weibo); } +.#{$fa-css-prefix}-weight:before { content: fa-content($fa-var-weight); } +.#{$fa-css-prefix}-weight-hanging:before { content: fa-content($fa-var-weight-hanging); } +.#{$fa-css-prefix}-weixin:before { content: fa-content($fa-var-weixin); } +.#{$fa-css-prefix}-whatsapp:before { content: fa-content($fa-var-whatsapp); } +.#{$fa-css-prefix}-whatsapp-square:before { content: fa-content($fa-var-whatsapp-square); } +.#{$fa-css-prefix}-wheelchair:before { content: fa-content($fa-var-wheelchair); } +.#{$fa-css-prefix}-whmcs:before { content: fa-content($fa-var-whmcs); } +.#{$fa-css-prefix}-wifi:before { content: fa-content($fa-var-wifi); } +.#{$fa-css-prefix}-wikipedia-w:before { content: fa-content($fa-var-wikipedia-w); } +.#{$fa-css-prefix}-wind:before { content: fa-content($fa-var-wind); } +.#{$fa-css-prefix}-window-close:before { content: fa-content($fa-var-window-close); } +.#{$fa-css-prefix}-window-maximize:before { content: fa-content($fa-var-window-maximize); } +.#{$fa-css-prefix}-window-minimize:before { content: fa-content($fa-var-window-minimize); } +.#{$fa-css-prefix}-window-restore:before { content: fa-content($fa-var-window-restore); } +.#{$fa-css-prefix}-windows:before { content: fa-content($fa-var-windows); } +.#{$fa-css-prefix}-wine-bottle:before { content: fa-content($fa-var-wine-bottle); } +.#{$fa-css-prefix}-wine-glass:before { content: fa-content($fa-var-wine-glass); } +.#{$fa-css-prefix}-wine-glass-alt:before { content: fa-content($fa-var-wine-glass-alt); } +.#{$fa-css-prefix}-wix:before { content: fa-content($fa-var-wix); } +.#{$fa-css-prefix}-wizards-of-the-coast:before { content: fa-content($fa-var-wizards-of-the-coast); } +.#{$fa-css-prefix}-wolf-pack-battalion:before { content: fa-content($fa-var-wolf-pack-battalion); } +.#{$fa-css-prefix}-won-sign:before { content: fa-content($fa-var-won-sign); } +.#{$fa-css-prefix}-wordpress:before { content: fa-content($fa-var-wordpress); } +.#{$fa-css-prefix}-wordpress-simple:before { content: fa-content($fa-var-wordpress-simple); } +.#{$fa-css-prefix}-wpbeginner:before { content: fa-content($fa-var-wpbeginner); } +.#{$fa-css-prefix}-wpexplorer:before { content: fa-content($fa-var-wpexplorer); } +.#{$fa-css-prefix}-wpforms:before { content: fa-content($fa-var-wpforms); } +.#{$fa-css-prefix}-wpressr:before { content: fa-content($fa-var-wpressr); } +.#{$fa-css-prefix}-wrench:before { content: fa-content($fa-var-wrench); } +.#{$fa-css-prefix}-x-ray:before { content: fa-content($fa-var-x-ray); } +.#{$fa-css-prefix}-xbox:before { content: fa-content($fa-var-xbox); } +.#{$fa-css-prefix}-xing:before { content: fa-content($fa-var-xing); } +.#{$fa-css-prefix}-xing-square:before { content: fa-content($fa-var-xing-square); } +.#{$fa-css-prefix}-y-combinator:before { content: fa-content($fa-var-y-combinator); } +.#{$fa-css-prefix}-yahoo:before { content: fa-content($fa-var-yahoo); } +.#{$fa-css-prefix}-yammer:before { content: fa-content($fa-var-yammer); } +.#{$fa-css-prefix}-yandex:before { content: fa-content($fa-var-yandex); } +.#{$fa-css-prefix}-yandex-international:before { content: fa-content($fa-var-yandex-international); } +.#{$fa-css-prefix}-yarn:before { content: fa-content($fa-var-yarn); } +.#{$fa-css-prefix}-yelp:before { content: fa-content($fa-var-yelp); } +.#{$fa-css-prefix}-yen-sign:before { content: fa-content($fa-var-yen-sign); } +.#{$fa-css-prefix}-yin-yang:before { content: fa-content($fa-var-yin-yang); } +.#{$fa-css-prefix}-yoast:before { content: fa-content($fa-var-yoast); } +.#{$fa-css-prefix}-youtube:before { content: fa-content($fa-var-youtube); } +.#{$fa-css-prefix}-youtube-square:before { content: fa-content($fa-var-youtube-square); } +.#{$fa-css-prefix}-zhihu:before { content: fa-content($fa-var-zhihu); } diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss new file mode 100644 index 0000000..58a3f67 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_larger.scss @@ -0,0 +1,23 @@ +// Icon Sizes +// ------------------------- +@use 'sass:math'; +// makes the font 33% larger relative to the icon container +.#{$fa-css-prefix}-lg { + font-size: (math.div(4em, 3)); + line-height: (math.div(3em, 4)); + vertical-align: -0.0667em; +} + +.#{$fa-css-prefix}-xs { + font-size: 0.75em; +} + +.#{$fa-css-prefix}-sm { + font-size: 0.875em; +} + +@for $i from 1 through 10 { + .#{$fa-css-prefix}-#{$i}x { + font-size: $i * 1em; + } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss new file mode 100644 index 0000000..a44483e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_list.scss @@ -0,0 +1,21 @@ +// List Icons +// ------------------------- +@use 'sass:math'; + +.#{$fa-css-prefix}-ul { + list-style-type: none; + margin-left: math.div($fa-li-width * 5, 4); + padding-left: 0; + + > li { + position: relative; + } +} + +.#{$fa-css-prefix}-li { + left: -$fa-li-width; + position: absolute; + text-align: center; + width: $fa-li-width; + line-height: inherit; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss new file mode 100644 index 0000000..55baeeb --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_mixins.scss @@ -0,0 +1,56 @@ +// Mixins +// -------------------------- + +@mixin fa-icon { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; +} + +@mixin fa-icon-rotate($degrees, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; + transform: rotate($degrees); +} + +@mixin fa-icon-flip($horiz, $vert, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; + transform: scale($horiz, $vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +@mixin sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +@mixin sr-only-focusable { + &:active, + &:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; + } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss new file mode 100644 index 0000000..164d972 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_rotated-flipped.scss @@ -0,0 +1,24 @@ +// Rotated & Flipped Icons +// ------------------------- + +.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } +.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } +.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } + +.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } +.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } +.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root { + .#{$fa-css-prefix}-rotate-90, + .#{$fa-css-prefix}-rotate-180, + .#{$fa-css-prefix}-rotate-270, + .#{$fa-css-prefix}-flip-horizontal, + .#{$fa-css-prefix}-flip-vertical, + .#{$fa-css-prefix}-flip-both { + filter: none; + } +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss new file mode 100644 index 0000000..5d0ab26 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_screen-reader.scss @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { @include sr-only; } +.sr-only-focusable { @include sr-only-focusable; } diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss new file mode 100644 index 0000000..d175344 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_shims.scss @@ -0,0 +1,2066 @@ +.#{$fa-css-prefix}.#{$fa-css-prefix}-glass:before { content: fa-content($fa-var-glass-martini); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-meetup { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o:before { content: fa-content($fa-var-star); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-remove:before { content: fa-content($fa-var-times); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-close:before { content: fa-content($fa-var-times); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gear:before { content: fa-content($fa-var-cog); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o:before { content: fa-content($fa-var-trash-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o:before { content: fa-content($fa-var-file); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o:before { content: fa-content($fa-var-clock); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o:before { content: fa-content($fa-var-play-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-repeat:before { content: fa-content($fa-var-redo); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-right:before { content: fa-content($fa-var-redo); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-refresh:before { content: fa-content($fa-var-sync); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-list-alt { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dedent:before { content: fa-content($fa-var-outdent); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-video-camera:before { content: fa-content($fa-var-video); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o:before { content: fa-content($fa-var-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-photo { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-photo:before { content: fa-content($fa-var-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-image { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil:before { content: fa-content($fa-var-pencil-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o:before { content: fa-content($fa-var-edit); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-share-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-share-square-o:before { content: fa-content($fa-var-share-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o:before { content: fa-content($fa-var-check-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows:before { content: fa-content($fa-var-arrows-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o:before { content: fa-content($fa-var-times-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o:before { content: fa-content($fa-var-check-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-forward:before { content: fa-content($fa-var-share); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-eye { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-eye-slash { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-warning:before { content: fa-content($fa-var-exclamation-triangle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-v:before { content: fa-content($fa-var-arrows-alt-v); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-h:before { content: fa-content($fa-var-arrows-alt-h); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart:before { content: fa-content($fa-var-chart-bar); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart-o:before { content: fa-content($fa-var-chart-bar); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gears:before { content: fa-content($fa-var-cogs); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up:before { content: fa-content($fa-var-thumbs-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down:before { content: fa-content($fa-var-thumbs-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o:before { content: fa-content($fa-var-heart); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-out:before { content: fa-content($fa-var-sign-out-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square:before { content: fa-content($fa-var-linkedin); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumb-tack:before { content: fa-content($fa-var-thumbtack); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link:before { content: fa-content($fa-var-external-link-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-in:before { content: fa-content($fa-var-sign-in-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-github-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o:before { content: fa-content($fa-var-lemon); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o:before { content: fa-content($fa-var-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o:before { content: fa-content($fa-var-bookmark); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook-f); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-github { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-feed:before { content: fa-content($fa-var-rss); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o:before { content: fa-content($fa-var-hdd); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right:before { content: fa-content($fa-var-hand-point-right); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left:before { content: fa-content($fa-var-hand-point-left); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up:before { content: fa-content($fa-var-hand-point-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down:before { content: fa-content($fa-var-hand-point-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-group:before { content: fa-content($fa-var-users); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-chain:before { content: fa-content($fa-var-link); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-scissors:before { content: fa-content($fa-var-cut); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o:before { content: fa-content($fa-var-copy); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o:before { content: fa-content($fa-var-save); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-navicon:before { content: fa-content($fa-var-bars); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-reorder:before { content: fa-content($fa-var-bars); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus-g); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-money { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-money:before { content: fa-content($fa-var-money-bill-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-unsorted:before { content: fa-content($fa-var-sort); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-desc:before { content: fa-content($fa-var-sort-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-asc:before { content: fa-content($fa-var-sort-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin-in); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-left:before { content: fa-content($fa-var-undo); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-legal:before { content: fa-content($fa-var-gavel); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tachometer:before { content: fa-content($fa-var-tachometer-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dashboard:before { content: fa-content($fa-var-tachometer-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o:before { content: fa-content($fa-var-comment); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o:before { content: fa-content($fa-var-comments); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-flash:before { content: fa-content($fa-var-bolt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-clipboard { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-paste { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-clipboard); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o:before { content: fa-content($fa-var-lightbulb); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-exchange:before { content: fa-content($fa-var-exchange-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-download:before { content: fa-content($fa-var-cloud-download-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-upload:before { content: fa-content($fa-var-cloud-upload-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o:before { content: fa-content($fa-var-bell); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cutlery:before { content: fa-content($fa-var-utensils); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o:before { content: fa-content($fa-var-file-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o:before { content: fa-content($fa-var-building); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o:before { content: fa-content($fa-var-hospital); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile-phone:before { content: fa-content($fa-var-mobile-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o:before { content: fa-content($fa-var-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply:before { content: fa-content($fa-var-reply); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-github-alt { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o:before { content: fa-content($fa-var-folder); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o:before { content: fa-content($fa-var-folder-open); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o:before { content: fa-content($fa-var-smile); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o:before { content: fa-content($fa-var-frown); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o:before { content: fa-content($fa-var-meh); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o:before { content: fa-content($fa-var-keyboard); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o:before { content: fa-content($fa-var-flag); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply-all:before { content: fa-content($fa-var-reply-all); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o:before { content: fa-content($fa-var-star-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty:before { content: fa-content($fa-var-star-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full:before { content: fa-content($fa-var-star-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-code-fork:before { content: fa-content($fa-var-code-branch); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-chain-broken:before { content: fa-content($fa-var-unlink); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-shield:before { content: fa-content($fa-var-shield-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o:before { content: fa-content($fa-var-calendar); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-maxcdn { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-html5 { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-css3 { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ticket:before { content: fa-content($fa-var-ticket-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o:before { content: fa-content($fa-var-minus-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-level-up:before { content: fa-content($fa-var-level-up-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-level-down:before { content: fa-content($fa-var-level-down-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square:before { content: fa-content($fa-var-pen-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link-square:before { content: fa-content($fa-var-external-link-square-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-compass { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down:before { content: fa-content($fa-var-caret-square-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down:before { content: fa-content($fa-var-caret-square-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up:before { content: fa-content($fa-var-caret-square-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up:before { content: fa-content($fa-var-caret-square-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right:before { content: fa-content($fa-var-caret-square-right); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right:before { content: fa-content($fa-var-caret-square-right); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-eur:before { content: fa-content($fa-var-euro-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-euro:before { content: fa-content($fa-var-euro-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gbp:before { content: fa-content($fa-var-pound-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-usd:before { content: fa-content($fa-var-dollar-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dollar:before { content: fa-content($fa-var-dollar-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-inr:before { content: fa-content($fa-var-rupee-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rupee:before { content: fa-content($fa-var-rupee-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-jpy:before { content: fa-content($fa-var-yen-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cny:before { content: fa-content($fa-var-yen-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rmb:before { content: fa-content($fa-var-yen-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yen:before { content: fa-content($fa-var-yen-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rub:before { content: fa-content($fa-var-ruble-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ruble:before { content: fa-content($fa-var-ruble-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rouble:before { content: fa-content($fa-var-ruble-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-krw:before { content: fa-content($fa-var-won-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-won:before { content: fa-content($fa-var-won-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-btc { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-btc); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text:before { content: fa-content($fa-var-file-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-asc:before { content: fa-content($fa-var-sort-alpha-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-desc:before { content: fa-content($fa-var-sort-alpha-down-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-asc:before { content: fa-content($fa-var-sort-amount-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-desc:before { content: fa-content($fa-var-sort-amount-down-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-asc:before { content: fa-content($fa-var-sort-numeric-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-desc:before { content: fa-content($fa-var-sort-numeric-down-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-xing { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-xing-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play:before { content: fa-content($fa-var-youtube); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dropbox { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-overflow { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-instagram { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-flickr { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-adn { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square:before { content: fa-content($fa-var-bitbucket); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-down:before { content: fa-content($fa-var-long-arrow-alt-down); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-up:before { content: fa-content($fa-var-long-arrow-alt-up); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-left:before { content: fa-content($fa-var-long-arrow-alt-left); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-right:before { content: fa-content($fa-var-long-arrow-alt-right); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-apple { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-windows { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-android { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-linux { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dribbble { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-skype { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-foursquare { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-trello { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gratipay { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip:before { content: fa-content($fa-var-gratipay); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o:before { content: fa-content($fa-var-sun); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o:before { content: fa-content($fa-var-moon); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vk { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-weibo { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-renren { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pagelines { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-exchange { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left:before { content: fa-content($fa-var-caret-square-left); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left:before { content: fa-content($fa-var-caret-square-left); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o:before { content: fa-content($fa-var-dot-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-try:before { content: fa-content($fa-var-lira-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-turkish-lira:before { content: fa-content($fa-var-lira-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o:before { content: fa-content($fa-var-plus-square); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-slack { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wordpress { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-openid { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-institution:before { content: fa-content($fa-var-university); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bank:before { content: fa-content($fa-var-university); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mortar-board:before { content: fa-content($fa-var-graduation-cap); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yahoo { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon-circle { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-delicious { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-digg { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-pp { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-alt { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-drupal { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-joomla { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-spoon:before { content: fa-content($fa-var-utensil-spoon); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-behance { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-behance-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-steam { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-steam-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-automobile:before { content: fa-content($fa-var-car); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o:before { content: fa-content($fa-var-envelope); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-spotify { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-deviantart { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-soundcloud { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o:before { content: fa-content($fa-var-file-pdf); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o:before { content: fa-content($fa-var-file-word); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o:before { content: fa-content($fa-var-file-excel); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o:before { content: fa-content($fa-var-file-powerpoint); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o:before { content: fa-content($fa-var-file-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o:before { content: fa-content($fa-var-file-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o:before { content: fa-content($fa-var-file-image); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o:before { content: fa-content($fa-var-file-archive); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o:before { content: fa-content($fa-var-file-archive); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o:before { content: fa-content($fa-var-file-audio); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o:before { content: fa-content($fa-var-file-audio); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o:before { content: fa-content($fa-var-file-video); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o:before { content: fa-content($fa-var-file-video); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o:before { content: fa-content($fa-var-file-code); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vine { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-codepen { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-jsfiddle { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-ring { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-bouy { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-bouy:before { content: fa-content($fa-var-life-ring); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-buoy { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-buoy:before { content: fa-content($fa-var-life-ring); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-saver { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-saver:before { content: fa-content($fa-var-life-ring); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-support { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-support:before { content: fa-content($fa-var-life-ring); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o-notch:before { content: fa-content($fa-var-circle-notch); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-rebel { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ra { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ra:before { content: fa-content($fa-var-rebel); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance:before { content: fa-content($fa-var-rebel); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-empire { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ge { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ge:before { content: fa-content($fa-var-empire); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-git-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-git { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hacker-news { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square:before { content: fa-content($fa-var-hacker-news); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square:before { content: fa-content($fa-var-hacker-news); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tencent-weibo { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-qq { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-weixin { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat:before { content: fa-content($fa-var-weixin); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-send:before { content: fa-content($fa-var-paper-plane); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o:before { content: fa-content($fa-var-paper-plane); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o:before { content: fa-content($fa-var-paper-plane); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin:before { content: fa-content($fa-var-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-header:before { content: fa-content($fa-var-heading); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sliders:before { content: fa-content($fa-var-sliders-h); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o:before { content: fa-content($fa-var-futbol); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o:before { content: fa-content($fa-var-futbol); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-slideshare { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitch { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yelp { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o:before { content: fa-content($fa-var-newspaper); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-paypal { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-wallet { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-visa { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-mastercard { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-discover { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-amex { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-paypal { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-stripe { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o:before { content: fa-content($fa-var-bell-slash); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash-alt); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-copyright { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-eyedropper:before { content: fa-content($fa-var-eye-dropper); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-area-chart:before { content: fa-content($fa-var-chart-area); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pie-chart:before { content: fa-content($fa-var-chart-pie); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-line-chart:before { content: fa-content($fa-var-chart-line); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ioxhost { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-angellist { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc:before { content: fa-content($fa-var-closed-captioning); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ils:before { content: fa-content($fa-var-shekel-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-shekel:before { content: fa-content($fa-var-shekel-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sheqel:before { content: fa-content($fa-var-shekel-sign); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-meanpath { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-meanpath:before { content: fa-content($fa-var-font-awesome); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-buysellads { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-connectdevelop { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-dashcube { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-forumbee { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-leanpub { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sellsy { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-shirtsinbulk { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-simplybuilt { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-skyatlas { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond:before { content: fa-content($fa-var-gem); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-intersex:before { content: fa-content($fa-var-transgender); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official:before { content: fa-content($fa-var-facebook); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-p { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-whatsapp { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hotel:before { content: fa-content($fa-var-bed); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-viacoin { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-medium { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc:before { content: fa-content($fa-var-y-combinator); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-optin-monster { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-opencart { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-expeditedssl { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-4:before { content: fa-content($fa-var-battery-full); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery:before { content: fa-content($fa-var-battery-full); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-3:before { content: fa-content($fa-var-battery-three-quarters); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-2:before { content: fa-content($fa-var-battery-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-1:before { content: fa-content($fa-var-battery-quarter); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-0:before { content: fa-content($fa-var-battery-empty); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-object-group { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-object-ungroup { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o:before { content: fa-content($fa-var-sticky-note); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-jcb { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-diners-club { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-clone { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-o:before { content: fa-content($fa-var-hourglass); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-1:before { content: fa-content($fa-var-hourglass-start); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-2:before { content: fa-content($fa-var-hourglass-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-3:before { content: fa-content($fa-var-hourglass-end); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o:before { content: fa-content($fa-var-hand-rock); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o:before { content: fa-content($fa-var-hand-rock); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o:before { content: fa-content($fa-var-hand-paper); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o:before { content: fa-content($fa-var-hand-paper); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o:before { content: fa-content($fa-var-hand-scissors); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o:before { content: fa-content($fa-var-hand-lizard); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o:before { content: fa-content($fa-var-hand-spock); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o:before { content: fa-content($fa-var-hand-pointer); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o:before { content: fa-content($fa-var-hand-peace); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-registered { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-creative-commons { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gg { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gg-circle { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-tripadvisor { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-get-pocket { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wikipedia-w { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-safari { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-chrome { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-firefox { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-opera { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-internet-explorer { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-television:before { content: fa-content($fa-var-tv); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-contao { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-500px { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-amazon { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o:before { content: fa-content($fa-var-calendar-plus); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o:before { content: fa-content($fa-var-calendar-minus); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o:before { content: fa-content($fa-var-calendar-times); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o:before { content: fa-content($fa-var-calendar-check); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o:before { content: fa-content($fa-var-map); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting:before { content: fa-content($fa-var-comment-dots); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o:before { content: fa-content($fa-var-comment-dots); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-houzz { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo-v); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-black-tie { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-fonticons { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-alien { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-edge { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card-alt:before { content: fa-content($fa-var-credit-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-codiepie { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-modx { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-fort-awesome { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-usb { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-product-hunt { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-mixcloud { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-scribd { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o:before { content: fa-content($fa-var-pause-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o:before { content: fa-content($fa-var-stop-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth-b { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-gitlab { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpbeginner { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpforms { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-envira { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt:before { content: fa-content($fa-var-accessible-icon); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o:before { content: fa-content($fa-var-question-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-volume-control-phone:before { content: fa-content($fa-var-phone-volume); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-asl-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-deafness:before { content: fa-content($fa-var-deaf); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-hard-of-hearing:before { content: fa-content($fa-var-deaf); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-glide { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-glide-g { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-signing:before { content: fa-content($fa-var-sign-language); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-ghost { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-square { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-first-order { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-yoast { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-themeisle { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official:before { content: fa-content($fa-var-google-plus); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle:before { content: fa-content($fa-var-google-plus); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-font-awesome { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-fa { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-fa:before { content: fa-content($fa-var-font-awesome); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o:before { content: fa-content($fa-var-handshake); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o:before { content: fa-content($fa-var-envelope-open); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-linode { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o:before { content: fa-content($fa-var-address-book); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard:before { content: fa-content($fa-var-address-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o:before { content: fa-content($fa-var-address-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o:before { content: fa-content($fa-var-address-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o:before { content: fa-content($fa-var-user-circle); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o:before { content: fa-content($fa-var-user); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-badge { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license:before { content: fa-content($fa-var-id-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o:before { content: fa-content($fa-var-id-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o:before { content: fa-content($fa-var-id-card); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-quora { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-free-code-camp { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-telegram { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-4:before { content: fa-content($fa-var-thermometer-full); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer:before { content: fa-content($fa-var-thermometer-full); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-3:before { content: fa-content($fa-var-thermometer-three-quarters); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-2:before { content: fa-content($fa-var-thermometer-half); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-1:before { content: fa-content($fa-var-thermometer-quarter); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-0:before { content: fa-content($fa-var-thermometer-empty); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bathtub:before { content: fa-content($fa-var-bath); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-s15:before { content: fa-content($fa-var-bath); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-maximize { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-restore { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle:before { content: fa-content($fa-var-window-close); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o:before { content: fa-content($fa-var-window-close); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o:before { content: fa-content($fa-var-window-close); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-bandcamp { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-grav { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-etsy { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-imdb { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-ravelry { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast:before { content: fa-content($fa-var-sellcast); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o:before { content: fa-content($fa-var-snowflake); } + +.#{$fa-css-prefix}.#{$fa-css-prefix}-superpowers { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpexplorer { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} + +.#{$fa-css-prefix}.#{$fa-css-prefix}-cab:before { content: fa-content($fa-var-taxi); } + diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss new file mode 100644 index 0000000..ae7ef4e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_stacked.scss @@ -0,0 +1,31 @@ +// Stacked Icons +// ------------------------- + +.#{$fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: ($fa-fw-width*2); +} + +.#{$fa-css-prefix}-stack-1x, +.#{$fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; +} + +.#{$fa-css-prefix}-stack-1x { + line-height: inherit; +} + +.#{$fa-css-prefix}-stack-2x { + font-size: 2em; +} + +.#{$fa-css-prefix}-inverse { + color: $fa-inverse; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss new file mode 100644 index 0000000..fb203b9 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/_variables.scss @@ -0,0 +1,1469 @@ +// Variables +// -------------------------- +@use 'sass:math'; + +$fa-font-path: '../../../fonts/fontawesome' !default; +$fa-font-size-base: 16px !default; +$fa-font-display: block !default; +$fa-css-prefix: fa !default; +$fa-version: '5.13.1' !default; +$fa-border-color: #eee !default; +$fa-inverse: #fff !default; +$fa-li-width: 2em !default; +$fa-fw-width: (math.div(20em, 16)); +$fa-primary-opacity: 1 !default; +$fa-secondary-opacity: 0.4 !default; + +// Convenience function used to set content property +@function fa-content($fa-var) { + @return unquote('"#{ $fa-var }"'); +} + +$fa-var-500px: \f26e; +$fa-var-accessible-icon: \f368; +$fa-var-accusoft: \f369; +$fa-var-acquisitions-incorporated: \f6af; +$fa-var-ad: \f641; +$fa-var-address-book: \f2b9; +$fa-var-address-card: \f2bb; +$fa-var-adjust: \f042; +$fa-var-adn: \f170; +$fa-var-adobe: \f778; +$fa-var-adversal: \f36a; +$fa-var-affiliatetheme: \f36b; +$fa-var-air-freshener: \f5d0; +$fa-var-airbnb: \f834; +$fa-var-algolia: \f36c; +$fa-var-align-center: \f037; +$fa-var-align-justify: \f039; +$fa-var-align-left: \f036; +$fa-var-align-right: \f038; +$fa-var-alipay: \f642; +$fa-var-allergies: \f461; +$fa-var-amazon: \f270; +$fa-var-amazon-pay: \f42c; +$fa-var-ambulance: \f0f9; +$fa-var-american-sign-language-interpreting: \f2a3; +$fa-var-amilia: \f36d; +$fa-var-anchor: \f13d; +$fa-var-android: \f17b; +$fa-var-angellist: \f209; +$fa-var-angle-double-down: \f103; +$fa-var-angle-double-left: \f100; +$fa-var-angle-double-right: \f101; +$fa-var-angle-double-up: \f102; +$fa-var-angle-down: \f107; +$fa-var-angle-left: \f104; +$fa-var-angle-right: \f105; +$fa-var-angle-up: \f106; +$fa-var-angry: \f556; +$fa-var-angrycreative: \f36e; +$fa-var-angular: \f420; +$fa-var-ankh: \f644; +$fa-var-app-store: \f36f; +$fa-var-app-store-ios: \f370; +$fa-var-apper: \f371; +$fa-var-apple: \f179; +$fa-var-apple-alt: \f5d1; +$fa-var-apple-pay: \f415; +$fa-var-archive: \f187; +$fa-var-archway: \f557; +$fa-var-arrow-alt-circle-down: \f358; +$fa-var-arrow-alt-circle-left: \f359; +$fa-var-arrow-alt-circle-right: \f35a; +$fa-var-arrow-alt-circle-up: \f35b; +$fa-var-arrow-circle-down: \f0ab; +$fa-var-arrow-circle-left: \f0a8; +$fa-var-arrow-circle-right: \f0a9; +$fa-var-arrow-circle-up: \f0aa; +$fa-var-arrow-down: \f063; +$fa-var-arrow-left: \f060; +$fa-var-arrow-right: \f061; +$fa-var-arrow-up: \f062; +$fa-var-arrows-alt: \f0b2; +$fa-var-arrows-alt-h: \f337; +$fa-var-arrows-alt-v: \f338; +$fa-var-artstation: \f77a; +$fa-var-assistive-listening-systems: \f2a2; +$fa-var-asterisk: \f069; +$fa-var-asymmetrik: \f372; +$fa-var-at: \f1fa; +$fa-var-atlas: \f558; +$fa-var-atlassian: \f77b; +$fa-var-atom: \f5d2; +$fa-var-audible: \f373; +$fa-var-audio-description: \f29e; +$fa-var-autoprefixer: \f41c; +$fa-var-avianex: \f374; +$fa-var-aviato: \f421; +$fa-var-award: \f559; +$fa-var-aws: \f375; +$fa-var-baby: \f77c; +$fa-var-baby-carriage: \f77d; +$fa-var-backspace: \f55a; +$fa-var-backward: \f04a; +$fa-var-bacon: \f7e5; +$fa-var-bacteria: \f959; +$fa-var-bacterium: \f95a; +$fa-var-bahai: \f666; +$fa-var-balance-scale: \f24e; +$fa-var-balance-scale-left: \f515; +$fa-var-balance-scale-right: \f516; +$fa-var-ban: \f05e; +$fa-var-band-aid: \f462; +$fa-var-bandcamp: \f2d5; +$fa-var-barcode: \f02a; +$fa-var-bars: \f0c9; +$fa-var-baseball-ball: \f433; +$fa-var-basketball-ball: \f434; +$fa-var-bath: \f2cd; +$fa-var-battery-empty: \f244; +$fa-var-battery-full: \f240; +$fa-var-battery-half: \f242; +$fa-var-battery-quarter: \f243; +$fa-var-battery-three-quarters: \f241; +$fa-var-battle-net: \f835; +$fa-var-bed: \f236; +$fa-var-beer: \f0fc; +$fa-var-behance: \f1b4; +$fa-var-behance-square: \f1b5; +$fa-var-bell: \f0f3; +$fa-var-bell-slash: \f1f6; +$fa-var-bezier-curve: \f55b; +$fa-var-bible: \f647; +$fa-var-bicycle: \f206; +$fa-var-biking: \f84a; +$fa-var-bimobject: \f378; +$fa-var-binoculars: \f1e5; +$fa-var-biohazard: \f780; +$fa-var-birthday-cake: \f1fd; +$fa-var-bitbucket: \f171; +$fa-var-bitcoin: \f379; +$fa-var-bity: \f37a; +$fa-var-black-tie: \f27e; +$fa-var-blackberry: \f37b; +$fa-var-blender: \f517; +$fa-var-blender-phone: \f6b6; +$fa-var-blind: \f29d; +$fa-var-blog: \f781; +$fa-var-blogger: \f37c; +$fa-var-blogger-b: \f37d; +$fa-var-bluetooth: \f293; +$fa-var-bluetooth-b: \f294; +$fa-var-bold: \f032; +$fa-var-bolt: \f0e7; +$fa-var-bomb: \f1e2; +$fa-var-bone: \f5d7; +$fa-var-bong: \f55c; +$fa-var-book: \f02d; +$fa-var-book-dead: \f6b7; +$fa-var-book-medical: \f7e6; +$fa-var-book-open: \f518; +$fa-var-book-reader: \f5da; +$fa-var-bookmark: \f02e; +$fa-var-bootstrap: \f836; +$fa-var-border-all: \f84c; +$fa-var-border-none: \f850; +$fa-var-border-style: \f853; +$fa-var-bowling-ball: \f436; +$fa-var-box: \f466; +$fa-var-box-open: \f49e; +$fa-var-box-tissue: \f95b; +$fa-var-boxes: \f468; +$fa-var-braille: \f2a1; +$fa-var-brain: \f5dc; +$fa-var-bread-slice: \f7ec; +$fa-var-briefcase: \f0b1; +$fa-var-briefcase-medical: \f469; +$fa-var-broadcast-tower: \f519; +$fa-var-broom: \f51a; +$fa-var-brush: \f55d; +$fa-var-btc: \f15a; +$fa-var-buffer: \f837; +$fa-var-bug: \f188; +$fa-var-building: \f1ad; +$fa-var-bullhorn: \f0a1; +$fa-var-bullseye: \f140; +$fa-var-burn: \f46a; +$fa-var-buromobelexperte: \f37f; +$fa-var-bus: \f207; +$fa-var-bus-alt: \f55e; +$fa-var-business-time: \f64a; +$fa-var-buy-n-large: \f8a6; +$fa-var-buysellads: \f20d; +$fa-var-calculator: \f1ec; +$fa-var-calendar: \f133; +$fa-var-calendar-alt: \f073; +$fa-var-calendar-check: \f274; +$fa-var-calendar-day: \f783; +$fa-var-calendar-minus: \f272; +$fa-var-calendar-plus: \f271; +$fa-var-calendar-times: \f273; +$fa-var-calendar-week: \f784; +$fa-var-camera: \f030; +$fa-var-camera-retro: \f083; +$fa-var-campground: \f6bb; +$fa-var-canadian-maple-leaf: \f785; +$fa-var-candy-cane: \f786; +$fa-var-cannabis: \f55f; +$fa-var-capsules: \f46b; +$fa-var-car: \f1b9; +$fa-var-car-alt: \f5de; +$fa-var-car-battery: \f5df; +$fa-var-car-crash: \f5e1; +$fa-var-car-side: \f5e4; +$fa-var-caravan: \f8ff; +$fa-var-caret-down: \f0d7; +$fa-var-caret-left: \f0d9; +$fa-var-caret-right: \f0da; +$fa-var-caret-square-down: \f150; +$fa-var-caret-square-left: \f191; +$fa-var-caret-square-right: \f152; +$fa-var-caret-square-up: \f151; +$fa-var-caret-up: \f0d8; +$fa-var-carrot: \f787; +$fa-var-cart-arrow-down: \f218; +$fa-var-cart-plus: \f217; +$fa-var-cash-register: \f788; +$fa-var-cat: \f6be; +$fa-var-cc-amazon-pay: \f42d; +$fa-var-cc-amex: \f1f3; +$fa-var-cc-apple-pay: \f416; +$fa-var-cc-diners-club: \f24c; +$fa-var-cc-discover: \f1f2; +$fa-var-cc-jcb: \f24b; +$fa-var-cc-mastercard: \f1f1; +$fa-var-cc-paypal: \f1f4; +$fa-var-cc-stripe: \f1f5; +$fa-var-cc-visa: \f1f0; +$fa-var-centercode: \f380; +$fa-var-centos: \f789; +$fa-var-certificate: \f0a3; +$fa-var-chair: \f6c0; +$fa-var-chalkboard: \f51b; +$fa-var-chalkboard-teacher: \f51c; +$fa-var-charging-station: \f5e7; +$fa-var-chart-area: \f1fe; +$fa-var-chart-bar: \f080; +$fa-var-chart-line: \f201; +$fa-var-chart-pie: \f200; +$fa-var-check: \f00c; +$fa-var-check-circle: \f058; +$fa-var-check-double: \f560; +$fa-var-check-square: \f14a; +$fa-var-cheese: \f7ef; +$fa-var-chess: \f439; +$fa-var-chess-bishop: \f43a; +$fa-var-chess-board: \f43c; +$fa-var-chess-king: \f43f; +$fa-var-chess-knight: \f441; +$fa-var-chess-pawn: \f443; +$fa-var-chess-queen: \f445; +$fa-var-chess-rook: \f447; +$fa-var-chevron-circle-down: \f13a; +$fa-var-chevron-circle-left: \f137; +$fa-var-chevron-circle-right: \f138; +$fa-var-chevron-circle-up: \f139; +$fa-var-chevron-down: \f078; +$fa-var-chevron-left: \f053; +$fa-var-chevron-right: \f054; +$fa-var-chevron-up: \f077; +$fa-var-child: \f1ae; +$fa-var-chrome: \f268; +$fa-var-chromecast: \f838; +$fa-var-church: \f51d; +$fa-var-circle: \f111; +$fa-var-circle-notch: \f1ce; +$fa-var-city: \f64f; +$fa-var-clinic-medical: \f7f2; +$fa-var-clipboard: \f328; +$fa-var-clipboard-check: \f46c; +$fa-var-clipboard-list: \f46d; +$fa-var-clock: \f017; +$fa-var-clone: \f24d; +$fa-var-closed-captioning: \f20a; +$fa-var-cloud: \f0c2; +$fa-var-cloud-download-alt: \f381; +$fa-var-cloud-meatball: \f73b; +$fa-var-cloud-moon: \f6c3; +$fa-var-cloud-moon-rain: \f73c; +$fa-var-cloud-rain: \f73d; +$fa-var-cloud-showers-heavy: \f740; +$fa-var-cloud-sun: \f6c4; +$fa-var-cloud-sun-rain: \f743; +$fa-var-cloud-upload-alt: \f382; +$fa-var-cloudscale: \f383; +$fa-var-cloudsmith: \f384; +$fa-var-cloudversify: \f385; +$fa-var-cocktail: \f561; +$fa-var-code: \f121; +$fa-var-code-branch: \f126; +$fa-var-codepen: \f1cb; +$fa-var-codiepie: \f284; +$fa-var-coffee: \f0f4; +$fa-var-cog: \f013; +$fa-var-cogs: \f085; +$fa-var-coins: \f51e; +$fa-var-columns: \f0db; +$fa-var-comment: \f075; +$fa-var-comment-alt: \f27a; +$fa-var-comment-dollar: \f651; +$fa-var-comment-dots: \f4ad; +$fa-var-comment-medical: \f7f5; +$fa-var-comment-slash: \f4b3; +$fa-var-comments: \f086; +$fa-var-comments-dollar: \f653; +$fa-var-compact-disc: \f51f; +$fa-var-compass: \f14e; +$fa-var-compress: \f066; +$fa-var-compress-alt: \f422; +$fa-var-compress-arrows-alt: \f78c; +$fa-var-concierge-bell: \f562; +$fa-var-confluence: \f78d; +$fa-var-connectdevelop: \f20e; +$fa-var-contao: \f26d; +$fa-var-cookie: \f563; +$fa-var-cookie-bite: \f564; +$fa-var-copy: \f0c5; +$fa-var-copyright: \f1f9; +$fa-var-cotton-bureau: \f89e; +$fa-var-couch: \f4b8; +$fa-var-cpanel: \f388; +$fa-var-creative-commons: \f25e; +$fa-var-creative-commons-by: \f4e7; +$fa-var-creative-commons-nc: \f4e8; +$fa-var-creative-commons-nc-eu: \f4e9; +$fa-var-creative-commons-nc-jp: \f4ea; +$fa-var-creative-commons-nd: \f4eb; +$fa-var-creative-commons-pd: \f4ec; +$fa-var-creative-commons-pd-alt: \f4ed; +$fa-var-creative-commons-remix: \f4ee; +$fa-var-creative-commons-sa: \f4ef; +$fa-var-creative-commons-sampling: \f4f0; +$fa-var-creative-commons-sampling-plus: \f4f1; +$fa-var-creative-commons-share: \f4f2; +$fa-var-creative-commons-zero: \f4f3; +$fa-var-credit-card: \f09d; +$fa-var-critical-role: \f6c9; +$fa-var-crop: \f125; +$fa-var-crop-alt: \f565; +$fa-var-cross: \f654; +$fa-var-crosshairs: \f05b; +$fa-var-crow: \f520; +$fa-var-crown: \f521; +$fa-var-crutch: \f7f7; +$fa-var-css3: \f13c; +$fa-var-css3-alt: \f38b; +$fa-var-cube: \f1b2; +$fa-var-cubes: \f1b3; +$fa-var-cut: \f0c4; +$fa-var-cuttlefish: \f38c; +$fa-var-d-and-d: \f38d; +$fa-var-d-and-d-beyond: \f6ca; +$fa-var-dailymotion: \f952; +$fa-var-dashcube: \f210; +$fa-var-database: \f1c0; +$fa-var-deaf: \f2a4; +$fa-var-deezer: \f977; +$fa-var-delicious: \f1a5; +$fa-var-democrat: \f747; +$fa-var-deploydog: \f38e; +$fa-var-deskpro: \f38f; +$fa-var-desktop: \f108; +$fa-var-dev: \f6cc; +$fa-var-deviantart: \f1bd; +$fa-var-dharmachakra: \f655; +$fa-var-dhl: \f790; +$fa-var-diagnoses: \f470; +$fa-var-diaspora: \f791; +$fa-var-dice: \f522; +$fa-var-dice-d20: \f6cf; +$fa-var-dice-d6: \f6d1; +$fa-var-dice-five: \f523; +$fa-var-dice-four: \f524; +$fa-var-dice-one: \f525; +$fa-var-dice-six: \f526; +$fa-var-dice-three: \f527; +$fa-var-dice-two: \f528; +$fa-var-digg: \f1a6; +$fa-var-digital-ocean: \f391; +$fa-var-digital-tachograph: \f566; +$fa-var-directions: \f5eb; +$fa-var-discord: \f392; +$fa-var-discourse: \f393; +$fa-var-disease: \f7fa; +$fa-var-divide: \f529; +$fa-var-dizzy: \f567; +$fa-var-dna: \f471; +$fa-var-dochub: \f394; +$fa-var-docker: \f395; +$fa-var-dog: \f6d3; +$fa-var-dollar-sign: \f155; +$fa-var-dolly: \f472; +$fa-var-dolly-flatbed: \f474; +$fa-var-donate: \f4b9; +$fa-var-door-closed: \f52a; +$fa-var-door-open: \f52b; +$fa-var-dot-circle: \f192; +$fa-var-dove: \f4ba; +$fa-var-download: \f019; +$fa-var-draft2digital: \f396; +$fa-var-drafting-compass: \f568; +$fa-var-dragon: \f6d5; +$fa-var-draw-polygon: \f5ee; +$fa-var-dribbble: \f17d; +$fa-var-dribbble-square: \f397; +$fa-var-dropbox: \f16b; +$fa-var-drum: \f569; +$fa-var-drum-steelpan: \f56a; +$fa-var-drumstick-bite: \f6d7; +$fa-var-drupal: \f1a9; +$fa-var-dumbbell: \f44b; +$fa-var-dumpster: \f793; +$fa-var-dumpster-fire: \f794; +$fa-var-dungeon: \f6d9; +$fa-var-dyalog: \f399; +$fa-var-earlybirds: \f39a; +$fa-var-ebay: \f4f4; +$fa-var-edge: \f282; +$fa-var-edge-legacy: \f978; +$fa-var-edit: \f044; +$fa-var-egg: \f7fb; +$fa-var-eject: \f052; +$fa-var-elementor: \f430; +$fa-var-ellipsis-h: \f141; +$fa-var-ellipsis-v: \f142; +$fa-var-ello: \f5f1; +$fa-var-ember: \f423; +$fa-var-empire: \f1d1; +$fa-var-envelope: \f0e0; +$fa-var-envelope-open: \f2b6; +$fa-var-envelope-open-text: \f658; +$fa-var-envelope-square: \f199; +$fa-var-envira: \f299; +$fa-var-equals: \f52c; +$fa-var-eraser: \f12d; +$fa-var-erlang: \f39d; +$fa-var-ethereum: \f42e; +$fa-var-ethernet: \f796; +$fa-var-etsy: \f2d7; +$fa-var-euro-sign: \f153; +$fa-var-evernote: \f839; +$fa-var-exchange-alt: \f362; +$fa-var-exclamation: \f12a; +$fa-var-exclamation-circle: \f06a; +$fa-var-exclamation-triangle: \f071; +$fa-var-expand: \f065; +$fa-var-expand-alt: \f424; +$fa-var-expand-arrows-alt: \f31e; +$fa-var-expeditedssl: \f23e; +$fa-var-external-link-alt: \f35d; +$fa-var-external-link-square-alt: \f360; +$fa-var-eye: \f06e; +$fa-var-eye-dropper: \f1fb; +$fa-var-eye-slash: \f070; +$fa-var-facebook: \f09a; +$fa-var-facebook-f: \f39e; +$fa-var-facebook-messenger: \f39f; +$fa-var-facebook-square: \f082; +$fa-var-fan: \f863; +$fa-var-fantasy-flight-games: \f6dc; +$fa-var-fast-backward: \f049; +$fa-var-fast-forward: \f050; +$fa-var-faucet: \f905; +$fa-var-fax: \f1ac; +$fa-var-feather: \f52d; +$fa-var-feather-alt: \f56b; +$fa-var-fedex: \f797; +$fa-var-fedora: \f798; +$fa-var-female: \f182; +$fa-var-fighter-jet: \f0fb; +$fa-var-figma: \f799; +$fa-var-file: \f15b; +$fa-var-file-alt: \f15c; +$fa-var-file-archive: \f1c6; +$fa-var-file-audio: \f1c7; +$fa-var-file-code: \f1c9; +$fa-var-file-contract: \f56c; +$fa-var-file-csv: \f6dd; +$fa-var-file-download: \f56d; +$fa-var-file-excel: \f1c3; +$fa-var-file-export: \f56e; +$fa-var-file-image: \f1c5; +$fa-var-file-import: \f56f; +$fa-var-file-invoice: \f570; +$fa-var-file-invoice-dollar: \f571; +$fa-var-file-medical: \f477; +$fa-var-file-medical-alt: \f478; +$fa-var-file-pdf: \f1c1; +$fa-var-file-powerpoint: \f1c4; +$fa-var-file-prescription: \f572; +$fa-var-file-signature: \f573; +$fa-var-file-upload: \f574; +$fa-var-file-video: \f1c8; +$fa-var-file-word: \f1c2; +$fa-var-fill: \f575; +$fa-var-fill-drip: \f576; +$fa-var-film: \f008; +$fa-var-filter: \f0b0; +$fa-var-fingerprint: \f577; +$fa-var-fire: \f06d; +$fa-var-fire-alt: \f7e4; +$fa-var-fire-extinguisher: \f134; +$fa-var-firefox: \f269; +$fa-var-firefox-browser: \f907; +$fa-var-first-aid: \f479; +$fa-var-first-order: \f2b0; +$fa-var-first-order-alt: \f50a; +$fa-var-firstdraft: \f3a1; +$fa-var-fish: \f578; +$fa-var-fist-raised: \f6de; +$fa-var-flag: \f024; +$fa-var-flag-checkered: \f11e; +$fa-var-flag-usa: \f74d; +$fa-var-flask: \f0c3; +$fa-var-flickr: \f16e; +$fa-var-flipboard: \f44d; +$fa-var-flushed: \f579; +$fa-var-fly: \f417; +$fa-var-folder: \f07b; +$fa-var-folder-minus: \f65d; +$fa-var-folder-open: \f07c; +$fa-var-folder-plus: \f65e; +$fa-var-font: \f031; +$fa-var-font-awesome: \f2b4; +$fa-var-font-awesome-alt: \f35c; +$fa-var-font-awesome-flag: \f425; +$fa-var-font-awesome-logo-full: \f4e6; +$fa-var-fonticons: \f280; +$fa-var-fonticons-fi: \f3a2; +$fa-var-football-ball: \f44e; +$fa-var-fort-awesome: \f286; +$fa-var-fort-awesome-alt: \f3a3; +$fa-var-forumbee: \f211; +$fa-var-forward: \f04e; +$fa-var-foursquare: \f180; +$fa-var-free-code-camp: \f2c5; +$fa-var-freebsd: \f3a4; +$fa-var-frog: \f52e; +$fa-var-frown: \f119; +$fa-var-frown-open: \f57a; +$fa-var-fulcrum: \f50b; +$fa-var-funnel-dollar: \f662; +$fa-var-futbol: \f1e3; +$fa-var-galactic-republic: \f50c; +$fa-var-galactic-senate: \f50d; +$fa-var-gamepad: \f11b; +$fa-var-gas-pump: \f52f; +$fa-var-gavel: \f0e3; +$fa-var-gem: \f3a5; +$fa-var-genderless: \f22d; +$fa-var-get-pocket: \f265; +$fa-var-gg: \f260; +$fa-var-gg-circle: \f261; +$fa-var-ghost: \f6e2; +$fa-var-gift: \f06b; +$fa-var-gifts: \f79c; +$fa-var-git: \f1d3; +$fa-var-git-alt: \f841; +$fa-var-git-square: \f1d2; +$fa-var-github: \f09b; +$fa-var-github-alt: \f113; +$fa-var-github-square: \f092; +$fa-var-gitkraken: \f3a6; +$fa-var-gitlab: \f296; +$fa-var-gitter: \f426; +$fa-var-glass-cheers: \f79f; +$fa-var-glass-martini: \f000; +$fa-var-glass-martini-alt: \f57b; +$fa-var-glass-whiskey: \f7a0; +$fa-var-glasses: \f530; +$fa-var-glide: \f2a5; +$fa-var-glide-g: \f2a6; +$fa-var-globe: \f0ac; +$fa-var-globe-africa: \f57c; +$fa-var-globe-americas: \f57d; +$fa-var-globe-asia: \f57e; +$fa-var-globe-europe: \f7a2; +$fa-var-gofore: \f3a7; +$fa-var-golf-ball: \f450; +$fa-var-goodreads: \f3a8; +$fa-var-goodreads-g: \f3a9; +$fa-var-google: \f1a0; +$fa-var-google-drive: \f3aa; +$fa-var-google-pay: \f979; +$fa-var-google-play: \f3ab; +$fa-var-google-plus: \f2b3; +$fa-var-google-plus-g: \f0d5; +$fa-var-google-plus-square: \f0d4; +$fa-var-google-wallet: \f1ee; +$fa-var-gopuram: \f664; +$fa-var-graduation-cap: \f19d; +$fa-var-gratipay: \f184; +$fa-var-grav: \f2d6; +$fa-var-greater-than: \f531; +$fa-var-greater-than-equal: \f532; +$fa-var-grimace: \f57f; +$fa-var-grin: \f580; +$fa-var-grin-alt: \f581; +$fa-var-grin-beam: \f582; +$fa-var-grin-beam-sweat: \f583; +$fa-var-grin-hearts: \f584; +$fa-var-grin-squint: \f585; +$fa-var-grin-squint-tears: \f586; +$fa-var-grin-stars: \f587; +$fa-var-grin-tears: \f588; +$fa-var-grin-tongue: \f589; +$fa-var-grin-tongue-squint: \f58a; +$fa-var-grin-tongue-wink: \f58b; +$fa-var-grin-wink: \f58c; +$fa-var-grip-horizontal: \f58d; +$fa-var-grip-lines: \f7a4; +$fa-var-grip-lines-vertical: \f7a5; +$fa-var-grip-vertical: \f58e; +$fa-var-gripfire: \f3ac; +$fa-var-grunt: \f3ad; +$fa-var-guitar: \f7a6; +$fa-var-gulp: \f3ae; +$fa-var-h-square: \f0fd; +$fa-var-hacker-news: \f1d4; +$fa-var-hacker-news-square: \f3af; +$fa-var-hackerrank: \f5f7; +$fa-var-hamburger: \f805; +$fa-var-hammer: \f6e3; +$fa-var-hamsa: \f665; +$fa-var-hand-holding: \f4bd; +$fa-var-hand-holding-heart: \f4be; +$fa-var-hand-holding-medical: \f95c; +$fa-var-hand-holding-usd: \f4c0; +$fa-var-hand-holding-water: \f4c1; +$fa-var-hand-lizard: \f258; +$fa-var-hand-middle-finger: \f806; +$fa-var-hand-paper: \f256; +$fa-var-hand-peace: \f25b; +$fa-var-hand-point-down: \f0a7; +$fa-var-hand-point-left: \f0a5; +$fa-var-hand-point-right: \f0a4; +$fa-var-hand-point-up: \f0a6; +$fa-var-hand-pointer: \f25a; +$fa-var-hand-rock: \f255; +$fa-var-hand-scissors: \f257; +$fa-var-hand-sparkles: \f95d; +$fa-var-hand-spock: \f259; +$fa-var-hands: \f4c2; +$fa-var-hands-helping: \f4c4; +$fa-var-hands-wash: \f95e; +$fa-var-handshake: \f2b5; +$fa-var-handshake-alt-slash: \f95f; +$fa-var-handshake-slash: \f960; +$fa-var-hanukiah: \f6e6; +$fa-var-hard-hat: \f807; +$fa-var-hashtag: \f292; +$fa-var-hat-cowboy: \f8c0; +$fa-var-hat-cowboy-side: \f8c1; +$fa-var-hat-wizard: \f6e8; +$fa-var-hdd: \f0a0; +$fa-var-head-side-cough: \f961; +$fa-var-head-side-cough-slash: \f962; +$fa-var-head-side-mask: \f963; +$fa-var-head-side-virus: \f964; +$fa-var-heading: \f1dc; +$fa-var-headphones: \f025; +$fa-var-headphones-alt: \f58f; +$fa-var-headset: \f590; +$fa-var-heart: \f004; +$fa-var-heart-broken: \f7a9; +$fa-var-heartbeat: \f21e; +$fa-var-helicopter: \f533; +$fa-var-highlighter: \f591; +$fa-var-hiking: \f6ec; +$fa-var-hippo: \f6ed; +$fa-var-hips: \f452; +$fa-var-hire-a-helper: \f3b0; +$fa-var-history: \f1da; +$fa-var-hockey-puck: \f453; +$fa-var-holly-berry: \f7aa; +$fa-var-home: \f015; +$fa-var-hooli: \f427; +$fa-var-hornbill: \f592; +$fa-var-horse: \f6f0; +$fa-var-horse-head: \f7ab; +$fa-var-hospital: \f0f8; +$fa-var-hospital-alt: \f47d; +$fa-var-hospital-symbol: \f47e; +$fa-var-hospital-user: \f80d; +$fa-var-hot-tub: \f593; +$fa-var-hotdog: \f80f; +$fa-var-hotel: \f594; +$fa-var-hotjar: \f3b1; +$fa-var-hourglass: \f254; +$fa-var-hourglass-end: \f253; +$fa-var-hourglass-half: \f252; +$fa-var-hourglass-start: \f251; +$fa-var-house-damage: \f6f1; +$fa-var-house-user: \f965; +$fa-var-houzz: \f27c; +$fa-var-hryvnia: \f6f2; +$fa-var-html5: \f13b; +$fa-var-hubspot: \f3b2; +$fa-var-i-cursor: \f246; +$fa-var-ice-cream: \f810; +$fa-var-icicles: \f7ad; +$fa-var-icons: \f86d; +$fa-var-id-badge: \f2c1; +$fa-var-id-card: \f2c2; +$fa-var-id-card-alt: \f47f; +$fa-var-ideal: \f913; +$fa-var-igloo: \f7ae; +$fa-var-image: \f03e; +$fa-var-images: \f302; +$fa-var-imdb: \f2d8; +$fa-var-inbox: \f01c; +$fa-var-indent: \f03c; +$fa-var-industry: \f275; +$fa-var-infinity: \f534; +$fa-var-info: \f129; +$fa-var-info-circle: \f05a; +$fa-var-instagram: \f16d; +$fa-var-instagram-square: \f955; +$fa-var-intercom: \f7af; +$fa-var-internet-explorer: \f26b; +$fa-var-invision: \f7b0; +$fa-var-ioxhost: \f208; +$fa-var-italic: \f033; +$fa-var-itch-io: \f83a; +$fa-var-itunes: \f3b4; +$fa-var-itunes-note: \f3b5; +$fa-var-java: \f4e4; +$fa-var-jedi: \f669; +$fa-var-jedi-order: \f50e; +$fa-var-jenkins: \f3b6; +$fa-var-jira: \f7b1; +$fa-var-joget: \f3b7; +$fa-var-joint: \f595; +$fa-var-joomla: \f1aa; +$fa-var-journal-whills: \f66a; +$fa-var-js: \f3b8; +$fa-var-js-square: \f3b9; +$fa-var-jsfiddle: \f1cc; +$fa-var-kaaba: \f66b; +$fa-var-kaggle: \f5fa; +$fa-var-key: \f084; +$fa-var-keybase: \f4f5; +$fa-var-keyboard: \f11c; +$fa-var-keycdn: \f3ba; +$fa-var-khanda: \f66d; +$fa-var-kickstarter: \f3bb; +$fa-var-kickstarter-k: \f3bc; +$fa-var-kiss: \f596; +$fa-var-kiss-beam: \f597; +$fa-var-kiss-wink-heart: \f598; +$fa-var-kiwi-bird: \f535; +$fa-var-korvue: \f42f; +$fa-var-landmark: \f66f; +$fa-var-language: \f1ab; +$fa-var-laptop: \f109; +$fa-var-laptop-code: \f5fc; +$fa-var-laptop-house: \f966; +$fa-var-laptop-medical: \f812; +$fa-var-laravel: \f3bd; +$fa-var-lastfm: \f202; +$fa-var-lastfm-square: \f203; +$fa-var-laugh: \f599; +$fa-var-laugh-beam: \f59a; +$fa-var-laugh-squint: \f59b; +$fa-var-laugh-wink: \f59c; +$fa-var-layer-group: \f5fd; +$fa-var-leaf: \f06c; +$fa-var-leanpub: \f212; +$fa-var-lemon: \f094; +$fa-var-less: \f41d; +$fa-var-less-than: \f536; +$fa-var-less-than-equal: \f537; +$fa-var-level-down-alt: \f3be; +$fa-var-level-up-alt: \f3bf; +$fa-var-life-ring: \f1cd; +$fa-var-lightbulb: \f0eb; +$fa-var-line: \f3c0; +$fa-var-link: \f0c1; +$fa-var-linkedin: \f08c; +$fa-var-linkedin-in: \f0e1; +$fa-var-linode: \f2b8; +$fa-var-linux: \f17c; +$fa-var-lira-sign: \f195; +$fa-var-list: \f03a; +$fa-var-list-alt: \f022; +$fa-var-list-ol: \f0cb; +$fa-var-list-ul: \f0ca; +$fa-var-location-arrow: \f124; +$fa-var-lock: \f023; +$fa-var-lock-open: \f3c1; +$fa-var-long-arrow-alt-down: \f309; +$fa-var-long-arrow-alt-left: \f30a; +$fa-var-long-arrow-alt-right: \f30b; +$fa-var-long-arrow-alt-up: \f30c; +$fa-var-low-vision: \f2a8; +$fa-var-luggage-cart: \f59d; +$fa-var-lungs: \f604; +$fa-var-lungs-virus: \f967; +$fa-var-lyft: \f3c3; +$fa-var-magento: \f3c4; +$fa-var-magic: \f0d0; +$fa-var-magnet: \f076; +$fa-var-mail-bulk: \f674; +$fa-var-mailchimp: \f59e; +$fa-var-male: \f183; +$fa-var-mandalorian: \f50f; +$fa-var-map: \f279; +$fa-var-map-marked: \f59f; +$fa-var-map-marked-alt: \f5a0; +$fa-var-map-marker: \f041; +$fa-var-map-marker-alt: \f3c5; +$fa-var-map-pin: \f276; +$fa-var-map-signs: \f277; +$fa-var-markdown: \f60f; +$fa-var-marker: \f5a1; +$fa-var-mars: \f222; +$fa-var-mars-double: \f227; +$fa-var-mars-stroke: \f229; +$fa-var-mars-stroke-h: \f22b; +$fa-var-mars-stroke-v: \f22a; +$fa-var-mask: \f6fa; +$fa-var-mastodon: \f4f6; +$fa-var-maxcdn: \f136; +$fa-var-mdb: \f8ca; +$fa-var-medal: \f5a2; +$fa-var-medapps: \f3c6; +$fa-var-medium: \f23a; +$fa-var-medium-m: \f3c7; +$fa-var-medkit: \f0fa; +$fa-var-medrt: \f3c8; +$fa-var-meetup: \f2e0; +$fa-var-megaport: \f5a3; +$fa-var-meh: \f11a; +$fa-var-meh-blank: \f5a4; +$fa-var-meh-rolling-eyes: \f5a5; +$fa-var-memory: \f538; +$fa-var-mendeley: \f7b3; +$fa-var-menorah: \f676; +$fa-var-mercury: \f223; +$fa-var-meteor: \f753; +$fa-var-microblog: \f91a; +$fa-var-microchip: \f2db; +$fa-var-microphone: \f130; +$fa-var-microphone-alt: \f3c9; +$fa-var-microphone-alt-slash: \f539; +$fa-var-microphone-slash: \f131; +$fa-var-microscope: \f610; +$fa-var-microsoft: \f3ca; +$fa-var-minus: \f068; +$fa-var-minus-circle: \f056; +$fa-var-minus-square: \f146; +$fa-var-mitten: \f7b5; +$fa-var-mix: \f3cb; +$fa-var-mixcloud: \f289; +$fa-var-mixer: \f956; +$fa-var-mizuni: \f3cc; +$fa-var-mobile: \f10b; +$fa-var-mobile-alt: \f3cd; +$fa-var-modx: \f285; +$fa-var-monero: \f3d0; +$fa-var-money-bill: \f0d6; +$fa-var-money-bill-alt: \f3d1; +$fa-var-money-bill-wave: \f53a; +$fa-var-money-bill-wave-alt: \f53b; +$fa-var-money-check: \f53c; +$fa-var-money-check-alt: \f53d; +$fa-var-monument: \f5a6; +$fa-var-moon: \f186; +$fa-var-mortar-pestle: \f5a7; +$fa-var-mosque: \f678; +$fa-var-motorcycle: \f21c; +$fa-var-mountain: \f6fc; +$fa-var-mouse: \f8cc; +$fa-var-mouse-pointer: \f245; +$fa-var-mug-hot: \f7b6; +$fa-var-music: \f001; +$fa-var-napster: \f3d2; +$fa-var-neos: \f612; +$fa-var-network-wired: \f6ff; +$fa-var-neuter: \f22c; +$fa-var-newspaper: \f1ea; +$fa-var-nimblr: \f5a8; +$fa-var-node: \f419; +$fa-var-node-js: \f3d3; +$fa-var-not-equal: \f53e; +$fa-var-notes-medical: \f481; +$fa-var-npm: \f3d4; +$fa-var-ns8: \f3d5; +$fa-var-nutritionix: \f3d6; +$fa-var-object-group: \f247; +$fa-var-object-ungroup: \f248; +$fa-var-odnoklassniki: \f263; +$fa-var-odnoklassniki-square: \f264; +$fa-var-oil-can: \f613; +$fa-var-old-republic: \f510; +$fa-var-om: \f679; +$fa-var-opencart: \f23d; +$fa-var-openid: \f19b; +$fa-var-opera: \f26a; +$fa-var-optin-monster: \f23c; +$fa-var-orcid: \f8d2; +$fa-var-osi: \f41a; +$fa-var-otter: \f700; +$fa-var-outdent: \f03b; +$fa-var-page4: \f3d7; +$fa-var-pagelines: \f18c; +$fa-var-pager: \f815; +$fa-var-paint-brush: \f1fc; +$fa-var-paint-roller: \f5aa; +$fa-var-palette: \f53f; +$fa-var-palfed: \f3d8; +$fa-var-pallet: \f482; +$fa-var-paper-plane: \f1d8; +$fa-var-paperclip: \f0c6; +$fa-var-parachute-box: \f4cd; +$fa-var-paragraph: \f1dd; +$fa-var-parking: \f540; +$fa-var-passport: \f5ab; +$fa-var-pastafarianism: \f67b; +$fa-var-paste: \f0ea; +$fa-var-patreon: \f3d9; +$fa-var-pause: \f04c; +$fa-var-pause-circle: \f28b; +$fa-var-paw: \f1b0; +$fa-var-paypal: \f1ed; +$fa-var-peace: \f67c; +$fa-var-pen: \f304; +$fa-var-pen-alt: \f305; +$fa-var-pen-fancy: \f5ac; +$fa-var-pen-nib: \f5ad; +$fa-var-pen-square: \f14b; +$fa-var-pencil-alt: \f303; +$fa-var-pencil-ruler: \f5ae; +$fa-var-penny-arcade: \f704; +$fa-var-people-arrows: \f968; +$fa-var-people-carry: \f4ce; +$fa-var-pepper-hot: \f816; +$fa-var-percent: \f295; +$fa-var-percentage: \f541; +$fa-var-periscope: \f3da; +$fa-var-person-booth: \f756; +$fa-var-phabricator: \f3db; +$fa-var-phoenix-framework: \f3dc; +$fa-var-phoenix-squadron: \f511; +$fa-var-phone: \f095; +$fa-var-phone-alt: \f879; +$fa-var-phone-slash: \f3dd; +$fa-var-phone-square: \f098; +$fa-var-phone-square-alt: \f87b; +$fa-var-phone-volume: \f2a0; +$fa-var-photo-video: \f87c; +$fa-var-php: \f457; +$fa-var-pied-piper: \f2ae; +$fa-var-pied-piper-alt: \f1a8; +$fa-var-pied-piper-hat: \f4e5; +$fa-var-pied-piper-pp: \f1a7; +$fa-var-pied-piper-square: \f91e; +$fa-var-piggy-bank: \f4d3; +$fa-var-pills: \f484; +$fa-var-pinterest: \f0d2; +$fa-var-pinterest-p: \f231; +$fa-var-pinterest-square: \f0d3; +$fa-var-pizza-slice: \f818; +$fa-var-place-of-worship: \f67f; +$fa-var-plane: \f072; +$fa-var-plane-arrival: \f5af; +$fa-var-plane-departure: \f5b0; +$fa-var-plane-slash: \f969; +$fa-var-play: \f04b; +$fa-var-play-circle: \f144; +$fa-var-playstation: \f3df; +$fa-var-plug: \f1e6; +$fa-var-plus: \f067; +$fa-var-plus-circle: \f055; +$fa-var-plus-square: \f0fe; +$fa-var-podcast: \f2ce; +$fa-var-poll: \f681; +$fa-var-poll-h: \f682; +$fa-var-poo: \f2fe; +$fa-var-poo-storm: \f75a; +$fa-var-poop: \f619; +$fa-var-portrait: \f3e0; +$fa-var-pound-sign: \f154; +$fa-var-power-off: \f011; +$fa-var-pray: \f683; +$fa-var-praying-hands: \f684; +$fa-var-prescription: \f5b1; +$fa-var-prescription-bottle: \f485; +$fa-var-prescription-bottle-alt: \f486; +$fa-var-print: \f02f; +$fa-var-procedures: \f487; +$fa-var-product-hunt: \f288; +$fa-var-project-diagram: \f542; +$fa-var-pump-medical: \f96a; +$fa-var-pump-soap: \f96b; +$fa-var-pushed: \f3e1; +$fa-var-puzzle-piece: \f12e; +$fa-var-python: \f3e2; +$fa-var-qq: \f1d6; +$fa-var-qrcode: \f029; +$fa-var-question: \f128; +$fa-var-question-circle: \f059; +$fa-var-quidditch: \f458; +$fa-var-quinscape: \f459; +$fa-var-quora: \f2c4; +$fa-var-quote-left: \f10d; +$fa-var-quote-right: \f10e; +$fa-var-quran: \f687; +$fa-var-r-project: \f4f7; +$fa-var-radiation: \f7b9; +$fa-var-radiation-alt: \f7ba; +$fa-var-rainbow: \f75b; +$fa-var-random: \f074; +$fa-var-raspberry-pi: \f7bb; +$fa-var-ravelry: \f2d9; +$fa-var-react: \f41b; +$fa-var-reacteurope: \f75d; +$fa-var-readme: \f4d5; +$fa-var-rebel: \f1d0; +$fa-var-receipt: \f543; +$fa-var-record-vinyl: \f8d9; +$fa-var-recycle: \f1b8; +$fa-var-red-river: \f3e3; +$fa-var-reddit: \f1a1; +$fa-var-reddit-alien: \f281; +$fa-var-reddit-square: \f1a2; +$fa-var-redhat: \f7bc; +$fa-var-redo: \f01e; +$fa-var-redo-alt: \f2f9; +$fa-var-registered: \f25d; +$fa-var-remove-format: \f87d; +$fa-var-renren: \f18b; +$fa-var-reply: \f3e5; +$fa-var-reply-all: \f122; +$fa-var-replyd: \f3e6; +$fa-var-republican: \f75e; +$fa-var-researchgate: \f4f8; +$fa-var-resolving: \f3e7; +$fa-var-restroom: \f7bd; +$fa-var-retweet: \f079; +$fa-var-rev: \f5b2; +$fa-var-ribbon: \f4d6; +$fa-var-ring: \f70b; +$fa-var-road: \f018; +$fa-var-robot: \f544; +$fa-var-rocket: \f135; +$fa-var-rocketchat: \f3e8; +$fa-var-rockrms: \f3e9; +$fa-var-route: \f4d7; +$fa-var-rss: \f09e; +$fa-var-rss-square: \f143; +$fa-var-ruble-sign: \f158; +$fa-var-ruler: \f545; +$fa-var-ruler-combined: \f546; +$fa-var-ruler-horizontal: \f547; +$fa-var-ruler-vertical: \f548; +$fa-var-running: \f70c; +$fa-var-rupee-sign: \f156; +$fa-var-rust: \f97a; +$fa-var-sad-cry: \f5b3; +$fa-var-sad-tear: \f5b4; +$fa-var-safari: \f267; +$fa-var-salesforce: \f83b; +$fa-var-sass: \f41e; +$fa-var-satellite: \f7bf; +$fa-var-satellite-dish: \f7c0; +$fa-var-save: \f0c7; +$fa-var-schlix: \f3ea; +$fa-var-school: \f549; +$fa-var-screwdriver: \f54a; +$fa-var-scribd: \f28a; +$fa-var-scroll: \f70e; +$fa-var-sd-card: \f7c2; +$fa-var-search: \f002; +$fa-var-search-dollar: \f688; +$fa-var-search-location: \f689; +$fa-var-search-minus: \f010; +$fa-var-search-plus: \f00e; +$fa-var-searchengin: \f3eb; +$fa-var-seedling: \f4d8; +$fa-var-sellcast: \f2da; +$fa-var-sellsy: \f213; +$fa-var-server: \f233; +$fa-var-servicestack: \f3ec; +$fa-var-shapes: \f61f; +$fa-var-share: \f064; +$fa-var-share-alt: \f1e0; +$fa-var-share-alt-square: \f1e1; +$fa-var-share-square: \f14d; +$fa-var-shekel-sign: \f20b; +$fa-var-shield-alt: \f3ed; +$fa-var-shield-virus: \f96c; +$fa-var-ship: \f21a; +$fa-var-shipping-fast: \f48b; +$fa-var-shirtsinbulk: \f214; +$fa-var-shoe-prints: \f54b; +$fa-var-shopify: \f957; +$fa-var-shopping-bag: \f290; +$fa-var-shopping-basket: \f291; +$fa-var-shopping-cart: \f07a; +$fa-var-shopware: \f5b5; +$fa-var-shower: \f2cc; +$fa-var-shuttle-van: \f5b6; +$fa-var-sign: \f4d9; +$fa-var-sign-in-alt: \f2f6; +$fa-var-sign-language: \f2a7; +$fa-var-sign-out-alt: \f2f5; +$fa-var-signal: \f012; +$fa-var-signature: \f5b7; +$fa-var-sim-card: \f7c4; +$fa-var-simplybuilt: \f215; +$fa-var-sink: \f96d; +$fa-var-sistrix: \f3ee; +$fa-var-sitemap: \f0e8; +$fa-var-sith: \f512; +$fa-var-skating: \f7c5; +$fa-var-sketch: \f7c6; +$fa-var-skiing: \f7c9; +$fa-var-skiing-nordic: \f7ca; +$fa-var-skull: \f54c; +$fa-var-skull-crossbones: \f714; +$fa-var-skyatlas: \f216; +$fa-var-skype: \f17e; +$fa-var-slack: \f198; +$fa-var-slack-hash: \f3ef; +$fa-var-slash: \f715; +$fa-var-sleigh: \f7cc; +$fa-var-sliders-h: \f1de; +$fa-var-slideshare: \f1e7; +$fa-var-smile: \f118; +$fa-var-smile-beam: \f5b8; +$fa-var-smile-wink: \f4da; +$fa-var-smog: \f75f; +$fa-var-smoking: \f48d; +$fa-var-smoking-ban: \f54d; +$fa-var-sms: \f7cd; +$fa-var-snapchat: \f2ab; +$fa-var-snapchat-ghost: \f2ac; +$fa-var-snapchat-square: \f2ad; +$fa-var-snowboarding: \f7ce; +$fa-var-snowflake: \f2dc; +$fa-var-snowman: \f7d0; +$fa-var-snowplow: \f7d2; +$fa-var-soap: \f96e; +$fa-var-socks: \f696; +$fa-var-solar-panel: \f5ba; +$fa-var-sort: \f0dc; +$fa-var-sort-alpha-down: \f15d; +$fa-var-sort-alpha-down-alt: \f881; +$fa-var-sort-alpha-up: \f15e; +$fa-var-sort-alpha-up-alt: \f882; +$fa-var-sort-amount-down: \f160; +$fa-var-sort-amount-down-alt: \f884; +$fa-var-sort-amount-up: \f161; +$fa-var-sort-amount-up-alt: \f885; +$fa-var-sort-down: \f0dd; +$fa-var-sort-numeric-down: \f162; +$fa-var-sort-numeric-down-alt: \f886; +$fa-var-sort-numeric-up: \f163; +$fa-var-sort-numeric-up-alt: \f887; +$fa-var-sort-up: \f0de; +$fa-var-soundcloud: \f1be; +$fa-var-sourcetree: \f7d3; +$fa-var-spa: \f5bb; +$fa-var-space-shuttle: \f197; +$fa-var-speakap: \f3f3; +$fa-var-speaker-deck: \f83c; +$fa-var-spell-check: \f891; +$fa-var-spider: \f717; +$fa-var-spinner: \f110; +$fa-var-splotch: \f5bc; +$fa-var-spotify: \f1bc; +$fa-var-spray-can: \f5bd; +$fa-var-square: \f0c8; +$fa-var-square-full: \f45c; +$fa-var-square-root-alt: \f698; +$fa-var-squarespace: \f5be; +$fa-var-stack-exchange: \f18d; +$fa-var-stack-overflow: \f16c; +$fa-var-stackpath: \f842; +$fa-var-stamp: \f5bf; +$fa-var-star: \f005; +$fa-var-star-and-crescent: \f699; +$fa-var-star-half: \f089; +$fa-var-star-half-alt: \f5c0; +$fa-var-star-of-david: \f69a; +$fa-var-star-of-life: \f621; +$fa-var-staylinked: \f3f5; +$fa-var-steam: \f1b6; +$fa-var-steam-square: \f1b7; +$fa-var-steam-symbol: \f3f6; +$fa-var-step-backward: \f048; +$fa-var-step-forward: \f051; +$fa-var-stethoscope: \f0f1; +$fa-var-sticker-mule: \f3f7; +$fa-var-sticky-note: \f249; +$fa-var-stop: \f04d; +$fa-var-stop-circle: \f28d; +$fa-var-stopwatch: \f2f2; +$fa-var-stopwatch-20: \f96f; +$fa-var-store: \f54e; +$fa-var-store-alt: \f54f; +$fa-var-store-alt-slash: \f970; +$fa-var-store-slash: \f971; +$fa-var-strava: \f428; +$fa-var-stream: \f550; +$fa-var-street-view: \f21d; +$fa-var-strikethrough: \f0cc; +$fa-var-stripe: \f429; +$fa-var-stripe-s: \f42a; +$fa-var-stroopwafel: \f551; +$fa-var-studiovinari: \f3f8; +$fa-var-stumbleupon: \f1a4; +$fa-var-stumbleupon-circle: \f1a3; +$fa-var-subscript: \f12c; +$fa-var-subway: \f239; +$fa-var-suitcase: \f0f2; +$fa-var-suitcase-rolling: \f5c1; +$fa-var-sun: \f185; +$fa-var-superpowers: \f2dd; +$fa-var-superscript: \f12b; +$fa-var-supple: \f3f9; +$fa-var-surprise: \f5c2; +$fa-var-suse: \f7d6; +$fa-var-swatchbook: \f5c3; +$fa-var-swift: \f8e1; +$fa-var-swimmer: \f5c4; +$fa-var-swimming-pool: \f5c5; +$fa-var-symfony: \f83d; +$fa-var-synagogue: \f69b; +$fa-var-sync: \f021; +$fa-var-sync-alt: \f2f1; +$fa-var-syringe: \f48e; +$fa-var-table: \f0ce; +$fa-var-table-tennis: \f45d; +$fa-var-tablet: \f10a; +$fa-var-tablet-alt: \f3fa; +$fa-var-tablets: \f490; +$fa-var-tachometer-alt: \f3fd; +$fa-var-tag: \f02b; +$fa-var-tags: \f02c; +$fa-var-tape: \f4db; +$fa-var-tasks: \f0ae; +$fa-var-taxi: \f1ba; +$fa-var-teamspeak: \f4f9; +$fa-var-teeth: \f62e; +$fa-var-teeth-open: \f62f; +$fa-var-telegram: \f2c6; +$fa-var-telegram-plane: \f3fe; +$fa-var-temperature-high: \f769; +$fa-var-temperature-low: \f76b; +$fa-var-tencent-weibo: \f1d5; +$fa-var-tenge: \f7d7; +$fa-var-terminal: \f120; +$fa-var-text-height: \f034; +$fa-var-text-width: \f035; +$fa-var-th: \f00a; +$fa-var-th-large: \f009; +$fa-var-th-list: \f00b; +$fa-var-the-red-yeti: \f69d; +$fa-var-theater-masks: \f630; +$fa-var-themeco: \f5c6; +$fa-var-themeisle: \f2b2; +$fa-var-thermometer: \f491; +$fa-var-thermometer-empty: \f2cb; +$fa-var-thermometer-full: \f2c7; +$fa-var-thermometer-half: \f2c9; +$fa-var-thermometer-quarter: \f2ca; +$fa-var-thermometer-three-quarters: \f2c8; +$fa-var-think-peaks: \f731; +$fa-var-thumbs-down: \f165; +$fa-var-thumbs-up: \f164; +$fa-var-thumbtack: \f08d; +$fa-var-ticket-alt: \f3ff; +$fa-var-tiktok: \f97b; +$fa-var-times: \f00d; +$fa-var-times-circle: \f057; +$fa-var-tint: \f043; +$fa-var-tint-slash: \f5c7; +$fa-var-tired: \f5c8; +$fa-var-toggle-off: \f204; +$fa-var-toggle-on: \f205; +$fa-var-toilet: \f7d8; +$fa-var-toilet-paper: \f71e; +$fa-var-toilet-paper-slash: \f972; +$fa-var-toolbox: \f552; +$fa-var-tools: \f7d9; +$fa-var-tooth: \f5c9; +$fa-var-torah: \f6a0; +$fa-var-torii-gate: \f6a1; +$fa-var-tractor: \f722; +$fa-var-trade-federation: \f513; +$fa-var-trademark: \f25c; +$fa-var-traffic-light: \f637; +$fa-var-trailer: \f941; +$fa-var-train: \f238; +$fa-var-tram: \f7da; +$fa-var-transgender: \f224; +$fa-var-transgender-alt: \f225; +$fa-var-trash: \f1f8; +$fa-var-trash-alt: \f2ed; +$fa-var-trash-restore: \f829; +$fa-var-trash-restore-alt: \f82a; +$fa-var-tree: \f1bb; +$fa-var-trello: \f181; +$fa-var-tripadvisor: \f262; +$fa-var-trophy: \f091; +$fa-var-truck: \f0d1; +$fa-var-truck-loading: \f4de; +$fa-var-truck-monster: \f63b; +$fa-var-truck-moving: \f4df; +$fa-var-truck-pickup: \f63c; +$fa-var-tshirt: \f553; +$fa-var-tty: \f1e4; +$fa-var-tumblr: \f173; +$fa-var-tumblr-square: \f174; +$fa-var-tv: \f26c; +$fa-var-twitch: \f1e8; +$fa-var-twitter: \f099; +$fa-var-twitter-square: \f081; +$fa-var-typo3: \f42b; +$fa-var-uber: \f402; +$fa-var-ubuntu: \f7df; +$fa-var-uikit: \f403; +$fa-var-umbraco: \f8e8; +$fa-var-umbrella: \f0e9; +$fa-var-umbrella-beach: \f5ca; +$fa-var-underline: \f0cd; +$fa-var-undo: \f0e2; +$fa-var-undo-alt: \f2ea; +$fa-var-uniregistry: \f404; +$fa-var-unity: \f949; +$fa-var-universal-access: \f29a; +$fa-var-university: \f19c; +$fa-var-unlink: \f127; +$fa-var-unlock: \f09c; +$fa-var-unlock-alt: \f13e; +$fa-var-unsplash: \f97c; +$fa-var-untappd: \f405; +$fa-var-upload: \f093; +$fa-var-ups: \f7e0; +$fa-var-usb: \f287; +$fa-var-user: \f007; +$fa-var-user-alt: \f406; +$fa-var-user-alt-slash: \f4fa; +$fa-var-user-astronaut: \f4fb; +$fa-var-user-check: \f4fc; +$fa-var-user-circle: \f2bd; +$fa-var-user-clock: \f4fd; +$fa-var-user-cog: \f4fe; +$fa-var-user-edit: \f4ff; +$fa-var-user-friends: \f500; +$fa-var-user-graduate: \f501; +$fa-var-user-injured: \f728; +$fa-var-user-lock: \f502; +$fa-var-user-md: \f0f0; +$fa-var-user-minus: \f503; +$fa-var-user-ninja: \f504; +$fa-var-user-nurse: \f82f; +$fa-var-user-plus: \f234; +$fa-var-user-secret: \f21b; +$fa-var-user-shield: \f505; +$fa-var-user-slash: \f506; +$fa-var-user-tag: \f507; +$fa-var-user-tie: \f508; +$fa-var-user-times: \f235; +$fa-var-users: \f0c0; +$fa-var-users-cog: \f509; +$fa-var-users-slash: \f973; +$fa-var-usps: \f7e1; +$fa-var-ussunnah: \f407; +$fa-var-utensil-spoon: \f2e5; +$fa-var-utensils: \f2e7; +$fa-var-vaadin: \f408; +$fa-var-vector-square: \f5cb; +$fa-var-venus: \f221; +$fa-var-venus-double: \f226; +$fa-var-venus-mars: \f228; +$fa-var-viacoin: \f237; +$fa-var-viadeo: \f2a9; +$fa-var-viadeo-square: \f2aa; +$fa-var-vial: \f492; +$fa-var-vials: \f493; +$fa-var-viber: \f409; +$fa-var-video: \f03d; +$fa-var-video-slash: \f4e2; +$fa-var-vihara: \f6a7; +$fa-var-vimeo: \f40a; +$fa-var-vimeo-square: \f194; +$fa-var-vimeo-v: \f27d; +$fa-var-vine: \f1ca; +$fa-var-virus: \f974; +$fa-var-virus-slash: \f975; +$fa-var-viruses: \f976; +$fa-var-vk: \f189; +$fa-var-vnv: \f40b; +$fa-var-voicemail: \f897; +$fa-var-volleyball-ball: \f45f; +$fa-var-volume-down: \f027; +$fa-var-volume-mute: \f6a9; +$fa-var-volume-off: \f026; +$fa-var-volume-up: \f028; +$fa-var-vote-yea: \f772; +$fa-var-vr-cardboard: \f729; +$fa-var-vuejs: \f41f; +$fa-var-walking: \f554; +$fa-var-wallet: \f555; +$fa-var-warehouse: \f494; +$fa-var-water: \f773; +$fa-var-wave-square: \f83e; +$fa-var-waze: \f83f; +$fa-var-weebly: \f5cc; +$fa-var-weibo: \f18a; +$fa-var-weight: \f496; +$fa-var-weight-hanging: \f5cd; +$fa-var-weixin: \f1d7; +$fa-var-whatsapp: \f232; +$fa-var-whatsapp-square: \f40c; +$fa-var-wheelchair: \f193; +$fa-var-whmcs: \f40d; +$fa-var-wifi: \f1eb; +$fa-var-wikipedia-w: \f266; +$fa-var-wind: \f72e; +$fa-var-window-close: \f410; +$fa-var-window-maximize: \f2d0; +$fa-var-window-minimize: \f2d1; +$fa-var-window-restore: \f2d2; +$fa-var-windows: \f17a; +$fa-var-wine-bottle: \f72f; +$fa-var-wine-glass: \f4e3; +$fa-var-wine-glass-alt: \f5ce; +$fa-var-wix: \f5cf; +$fa-var-wizards-of-the-coast: \f730; +$fa-var-wolf-pack-battalion: \f514; +$fa-var-won-sign: \f159; +$fa-var-wordpress: \f19a; +$fa-var-wordpress-simple: \f411; +$fa-var-wpbeginner: \f297; +$fa-var-wpexplorer: \f2de; +$fa-var-wpforms: \f298; +$fa-var-wpressr: \f3e4; +$fa-var-wrench: \f0ad; +$fa-var-x-ray: \f497; +$fa-var-xbox: \f412; +$fa-var-xing: \f168; +$fa-var-xing-square: \f169; +$fa-var-y-combinator: \f23b; +$fa-var-yahoo: \f19e; +$fa-var-yammer: \f840; +$fa-var-yandex: \f413; +$fa-var-yandex-international: \f414; +$fa-var-yarn: \f7e3; +$fa-var-yelp: \f1e9; +$fa-var-yen-sign: \f157; +$fa-var-yin-yang: \f6ad; +$fa-var-yoast: \f2b1; +$fa-var-youtube: \f167; +$fa-var-youtube-square: \f431; +$fa-var-zhihu: \f63f; diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss new file mode 100644 index 0000000..eb153b2 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/brands.scss @@ -0,0 +1,23 @@ +/*! + * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: 400; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-brands-400.eot'); + src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), + url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); +} + +.fab { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss new file mode 100644 index 0000000..ac6d7e9 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/fontawesome.scss @@ -0,0 +1,16 @@ +/*! + * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; +@import 'mixins'; +@import 'core'; +@import 'larger'; +@import 'fixed-width'; +@import 'list'; +@import 'bordered-pulled'; +@import 'animated'; +@import 'rotated-flipped'; +@import 'stacked'; +@import 'icons'; +@import 'screen-reader'; diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss new file mode 100644 index 0000000..953e3a7 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/regular.scss @@ -0,0 +1,23 @@ +/*! + * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-regular-400.eot'); + src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), + url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); +} + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss new file mode 100644 index 0000000..6ea911c --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/solid.scss @@ -0,0 +1,24 @@ +/*! + * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-solid-900.eot'); + src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), + url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), + url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); +} + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; +} diff --git a/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss new file mode 100644 index 0000000..90f1392 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/fonts/fontawesome/v4-shims.scss @@ -0,0 +1,6 @@ +/*! + * Font Awesome Free 5.13.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; +@import 'shims'; diff --git a/MyOffice.SPA/src/assets/scss/pages/_auth.scss b/MyOffice.SPA/src/assets/scss/pages/_auth.scss new file mode 100644 index 0000000..113d220 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_auth.scss @@ -0,0 +1,211 @@ +.auth-container { + height: 100%; + width: 100%; + .auth-main { + height: 100%; + width: 100%; + margin: 0px !important; + min-height: 100vh; + } +} + +.left-img { + height: 100%; + width: 100%; + background-repeat: no-repeat; + background-position: center center; + background-size: cover; + display: flex; + align-items: center; + justify-content: center; + padding: 30px 15px; + position: relative; + z-index: 1; +} + +.left-content { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + max-width: 480px; + width: 100%; + text-align: center; + + h1 { + color: #fff; + } + p { + color: #fff; + } +} +.auth-form-section { + background-color: #fff; +} +.auth-form-btn { + display: flex; + justify-content: center; + width: 100%; + height: 50px !important; + border-radius: 10px; + cursor: pointer; + button { + width: 100%; + } +} +.form-section { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; +} +.auth-signup-text { + font-size: 18px; + color: #000; + padding-bottom: 30px; + width: 410px; + max-width: 100%; +} +.sign-up-link { + color: #3699ff; + font-size: 20px !important; + margin: 0px 10px; +} +.auth-wrapper { + width: 410px; + max-width: 100%; + margin-top: auto; + margin-bottom: auto; +} +.login-title { + margin-bottom: 20px; +} +.social-login-title { + font-size: 15px; + color: #919aa3; + display: flex; + margin: 20px 0px; + + &::before, + &::after { + content: ""; + background-image: linear-gradient(#bbb8b8, #f3f3f3); + flex-grow: 1; + background-size: calc(100% - 20px) 1px; + background-repeat: no-repeat; + } + + &::before { + background-position: center left; + } + + &::after { + background-position: center right; + } +} +.welcome-msg { + font-weight: 500; +} +.social-icon { + text-align: center; + li a { + color: #3c4858; + border: 1px solid #3c4858; + display: inline-block; + height: 32px; + width: 32px; + line-height: 32px; + text-align: center; + transition: all 0.4s ease; + overflow: hidden; + position: relative; + &:hover { + background-color: #2f55d4; + border-color: #2f55d4 !important; + color: #ffffff !important; + } + } +} +.sm-icon { + height: 16px !important; + width: 16px !important; +} +.show-pwd-icon { + color: rgba(0, 0, 0, 0.55); + padding: 12px; +} +.face-icon { + color: rgba(0, 0, 0, 0.55); +} +.auth-locked { + font-size: 60px; + color: #333; + width: 120px; + height: 120px; + background-color: transparent; + margin: 0 auto; + img { + width: 100px; + border-radius: 50%; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); + } +} +.auth-locked-title { + font-size: 30px; + font-family: Poppins, sans-serif; + color: #403866; + line-height: 1.2; + text-align: center; + width: 100%; + display: block; +} +.error-header { + font-size: 80px; + line-height: 1.2; + color: #403866; + text-transform: uppercase; + text-align: center; + width: 100%; + display: block; + font-weight: 700; +} +.error-subheader { + font-size: 17px; + color: #403866; + text-transform: uppercase; + text-align: center; + width: 100%; + display: block; + font-weight: 700; +} +.error-subheader2 { + font-size: 12px; + color: #919192; + text-align: center; + width: 100%; + display: block; + font-weight: 500; +} + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} + +.auth-spinner:before { + content: ""; + box-sizing: border-box; + position: absolute; + top: 50%; + left: 50%; + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + border-radius: 50%; + border: 2px solid #ffffff; + border-top-color: #000000; + animation: spinner 0.8s linear infinite; +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss b/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss new file mode 100644 index 0000000..539e19f --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_dashboard.scss @@ -0,0 +1,47 @@ +/* + * Document : _dashboard.scss + * Author : RedStar Template + * Description: This scss file for dashboard page style classes + */ +.dashboard-flot-chart { + height: 275px; +} + +.dashboard-donut-chart { + height: 265px; + text-align: center; +} + +.dashboard-line-chart { + height: 250px; +} + +.dashboard-stat-list { + list-style: none; + padding-left: 0; + margin-top: 40px; + + li { + padding: 16px 0 0 0; + + small { + font-size: 8px; + } + } +} + +.dashboard-task-infos { + .progress { + height: 10px; + position: relative; + top: 6px; + } +} +.totalEarning { + text-align: center; + padding: 6px; + color: #ff9800; +} +.earningProgress .progress { + height: 9px; +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_inbox.scss b/MyOffice.SPA/src/assets/scss/pages/_inbox.scss new file mode 100644 index 0000000..ba18d1a --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_inbox.scss @@ -0,0 +1,121 @@ +/* + * Document : _inbox.scss + * Author : RedStar Template + * Description: This scss file for email page style classes + */ +.p-15 { + padding: 15px; +} +.p-10 { + padding: 10px; +} +.b-b { + border-bottom: 1px solid rgba(0, 0, 0, 0.2); +} +.mail_listing { + .mail-option { + .btn-group { + margin-bottom: 5px; + } + } +} +#mail-nav { + .btn { + min-width: 110px; + } + #mail-folders { + list-style-type: none; + padding-left: 0px; + .badge { + float: right; + } + } + #mail-folders > li { + margin: 2px 0; + a { + &:hover { + color: #fff; + background-color: #337ab7; + } + } + &.active > a { + color: #fff; + background-color: #337ab7; + &:hover { + background-color: #32c0c3; + } + } + } + #mail-labels { + float: left; + width: 100%; + list-style-type: none; + padding-left: 0px; + li { + float: left; + } + .material-icons { + font-size: 16px; + height: 16px; + padding: 2px; + float: left; + } + } + #online-offline { + list-style-type: none; + padding-left: 0px; + .material-icons { + font-size: 8px; + height: 8px; + padding: 0px 5px 2px 0; + } + } + #mail-labels, + #online-offline { + li { + a:hover { + background-color: #e6e6e6; + } + } + } + li { + a { + color: #212529; + padding: 7px 10px; + display: block; + border-radius: 4px; + position: relative; + -webkit-transition: all 0.2s ease-out; + -moz-transition: all 0.2s ease-out; + transition: all 0.2s ease-out; + } + } +} +.composeForm { + padding: 25px; +} +.inbox-body { + padding: 20px; +} +.replyBox { + border: 1px solid rgba(120, 130, 140, 0.13); + padding: 20px; +} +.inbox-center .table thead th { + vertical-align: middle; + padding: 20px; +} +.email-btn-group { + position: relative; + display: -ms-inline-flexbox; + display: -webkit-inline-box; + display: inline-flex; + vertical-align: middle; +} +.max-texts { + padding: 15px !important; + a { + color: #212529; + padding: 10px 0px 10px 0px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_pricing.scss b/MyOffice.SPA/src/assets/scss/pages/_pricing.scss new file mode 100644 index 0000000..74de917 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_pricing.scss @@ -0,0 +1,195 @@ +/* + * Document : _pricing.scss + * Author : RedStar Template + * Description: This scss file for pricing page style classes + */ +//colors +$white: #fff; +$color_orange: #ffa442; +$color_blue: #4b64ff; +$color_red: #ff4b4b; +$color_green: #40c952; + +.pricingTable { + text-align: center; + background: $white; + margin: 0 -10px; + box-shadow: 0 0 10px #ababab; + padding-bottom: 40px; + border-radius: 10px; + color: #cad0de; + transform: scale(1); + transition: all 0.5s ease 0s; + &:hover { + transform: scale(1.05); + z-index: 1; + .pricingTable-header { + background: #ff9624; + i { + color: $white; + } + } + .price-value { + color: $white; + } + .month { + color: $white; + } + } + .pricingTable-header { + padding: 40px 0; + background: #f5f6f9; + border-radius: 10px 10px 50% 50%; + transition: all 0.5s ease 0s; + i { + font-size: 50px; + color: #858c9a; + margin-bottom: 10px; + transition: all 0.5s ease 0s; + } + } + .price-value { + font-size: 35px; + color: #ff9624; + transition: all 0.5s ease 0s; + } + .month { + display: block; + font-size: 14px; + color: #cad0de; + } + .heading { + font-size: 24px; + color: #ff9624; + margin-bottom: 20px; + text-transform: uppercase; + padding-top: 15px; + } + &.blue { + .price-value { + color: $color_blue; + } + .heading { + color: $color_blue; + } + &:hover .pricingTable-header { + background: $color_blue; + } + .pricingTable-signup a { + background: $color_blue; + &:hover { + box-shadow: 0 0 10px $color_blue; + } + } + } + &.red { + .price-value { + color: $color_red; + } + .heading { + color: $color_red; + } + &:hover .pricingTable-header { + background: $color_red; + } + .pricingTable-signup a { + background: $color_red; + &:hover { + box-shadow: 0 0 10px $color_red; + } + } + } + &.greenColor { + .price-value { + color: $color_green; + } + &:hover { + .pricingTable-header { + background: $color_green; + } + .price-value { + color: $white; + } + } + .pricingTable-signup a { + background: $color_green; + &:hover { + box-shadow: 0 0 10px $color_green; + } + } + } + &.blueColor { + &:hover { + .pricingTable-header { + background: $color_blue; + } + .price-value { + color: $white; + } + } + .price-value { + color: $color_blue; + } + .heading { + color: $color_blue; + } + .pricingTable-signup a { + background: $color_blue; + } + } + &.redColor { + &:hover { + .pricingTable-header { + background: $color_red; + } + .price-value { + color: $white; + } + } + .price-value { + color: $color_red; + } + .heading { + color: $color_red; + } + .pricingTable-signup a { + background: $color_red; + } + } + .pricing-content ul { + list-style: none; + padding: 0; + margin-bottom: 30px; + li { + line-height: 30px; + color: #a7a8aa; + } + } + .pricingTable-signup a { + display: inline-block; + font-size: 15px; + color: $white; + padding: 10px 35px; + border-radius: 20px; + background: $color_orange; + text-transform: uppercase; + transition: all 0.3s ease 0s; + &:hover { + box-shadow: 0 0 10px $color_orange; + } + } + &.green .heading { + color: $color_green; + } +} +@media screen and (max-width: 990px) { + .pricingTable { + margin: 0 0 20px 0; + } +} +.greenColor .heading { + font-size: 24px; + color: $color_green; + margin-bottom: 20px; + text-transform: uppercase; +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_profile.scss b/MyOffice.SPA/src/assets/scss/pages/_profile.scss new file mode 100644 index 0000000..a7c61ea --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_profile.scss @@ -0,0 +1,26 @@ +/* + * Document : _profile.scss + * Author : RedStar Template + * Description: This scss file for profile page style classes + */ +.profile-tab-box { + background: $white; + padding: 10px; + margin-top: 10px; + margin-bottom: 15px; + width: 100%; +} + +.skill-progress { + height: 10px !important; +} +.tab-all a { + color: #948f8f !important; + &.active { + background-color: #e91e63 !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), + 0 13px 24px -11px rgba(233, 30, 99, 0.6); + color: #ffffff !important; + border-radius: 30px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_projects.scss b/MyOffice.SPA/src/assets/scss/pages/_projects.scss new file mode 100644 index 0000000..7d910ba --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_projects.scss @@ -0,0 +1,539 @@ +@use "sass:math"; + +@function rem($size) { + $remSize: math.div($size, 16px); + @return #{$remSize}rem; +} + +.board { + height: 100%; + max-width: 100%; + background-color: #ffffff; + float: none; + box-shadow: none; + .list { + flex: 1 0 0; + margin: rem(16px) 0; + border-radius: rem(5px); + box-shadow: 0 rem(2px) rem(2px) rgba(#000, 0.03), + 0 rem(1px) rem(5px) rgba(#000, 0.02); + overflow: hidden; + .header { + display: flex; + padding: rem(18px) rem(14px); + background: #ffffff; + align-items: center; + .title { + flex: 1; + text-align: center; + h2 { + margin: 0 0 rem(6px); + font-weight: 500; + font-size: 18px; + line-height: 1; + } + .count { + font-size: rem(14px); + line-height: 1; + opacity: 0.65; + } + } + } + .projects { + margin: 0; + padding: rem(14px); + list-style: none; + &.cdk-drop-list-dragging { + opacity: 0.65; + } + .cdk-drag-placeholder { + display: none; + } + } + } +} + +.project { + cursor: pointer; + list-style: none; + padding: rem(16px); + background: #ffffff; + transition: box-shadow 0.2s; + min-height: 50px; + position: relative; + margin-bottom: 24px; + border: 1px solid #d1d1d1; + border-radius: 10px; + box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); + -webkit-box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); + + &:hover { + box-shadow: 0 rem(2px) rem(2px) rgba(#000, 0.1), + 0 rem(1px) rem(5px) rgba(#000, 0.09); + } + &:last-child { + margin-bottom: 0; + } + &:not(.project-list-add) { + padding-right: rem(32px); + } + + h3 { + margin: 0 0 rem(4px); + font-size: 1em; + font-weight: 500; + } + .description { + margin: 0 0 rem(8px); + } + .gravity { + display: flex; + font-size: rem(11px); + letter-spacing: 1px; + text-transform: uppercase; + .priority { + flex: 1; + } + .deadline { + margin-right: rem(-16px); + text-align: right; + .icon { + margin-right: rem(4px); + display: inline-block; + height: 1em; + overflow: visible; + font-size: inherit; + vertical-align: -0.125em; + } + .deadline-label { + display: none; + } + } + } + .project-actions { + opacity: 0; + position: absolute; + top: rem(6px); + right: rem(-3px); + transition: opacity 0.2s; + } + .project-actions[aria-expanded="true"], + &:hover .project-actions { + opacity: 1; + } +} + +@media (min-width: 768px) { + .board { + display: flex; + .list { + margin: 0; + box-shadow: none; + border-radius: 0; + border-width: 0 0 0 1px; + // &:last-child { + // border-right: 1px solid #bbb; + // } + } + } +} + +@media (min-width: 992px) { + .project .gravity .deadline .deadline-label { + display: inline; + } +} + +.wrapper { + display: flex; + flex-flow: column; + height: 100%; +} + +.container { + margin: 0 auto; + padding: 0 rem(8px); + max-width: 1320px; +} + +.header { + flex: 0 1 auto; + padding: rem(18px) 0; + background: linear-gradient( + to top, + var(--color-purple-heart), + var(--color-purple-heart-light) + ); + color: var(--color-white); + .container { + display: flex; + justify-content: space-between; + align-items: center; + } + h1 { + margin: 0; + font-size: rem(16px); + line-height: 1; + font-weight: 500; + text-transform: uppercase; + letter-spacing: rem(1.5px); + a { + color: var(--color-white); + } + svg { + position: relative; + top: -1px; + margin-right: rem(12px); + display: inline-block; + vertical-align: middle; + height: rem(25px); + } + span { + display: inline-block; + vertical-align: middle; + } + } +} + +nav { + flex: 0 1 auto; + padding: rem(3px) 0; + background: var(--color-purple-heart-dark); + .container { + display: flex; + justify-content: space-between; + align-items: center; + } + .menu { + a { + display: inline-block; + padding: rem(11px) rem(11px) rem(9px); + color: var(--color-white); + font-weight: 500; + text-decoration: none; + border-bottom: rem(3px) solid rgba(#fff, 0.5); + } + } + .actions { + position: fixed; + z-index: 10; + right: rem(40px); + bottom: rem(40px); + button { + width: rem(60px); + height: rem(60px); + padding: 0; + background: #1075f2; + color: white; + border: none; + border-radius: 50%; + box-shadow: 0 0 rem(20px) rgba(#000, 0.3); + cursor: pointer; + svg { + height: rem(30px); + } + } + } +} + +main { + position: relative; + flex: 1 1 auto; + .container { + height: 100%; + } +} +.project-bedge { + font-size: 12px; + font-weight: 500; + background-color: #d1d3d4; + display: inline-flex; + cursor: default; + user-select: none; + border-radius: 3px; + padding: 2px 5px; + float: right; +} +.project-bedge2 { + font-size: 12px; + font-weight: 500; + background-color: #d1d3d4; + display: inline-flex; + cursor: default; + user-select: none; + border-radius: 3px; + padding: 2px 5px; + float: left; +} +.project-priority--1 { + color: rgb(0, 218, 0); + font-weight: 500; +} +.project-priority-0 { + color: rgb(233, 0, 233); + font-weight: 500; +} +.project-priority-1 { + color: hsl(0, 84%, 31%); + font-weight: 500; +} +.project-type-Website { + background-color: #1075f2; + color: #fff; +} +.project-type-Android { + background-color: #f21023; + color: #fff; +} +.project-type-IPhone { + background-color: #110103; + color: #fff; +} +.project-type-Testing { + background-color: #06a800; + color: #fff; +} +.pro-left { + font-weight: 500; + padding: 0px 10px; + border-radius: 5px; +} +.project-title { + font-size: 17px; + color: #1f2225; +} +.project-icon { + font-size: 19px; + margin-right: 5px; + vertical-align: text-top; +} +.project-icon2 { + font-size: 16px; + margin-right: 5px; + vertical-align: text-top; +} +.add-icon { + font-size: 19px; + margin-right: 5px; + vertical-align: text-top; +} + +@media (min-width: 576px) { + .container { + padding: 0 rem(16px); + } +} + +.project-people { + text-align: right; + vertical-align: middle; + img { + width: 32px; + height: 32px; + } +} +.project-actions { + text-align: right; + vertical-align: middle; +} +.profile-content { + border-top: none !important; +} +.profile-stats { + margin-right: 10px; +} +.profile-image { + width: 120px; + float: left; + img { + width: 96px; + height: 96px; + } +} +.profile-info { + margin-left: 120px; +} +.feed-element { + padding-bottom: 15px; + margin-top: 15px; + overflow: hidden; + &:first-child { + margin-top: 0; + } + .media { + margin-top: 15px; + } + .well { + border: 1px solid #e7eaec; + box-shadow: none; + background: #f2f3ff; + margin-top: 10px; + margin-bottom: 5px; + padding: 10px 20px; + font-size: 11px; + line-height: 16px; + } + .actions { + margin-top: 10px; + } + .photos { + margin: 10px 0; + } + > .pull-left { + margin-right: 10px; + } + img.img-circle { + width: 38px; + height: 38px; + } +} +.media-body { + overflow: hidden; +} +.feed-photo { + max-height: 180px; + //Instead of the line below you could use @include border-radius($radius, $vertical-radius) + border-radius: 4px; + overflow: hidden; + margin-right: 10px; + margin-bottom: 10px; +} +.ibox { + clear: both; + margin-bottom: 25px; + margin-top: 0; + padding: 0; + &.collapsed { + .ibox-content { + display: none; + } + .fa { + &.fa-chevron-up:before { + content: "\f078"; + } + &.fa-chevron-down:before { + content: "\f077"; + } + } + } + &:after { + display: table; + } + &:before { + display: table; + } +} +.ibox-title { + background-color: #ffffff; + border-color: #e7eaec; + //Instead of the line below you could use @include border-image($value) + border-image: none; + border-style: solid solid none; + border-width: 3px 0 0; + color: inherit; + margin-bottom: 0; + padding: 14px 15px 7px; + min-height: 48px; +} +.ibox-content { + background-color: #ffffff; + color: inherit; + padding: 0px 20px 20px; + border-image: none; + border-width: 1px 0; +} +.ibox-footer { + color: inherit; + border-top: 1px solid #e7eaec; + font-size: 90%; + background: #ffffff; + padding: 10px 15px; +} +dd.project-people { + text-align: left; + margin-top: 5px; +} +.project-title a { + font-size: 14px; + color: #676a6c; + font-weight: 600; +} +.project-list table tr td { + border-top: none; + border-bottom: 1px solid #e7eaec; + padding: 15px 10px; + vertical-align: middle; +} +.project-manager .tag-list li a { + font-size: 10px; + background-color: white; + padding: 5px 12px; + color: inherit; + //Instead of the line below you could use @include border-radius($radius, $vertical-radius) + border-radius: 2px; + border: 1px solid #e7eaec; + margin-right: 5px; + margin-top: 5px; + display: block; +} +.project-files li a { + font-size: 11px; + color: #676a6c; + margin-left: 10px; + line-height: 22px; +} +.feed-activity-list { + margin: 10px; + .feed-element { + border-bottom: 1px solid #e7eaec; + } +} +.dropdown-messages-box img.img-circle { + width: 38px; + height: 38px; +} +.file-list li { + padding: 5px 10px; + font-size: 11px; + //Instead of the line below you could use @include border-radius($radius, $vertical-radius) + border-radius: 2px; + border: 1px solid #e7eaec; + margin-bottom: 5px; + a { + color: inherit; + &:hover { + color: #1ab394; + } + } +} +.user-friends img { + width: 42px; + height: 42px; + margin-bottom: 5px; + margin-right: 5px; +} +.project-activity { + border: 1px solid #e5e5e5; + margin-top: 20px; +} +.project-doc-icon { + width: 40px; + height: 40px; + border: 1px solid #d9d9d9; + border-radius: 0.55rem; + i { + font-size: 20px; + line-height: 40px; + } +} +.project-name { + color: #f68c1f; +} +.project-card-header { + color: #5b626b; + font-size: 17px; + line-height: 28px; + padding-right: 10px; + font-weight: 500; + margin-bottom: 10px; +} diff --git a/MyOffice.SPA/src/assets/scss/pages/_timeline.scss b/MyOffice.SPA/src/assets/scss/pages/_timeline.scss new file mode 100644 index 0000000..a5445a7 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/pages/_timeline.scss @@ -0,0 +1,744 @@ +/* + * Document : _timeline.scss + * Author : RedStar Template + * Description: This scss file for timeline page style classes + */ + +.cd-container { + width: 90%; + max-width: 1170px; + margin: 0 auto; +} + +.cd-container::after { + content: ""; + display: table; + clear: both; +} + +/* -------------------------------- + + Main components + + -------------------------------- */ +header { + height: 200px; + line-height: 200px; + text-align: center; + background: #303e49; +} + +header h1 { + color: #ffffff; + font-size: 18px; + font-size: 1.125rem; +} + +.timelineImgHight { + width: 150px; +} + +@media only screen and (min-width: 1170px) { + header { + height: 300px; + line-height: 300px; + } + header h1 { + font-size: 24px; + font-size: 1.5rem; + } +} + +#cd-timeline { + position: relative; + padding: 2em 0; + margin-top: 2em; + margin-bottom: 2em; +} + +#cd-timeline::before { + /* this is the vertical line */ + content: ""; + position: absolute; + top: 0; + left: 18px; + height: 100%; + width: 4px; + background: #d7e4ed; +} + +@media only screen and (min-width: 1170px) { + #cd-timeline { + margin-top: 3em; + margin-bottom: 3em; + } + #cd-timeline::before { + left: 50%; + margin-left: -2px; + } +} + +.cd-timeline-block { + position: relative; + margin: 2em 0; +} + +.cd-timeline-block::after { + clear: both; + content: ""; + display: table; +} + +.cd-timeline-block:first-child { + margin-top: 0; +} + +.cd-timeline-block:last-child { + margin-bottom: 0; +} + +@media only screen and (min-width: 1170px) { + .cd-timeline-block { + margin: 4em 0; + } + .cd-timeline-block:first-child { + margin-top: 0; + } + .cd-timeline-block:last-child { + margin-bottom: 0; + } +} + +.cd-timeline-img { + position: absolute; + top: 0; + left: 0; + width: 40px; + height: 40px; + border-radius: 50%; + box-shadow: 0 0 0 4px #e6dfdf, inset 0 2px 0 rgba(0, 0, 0, 0.08), + 0 3px 0 4px rgba(0, 0, 0, 0.05); +} + +.cd-timeline-img img { + display: block; + width: 48px; + position: relative; + left: 30%; + top: 30%; + margin-left: -12px; + margin-top: -12px; + border-radius: 50%; +} + +.cd-timeline-img.cd-picture { + background: #75ce66; +} + +.cd-timeline-img.cd-movie { + background: #c03b44; +} + +.cd-timeline-img.cd-location { + background: #f0ca45; +} + +@media only screen and (min-width: 1170px) { + .cd-timeline-img { + width: 60px; + height: 60px; + left: 50%; + margin-left: -30px; + /* Force Hardware Acceleration in WebKit */ + -webkit-transform: translateZ(0); + -webkit-backface-visibility: hidden; + } + .cssanimations .cd-timeline-img.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-img.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-1 0.6s; + -moz-animation: cd-bounce-1 0.6s; + animation: cd-bounce-1 0.6s; + } +} + +@-webkit-keyframes cd-bounce-1 { + 0% { + opacity: 0; + -webkit-transform: scale(0.5); + } + 60% { + opacity: 1; + -webkit-transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + } +} + +@-moz-keyframes cd-bounce-1 { + 0% { + opacity: 0; + -moz-transform: scale(0.5); + } + 60% { + opacity: 1; + -moz-transform: scale(1.2); + } + 100% { + -moz-transform: scale(1); + } +} + +@keyframes cd-bounce-1 { + 0% { + opacity: 0; + -webkit-transform: scale(0.5); + -moz-transform: scale(0.5); + -ms-transform: scale(0.5); + -o-transform: scale(0.5); + transform: scale(0.5); + } + 60% { + opacity: 1; + -webkit-transform: scale(1.2); + -moz-transform: scale(1.2); + -ms-transform: scale(1.2); + -o-transform: scale(1.2); + transform: scale(1.2); + } + 100% { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); + } +} + +.cd-timeline-content { + position: relative; + margin-left: 60px; + background: #f0f1f3; + border-radius: 0.25em; + padding: 1em; + box-shadow: 0 3px 0 #d7e4ed; +} + +.cd-timeline-content::after { + clear: both; + content: ""; + display: table; +} + +.cd-timeline-content h2 { + color: #303e49; +} + +.cd-timeline-content p, +.cd-timeline-content .cd-read-more, +.cd-timeline-content .cd-date { + font-size: 13px; + font-size: 0.8125rem; +} + +.cd-timeline-content .cd-read-more, +.cd-timeline-content .cd-date { + display: inline-block; +} + +.cd-timeline-content p { + margin: 1em 0; + line-height: 1.6; +} + +.cd-timeline-content .cd-read-more { + float: right; + padding: 0.8em 1em; + background: #acb7c0; + color: #ffffff; + border-radius: 0.25em; +} + +.no-touch .cd-timeline-content .cd-read-more:hover { + background-color: #bac4cb; +} + +.cd-timeline-content .cd-date { + float: left; + padding: 0.8em 0; + opacity: 0.7; +} + +.cd-timeline-content::before { + content: ""; + position: absolute; + top: 16px; + right: 100%; + height: 0; + width: 0; + border: 7px solid transparent; + border-right: 7px solid #ffffff; +} + +@media only screen and (min-width: 768px) { + .cd-timeline-content h2 { + font-size: 20px; + font-size: 1.25rem; + } + .cd-timeline-content p { + font-size: 16px; + font-size: 1rem; + } + .cd-timeline-content .cd-read-more, + .cd-timeline-content .cd-date { + font-size: 14px; + font-size: 0.875rem; + } +} + +@media only screen and (min-width: 1170px) { + .cd-timeline-content { + margin-left: 0; + padding: 1.6em; + width: 45%; + } + .cd-timeline-content::before { + top: 24px; + left: 100%; + border-color: transparent; + border-left-color: #f0f1f3; + } + .cd-timeline-content .cd-read-more { + float: left; + } + .cd-timeline-content .cd-date { + position: absolute; + width: 100%; + left: 122%; + top: 6px; + font-size: 16px; + font-size: 1rem; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content::before { + top: 24px; + left: auto; + right: 100%; + border-color: transparent; + border-right-color: #f0f1f3; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date { + left: auto; + right: 122%; + text-align: right; + } + .cssanimations .cd-timeline-content.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-content.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-2 0.6s; + -moz-animation: cd-bounce-2 0.6s; + animation: cd-bounce-2 0.6s; + } +} + +@media only screen and (min-width: 1170px) { + /* inverse bounce effect on even content blocks */ + .cssanimations + .cd-timeline-block:nth-child(even) + .cd-timeline-content.bounce-in { + -webkit-animation: cd-bounce-2-inverse 0.6s; + -moz-animation: cd-bounce-2-inverse 0.6s; + animation: cd-bounce-2-inverse 0.6s; + } +} + +@-webkit-keyframes cd-bounce-2 { + 0% { + opacity: 0; + -webkit-transform: translateX(-100px); + } + 60% { + opacity: 1; + -webkit-transform: translateX(20px); + } + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes cd-bounce-2 { + 0% { + opacity: 0; + -moz-transform: translateX(-100px); + } + 60% { + opacity: 1; + -moz-transform: translateX(20px); + } + 100% { + -moz-transform: translateX(0); + } +} + +@keyframes cd-bounce-2 { + 0% { + opacity: 0; + -webkit-transform: translateX(-100px); + -moz-transform: translateX(-100px); + -ms-transform: translateX(-100px); + -o-transform: translateX(-100px); + transform: translateX(-100px); + } + 60% { + opacity: 1; + -webkit-transform: translateX(20px); + -moz-transform: translateX(20px); + -ms-transform: translateX(20px); + -o-transform: translateX(20px); + transform: translateX(20px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -ms-transform: translateX(0); + -o-transform: translateX(0); + transform: translateX(0); + } +} + +@-webkit-keyframes cd-bounce-2-inverse { + 0% { + opacity: 0; + -webkit-transform: translateX(100px); + } + 60% { + opacity: 1; + -webkit-transform: translateX(-20px); + } + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes cd-bounce-2-inverse { + 0% { + opacity: 0; + -moz-transform: translateX(100px); + } + 60% { + opacity: 1; + -moz-transform: translateX(-20px); + } + 100% { + -moz-transform: translateX(0); + } +} + +@keyframes cd-bounce-2-inverse { + 0% { + opacity: 0; + -webkit-transform: translateX(100px); + -moz-transform: translateX(100px); + -ms-transform: translateX(100px); + -o-transform: translateX(100px); + transform: translateX(100px); + } + 60% { + opacity: 1; + -webkit-transform: translateX(-20px); + -moz-transform: translateX(-20px); + -ms-transform: translateX(-20px); + -o-transform: translateX(-20px); + transform: translateX(-20px); + } + 100% { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -ms-transform: translateX(0); + -o-transform: translateX(0); + transform: translateX(0); + } +} + +.timeline { + list-style: none; + padding: 0 0 8px; + position: relative; + &:before { + top: 00px; + bottom: 0; + position: absolute; + content: " "; + width: 3px; + background-color: #e7e7e7; + left: 25px; + margin-right: -1.5px; + } + > li { + margin-bottom: 5px; + position: relative; + &:before { + content: " "; + display: table; + } + &:after { + content: " "; + display: table; + clear: both; + } + > { + .timeline-panel { + width: calc(100% - 70px); + float: right; + border: 1px solid #e7e7e7; + border-radius: 2px; + padding: 5px 20px; + position: relative; + border-radius: 10px; + margin-bottom: 5px; + &:before { + position: absolute; + top: 26px; + left: -15px; + display: inline-block; + border-top: 15px solid transparent; + border-right: 15px solid #e7e7e7; + border-left: 0 solid #e7e7e7; + border-bottom: 15px solid transparent; + content: " "; + } + &:after { + position: absolute; + top: 27px; + left: -14px; + display: inline-block; + border-top: 14px solid transparent; + border-right: 14px solid #ffffff; + border-left: 0 solid #ffffff; + border-bottom: 14px solid transparent; + content: " "; + } + } + .timeline-badge { + width: 35px; + height: 35px; + position: absolute; + top: 25px; + left: 8px; + img { + border-radius: 50%; + border: 2px solid #ffffff; + -webkit-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); + -ms-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); + box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2); + } + } + } + } +} +.timeline-title { + margin: 4px 0 !important; + font-size: 13px; +} +.timeline-body > p { + font-size: 12px; + margin-bottom: 2px; +} + +// Timeline 2 + +.left-timeline { + margin: 0; + padding: 0; + list-style: none; + position: relative; + &:before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + width: 3px; + background: #eee; + left: 20%; + margin-left: -6px; + } + > li { + position: relative; + &:first-child { + .left-icon { + background: #fff; + color: #666; + } + .left-time span.large { + color: #444; + font-size: 17px !important; + font-weight: 700; + } + } + &:nth-child(odd) { + .left-label { + background: #f0f1f3; + &:after { + border-right-color: #f0f1f3; + } + } + .left-time span:last-child { + color: #444; + font-size: 13px; + } + } + .left-time { + display: block; + width: 23%; + padding-right: 70px; + position: absolute; + span { + display: block; + text-align: right; + &:first-child { + font-size: 15px; + color: #3d4c5a; + font-weight: 700; + } + &:last-child { + font-size: 14px; + color: #444; + } + } + } + .left-label { + margin: 0 0 15px 25%; + background: #f0f1f3; + padding: 1.2em; + position: relative; + //Instead of the line below you could use @include border-radius($radius, $vertical-radius) + border-radius: 5px; + &:after { + right: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-right-color: #f0f1f3; + border-width: 10px; + top: 10px; + } + blockquote { + font-size: 16px; + } + .map-checkin { + border: 5px solid rgba(235, 235, 235, 0.2); + //Instead of the line below you could use @include box-shadow($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10) + box-shadow: 0 0 0 1px #ebebeb; + background: #fff !important; + } + h2 { + margin: 0; + padding: 0 0 10px 0; + line-height: 26px; + font-size: 16px; + font-weight: normal; + a { + font-size: 15px; + &:hover { + text-decoration: none; + } + } + span { + font-size: 15px; + } + } + p { + color: #444; + } + } + .left-icon { + width: 40px; + height: 40px; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + font-size: 1.4em; + line-height: 40px; + position: absolute; + color: #fff; + border-radius: 50%; + box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.2); + text-align: center; + left: 20%; + top: 0; + margin: 0 0 0 -25px; + img { + border-radius: 50%; + } + } + .empty span { + color: #777; + } + } +} +@media screen and (max-width: 992px) and (min-width: 768px) { + .left-timeline > li .left-time { + padding-right: 60px; + } +} +@media screen and (max-width: 65.375em) { + .left-timeline > li .left-time span:last-child { + font-size: 12px; + } +} +@media screen and (max-width: 47.2em) { + .left-timeline { + &:before { + display: none; + } + > li { + .left-time { + width: 100%; + position: relative; + padding: 0 0 20px 0; + span { + text-align: left; + } + } + .left-label { + margin: 0 0 30px 0; + padding: 1em; + font-weight: 400; + font-size: 95%; + &:after { + right: auto; + left: 20px; + border-right-color: transparent; + border-bottom-color: #f5f5f6; + top: -20px; + } + } + .left-icon { + position: relative; + float: right; + left: auto; + margin: -64px 5px 0 0; + } + &:nth-child(odd) .left-label:after { + border-right-color: transparent; + border-bottom-color: #f5f5f6; + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss b/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss new file mode 100644 index 0000000..435404d --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_carousel.scss @@ -0,0 +1,37 @@ +/* + * Document : _carousel.scss + * Author : RedStar Template + * Description: This scss file for owl carousel style classes + */ + +.owl-btns { + text-align: center; + [class*="owl-"] { + color: #fff; + font-size: 14px; + margin: 5px; + padding: 4px 7px; + background: #d6d6d6; + display: inline-block; + cursor: pointer; + border-radius: 3px; + &:hover { + background: #869791; + color: #fff; + text-decoration: none; + } + } +} +#dashboard_slide { + padding: 6px 10px 0px 0px; +} +#dashboard_slide2 { + padding: 0px 10px 0px 0px; +} +.carousel-content { + height: 232px; + border-radius: 5px; + .slide-heading { + font-size: 20px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_charts.scss b/MyOffice.SPA/src/assets/scss/plugins/_charts.scss new file mode 100644 index 0000000..fa7850f --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_charts.scss @@ -0,0 +1,305 @@ +/* + * Document : _charts.scss + * Author : RedStar Template + * Description: This scss file for all charts style classes + */ +/* Morris */ +.morris-hover { + &.morris-default-style { + @include border-radius(0); + } +} + +/* Flot */ +.flot-chart { + width: 100%; + height: 320px; +} + +.panel-switch-btn { + position: relative; + right: 20px; + z-index: 9; + + label { + font-weight: bold !important; + } +} + +.legendLabel { + width: 85px !important; + position: relative; + left: 3px; +} + +#multiple_axis_chart { + .legendLabel { + width: 160px !important; + } +} + +/* Sparkline */ +.sparkline { + text-align: center; +} + +.chart-box { + display: flex; + justify-content: space-between; + font-size: 14px; + margin-bottom: 30px; +} +.chart-box2 { + font-size: 14px; + margin-bottom: 30px; + text-align: center; +} +.chart-note { + text-transform: capitalize; + display: inline-block; + margin-right: 12px; + font-size: 14px; + .dot { + margin: 0px 7px; + } +} +.chart-statis { + display: inline-block; + margin-right: 35px; + .label { + display: block; + text-transform: capitalize; + line-height: 1.2; + } + .index { + font-size: 18px; + color: #333; + padding-left: 15px; + } +} + +.dot { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 100%; +} +.dot-black { + background: #000000; +} +.dot-orange { + background: #f96332; +} +.chart-box-left { + padding-left: 10px; +} +.area_chart-style { + height: 170px; + margin: 30px; +} +.chart-shadow2 { + -webkit-filter: drop-shadow(0 -6px 4px rgba(106, 141, 247, 0.5)); + filter: drop-shadow(0 -6px 4px rgba(106, 141, 247, 0.5)); +} +.chart-shadow { + -webkit-filter: drop-shadow(0px 9px 2px rgba(0, 0, 0, 0.3)); + filter: drop-shadow(0px 9px 2px rgba(0, 0, 0, 0.3)); +} +.chartsh { + height: 16rem; +} + +// chartjs + +.axisData { + position: absolute; + color: #fff; + z-index: 1; + text-transform: uppercase; + display: flex; + width: 100%; + bottom: 0; + .tick { + flex: 1; + position: relative; + overflow: hidden; + opacity: 0.2; + font-size: 11px; + text-align: center; + line-height: 40px; + padding-top: 150px; + &:hover { + opacity: 1; + background-color: rgba(255, 255, 255, 0.2); + .value { + &.productValue { + transform: translateY(0); + display: block; + } + &.serviceValue { + transform: translateY(0); + display: block; + left: 0; + top: 80px; + color: #000; + transition: 0.3s transform; + } + } + } + .value { + transform: translateY(20px); + transition: 0.3s transform; + position: absolute; + top: 20px; + color: #000; + border-radius: 2px; + width: 100%; + line-height: 20px; + } + } +} +.dot-product { + background: #5bcfe4; +} +.dot-service { + background: #64e88b; +} +.dot-product1 { + background: #d3d3d3; +} +.dot-service1 { + background: #6e68c1; +} + +// ngx-chart +.chart-legend { + header { + background: transparent; + height: 0px; + } + .legend-labels { + background: transparent !important; + } +} +.ngx-charts { + text { + fill: #9aa0ac; + } +} + +// Gauge chart +mwl-gauge { + width: 150px; + height: 150px; + display: block; + padding: 10px; +} +mwl-gauge > .gauge > .dial { + stroke: #d7d7d7; + stroke-width: 5; + fill: rgba(0, 0, 0, 0); +} +mwl-gauge > .gauge > .value { + stroke: #4fa1f1; + stroke-width: 5; + fill: rgba(0, 0, 0, 0); +} +mwl-gauge > .gauge > .value-text { + fill: #4fa1f1; + font-family: sans-serif; + font-weight: bold; + font-size: 0.8em; +} +/* ------- Alternate Style ------- */ +mwl-gauge.two { +} +mwl-gauge.two > .gauge > .dial { + stroke: #334455; + stroke-width: 10; +} +mwl-gauge.two > .gauge > .value { + stroke: orange; + stroke-dasharray: none; + stroke-width: 13; +} +mwl-gauge.two > .gauge > .value-text { + fill: orange; +} +/* ------- Alternate Style ------- */ +mwl-gauge.three { +} +mwl-gauge.three > .gauge > .dial { + stroke: #334455; + stroke-width: 2; +} +mwl-gauge.three > .gauge > .value { + stroke: #c9de3c; + stroke-width: 5; +} +mwl-gauge.three > .gauge > .value-text { + fill: #c9de3c; +} +/* ----- Alternate Style ----- */ +mwl-gauge.four > .gauge > .dial { + stroke: #334455; + stroke-width: 5; +} +mwl-gauge.four > .gauge > .value { + stroke: #be80ff; + stroke-dasharray: none; + stroke-width: 5; +} +mwl-gauge.four > .gauge > .value-text { + fill: #be80ff; +} +/* ----- Alternate Style ----- */ +mwl-gauge.five > .gauge > .dial { + stroke: #334455; + stroke-width: 5; +} +mwl-gauge.five > .gauge > .value { + stroke: #f8774b; + stroke-dasharray: 25 1; + stroke-width: 5; +} +mwl-gauge.five > .gauge > .value-text { + fill: #f8774b; + font-size: 0.7em; +} +/* ----- Alternate Style ----- */ +mwl-gauge.six > .gauge > .dial { + stroke: #334455; + fill: #334455; + stroke-width: 20; +} +mwl-gauge.six > .gauge > .value { + stroke: #ff6daf; + stroke-width: 20; +} +mwl-gauge.six > .gauge > .value-text { + fill: #ff6daf; + font-size: 0.7em; +} +mwl-gauge.seven > .gauge > .dial { + stroke: transparent; + stroke-width: 5; + transform: scale(0.9, 0.9) translate3d(5.5px, 5.5px, 0); + fill: rgba(191, 202, 214, 0.42); +} +mwl-gauge.seven > .gauge > .value { + stroke: #f8774b; + stroke-dasharray: none; + stroke-width: 5; +} +ngx-gauge.guage-chart-center { + display: flex; + justify-content: center; + width: 100% !important; +} +.apex-pie-center { + display: flex; + justify-content: center; +} +.apexcharts-legend-marker { + margin: 0px 5px !important; +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss b/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss new file mode 100644 index 0000000..a63cbc2 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_formwizard.scss @@ -0,0 +1,368 @@ +/* + * Document : _formwizard.scss + * Author : RedStar Template + * Description: This scss file for wizard style classes + */ + +.wizard, +.tabcontrol { + display: block; + width: 100%; + overflow: hidden; +} + +.wizard a, +.tabcontrol a { + outline: 0; +} + +.wizard ul, +.tabcontrol ul { + list-style: none !important; + padding: 0; + margin: 0; +} + +.wizard ul > li, +.tabcontrol ul > li { + display: block; + padding: 0; +} +/* Accessibility */ +.wizard > .steps .current-info, +.tabcontrol > .steps .current-info, +.wizard > .content > .title, +.tabcontrol > .content > .title { + position: absolute; + left: -999em; +} + +.wizard { + > .steps { + position: relative; + display: block; + width: 100%; + } + + &.vertical { + > .steps { + float: left; + width: 30%; + clear: none; + } + + > .steps > ul > li { + float: none; + width: 100%; + } + + > .content { + float: left; + margin: 0 0 0.5em 0; + width: 70%; + clear: none; + } + + > .actions { + float: right; + width: 100%; + } + + > .actions > ul > li { + margin: 0 0 0 1em; + } + } + + > { + .steps { + .number { + font-size: 1.429em; + } + + > ul > li { + width: 25%; + float: left; + } + } + + .actions > ul > li { + float: left; + } + } + + > { + .steps { + a { + display: block; + width: auto; + margin: 0 0.5em 0.5em; + padding: 1em 1em; + text-decoration: none; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + + &:hover, + &:active { + display: block; + width: auto; + margin: 0 0.5em 0.5em; + padding: 1em 1em; + text-decoration: none; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + } + + .disabled a { + background: #eee; + color: #aaa; + cursor: default; + + &:hover, + &:active { + background: #eee; + color: #aaa; + cursor: default; + } + } + + .current a { + background: #2184be; + color: #fff; + cursor: default; + + &:hover, + &:active { + background: #2184be; + color: #fff; + cursor: default; + } + } + + .done a { + background: #9dc8e2; + color: #fff; + + &:hover, + &:active { + background: #9dc8e2; + color: #fff; + } + } + + .error a { + background: #ff3111; + color: #fff; + + &:hover, + &:active { + background: #ff3111; + color: #fff; + } + } + } + + .content { + border: 1px solid #ddd; + display: block; + margin: 0.5em; + min-height: 35em; + overflow: hidden; + position: relative; + width: auto; + } + } + + > { + .actions { + position: relative; + display: block; + text-align: right; + width: 100%; + } + } + + > .actions > ul { + display: inline-block; + text-align: right; + + > li { + margin: 0 0.5em; + } + } + + > { + .actions { + a { + background: #009688; + color: #fff; + display: block; + padding: 0.5em 1em; + text-decoration: none; + @include border-radius(0); + + &:hover, + &:active { + background: #009688; + color: #fff; + display: block; + padding: 0.5em 1em; + text-decoration: none; + @include border-radius(0); + } + } + + .disabled a { + background: #eee; + color: #aaa; + + &:hover, + &:active { + background: #eee; + color: #aaa; + } + } + } + } +} + +.tabcontrol > { + .steps { + position: relative; + display: block; + width: 100%; + + > ul { + position: relative; + margin: 6px 0 0 0; + top: 1px; + z-index: 1; + + > li { + float: left; + margin: 5px 2px 0 0; + padding: 1px; + -webkit-border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + + &:hover { + background: #edecec; + border: 1px solid #bbb; + padding: 0; + } + + &.current { + background: #fff; + border: 1px solid #bbb; + border-bottom: 0 none; + padding: 0 0 1px 0; + margin-top: 0; + + > a { + padding: 15px 30px 10px 30px; + } + } + + > a { + color: #5f5f5f; + display: inline-block; + border: 0 none; + margin: 0; + padding: 10px 30px; + text-decoration: none; + + &:hover { + text-decoration: none; + } + } + } + } + } + + .content { + position: relative; + display: inline-block; + width: 100%; + height: 35em; + overflow: hidden; + border-top: 1px solid #bbb; + padding-top: 20px; + + > .body { + float: left; + position: absolute; + width: 95%; + height: 95%; + padding: 2.5%; + + ul { + list-style: disc !important; + + > li { + display: list-item; + } + } + } + } +} + +.wizard { + .content { + min-height: 245px; + @include border-radius(0); + overflow-y: auto; + + .body { + padding: 15px; + } + } + + .steps { + a { + @include border-radius(0); + @include transition(0.5s); + + &:active, + &:focus, + &:hover { + @include border-radius(0); + } + } + + .done { + a { + background-color: rgba(#009688, 0.6); + + &:hover, + &:active, + &:focus { + background-color: rgba(#009688, 0.5); + } + } + } + + .error { + a { + background-color: #f44336 !important; + } + } + + .current { + a { + background-color: #009688; + + &:active, + &:focus, + &:hover { + background-color: #009688; + } + } + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss b/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss new file mode 100644 index 0000000..9586c44 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_imagegallery.scss @@ -0,0 +1,22 @@ +/* + * Document : _imagegallery.scss + * Author : RedStar Template + * Description: This scss file for image gallery style classes + */ +.group-1, +.group-2 { + border: 1px solid #ffffff; + border-radius: 5px; + display: table; + margin-bottom: 20px; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +.group-1 img, +.group-2 img { + cursor: pointer; + width: 300px; + height: 300px; + padding: 10px; + border-radius: 10px; +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_maps.scss b/MyOffice.SPA/src/assets/scss/plugins/_maps.scss new file mode 100644 index 0000000..3d4aef8 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_maps.scss @@ -0,0 +1,9 @@ +/* + * Document : _maps.scss + * Author : RedStar Template + * Description: This scss file for maps style classes + */ +/* Google Maps */ +agm-map { + height: 300px; +} diff --git a/MyOffice.SPA/src/assets/scss/plugins/_tables.scss b/MyOffice.SPA/src/assets/scss/plugins/_tables.scss new file mode 100644 index 0000000..46c0189 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/plugins/_tables.scss @@ -0,0 +1,910 @@ +/* + * Document : _tables.scss + * Author : RedStar Template + * Description: This scss file for tables style classes + */ + + .table { + tbody { + border-top: none !important; + tr { + td, + th { + padding: 10px; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + vertical-align: middle; + + ul { + margin: 0; + } + .tbl-user-img-small { + margin: 0px 5px; + border-radius: 5px; + height: 30px; + width: 30px; + } + } + } + + tr.primary { + td, + th { + background-color: #1f91f3; + color: #fff; + } + } + + tr.success { + td, + th { + background-color: #2b982b; + color: #fff; + } + } + + tr.info { + td, + th { + background-color: #00b0e4; + color: #fff; + } + } + + tr.warning { + td, + th { + background-color: #ff9600; + color: #fff; + } + } + + tr.danger { + td, + th { + background-color: #fb483a; + color: #fff; + } + } + } + + thead { + tr { + th { + padding: 0 10px; + height: 50px; + vertical-align: middle; + background-color: #f5f5f5; + color: #666; + font-weight: 500; + border: none; + } + } + } + + .tbl-pdf { + color: #f96332; + font-size: 20px; + cursor: pointer; + } + .tbl-action-btn { + height: 40px; + width: 40px; + display: inline-flex; + align-items: center; + } +} + +.table-bordered { + border-top: 1px solid #eee; + + tbody { + tr { + td, + th { + padding: 10px; + border: 1px solid #eee; + } + } + } + + thead { + tr { + th { + padding: 10px; + border: 1px solid #eee; + } + } + } +} + +.table-img { + img { + border-radius: 5px; + height: 33px; + width: 33px; + background: #fff; + position: inherit; + } +} + +.btn-tbl-edit { + background-color: #96a2b4; + height: 30px !important; + width: 30px !important; + margin: 2px !important; + line-height: 30px !important; + color: #fff; + + // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; + .material-icons { + font-size: 16px !important; + } + + &:hover { + background-color: #888; + color: $white; + } + + &:focus { + background-color: #888; + } +} + +.btn-tbl-delete { + background-color: #ff944f; + height: 30px !important; + width: 30px !important; + margin: 2px !important; + line-height: 30px !important; + color: #fff; + + // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; + .material-icons { + font-size: 16px !important; + } + + &:hover { + background-color: #ff9600; + color: $white; + } + + &:focus { + background-color: #ff9600; + } +} +.btn-tbl-confirm { + background-color: #3fa3f3; + height: 30px !important; + width: 30px !important; + margin: 2px !important; + line-height: 30px !important; + color: #fff; + + // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; + .material-icons { + font-size: 16px !important; + } + + &:hover { + background-color: #62b5f8; + color: $white; + } + + &:focus { + background-color: #62b5f8; + } +} +.btn-tbl-reject { + background-color: #f96333; + height: 30px !important; + width: 30px !important; + margin: 2px !important; + line-height: 30px !important; + color: #fff; + + // box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.2) !important; + .material-icons { + font-size: 16px !important; + } + + &:hover { + background-color: #f87346; + color: $white; + } + + &:focus { + background-color: #f87346; + } +} + +.tbl-fav-edit { + color: #6777ef; + display: inline !important; + .feather { + height: 20px !important; + width: 20px !important; + } +} +.tbl-fav-delete { + color: #ff5200; + display: inline !important; + .feather { + height: 20px !important; + width: 20px !important; + } +} +.avatar { + position: relative; + width: 30px; + white-space: nowrap; + border-radius: 1000px; + vertical-align: bottom; + display: inline-block; + + img { + width: 100%; + max-width: 100%; + height: auto; + border: 0; + border-radius: 1000px; + } +} + +.avatar-sm { + width: 32px; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.spinner { + display: inline-block; +} + +.spinner-reverse { + display: inline-block; +} + +.order-list li { + img { + border: 2px solid #ffffff; + box-shadow: 0 2px 10px 0 rgba(107, 111, 130, 0.3); + } + + + li { + margin-left: -14px; + } + + .badge { + background: rgba(255, 255, 255, 0.8); + color: #6b6f82; + margin-bottom: 6px; + } +} + +.buttons-copy { + background-color: #666 !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), + 0 13px 24px -11px rgba(233, 30, 99, 0.6); + color: #fff !important; + border-radius: 30px !important; + border: 0px !important; + height: 30px; + width: 60px; + cursor: pointer; +} + +.buttons-excel { + background-color: #59bf70 !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), + 0 13px 24px -11px rgba(233, 30, 99, 0.6); + color: #fff !important; + border-radius: 30px !important; + border: 0px !important; + height: 30px; + width: 60px; + cursor: pointer; +} + +.buttons-csv { + background-color: #2ab9d0 !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), + 0 13px 24px -11px rgba(233, 30, 99, 0.6); + color: #fff !important; + border-radius: 30px !important; + border: 0px !important; + height: 30px; + width: 60px; + cursor: pointer; +} + +.buttons-pdf { + background-color: #e91e63 !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), + 0 13px 24px -11px rgba(233, 30, 99, 0.6); + color: #fff !important; + border-radius: 30px !important; + border: 0px !important; + height: 30px; + width: 60px; + cursor: pointer; +} + +.buttons-print { + background-color: #6563ef !important; + box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.2), 0 13px 24px -11px #6563ef; + color: #fff !important; + border-radius: 30px !important; + border: 0px !important; + height: 30px; + width: 60px; + cursor: pointer; +} + +tr.group, +tr.group:hover { + background-color: #ddd !important; +} + +.tableBody { + font-size: 14px; + color: #555; + padding: 0px 15px 0px 15px; +} + +.tbl-checkbox { + text-align: center; +} + +.ngx-datatable.material { + background: #fff; + border: 1px solid #f5f5f5; + box-shadow: none !important; + + .datatable-footer { + .datatable-pager { + .pager li a { + margin: 5px; + + .datatable-icon-right, + .datatable-icon-skip, + .datatable-icon-left, + .datatable-icon-prev { + line-height: 30px; + } + } + + li.active a { + background-color: #0d8df3; + transition: 0.25s ease; + color: #ffffff; + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + } + } +} + +.ngx-table-form-select { + margin-top: 0px; + padding-left: 40px !important; +} + +.ngx-search { + margin: 15px auto !important; + width: 30% !important; + font-size: 13px !important; +} + +.ngx-datatable { + .datatable-body-cell { + display: table !important; + } + + .datatable-body-cell-label { + display: table-cell !important; + vertical-align: middle !important; + } + + .datatable-header-cell { + line-height: 2.4 !important; + } +} + +.ngxTableHeader { + padding: 10px 20px; + display: flex; + align-items: center; + border-color: #e6e9ed; + background-color: #ebebee; + min-width: 800px; + height: 70px; + + .header-buttons { + position: absolute; + right: 30px; + list-style: none; + margin-bottom: 0px; + + li { + display: inline-block; + } + + .material-icons { + color: #000000; + vertical-align: text-bottom; + } + } + + .header-buttons-left { + position: absolute; + list-style: none; + + li { + display: inline-block; + } + + .searchbox { + position: relative; + } + + ::placeholder { + color: rgba(0, 0, 0, 0.54); + } + + .search-icon { + position: absolute; + top: 10px; + padding-left: 10px; + color: rgba(0, 0, 0, 0.54); + } + + input.search-field { + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + border-radius: 25px; + border: 0; + height: 45px; + padding: 8px 8px 8px 50px; + width: 250px; + background: #ffffff; + transition: background 0.2s, width 0.2s; + + &:hover { + background: #fffefe; + } + + &:focus { + outline: none; + width: 380px; + color: #212121; + + &:hover { + background: #f7f7f7; + } + } + } + } + + h2 { + margin: 0; + font-size: 16px; + font-weight: normal; + color: #5b626b; + } +} + +.mat-table { + .mat-header-cell { + font-size: 14px; + font-weight: 600; + } +} + +.ngx-datatable.material { + background: #fff; + border: 1px solid #f5f5f5; + box-shadow: none !important; + + .datatable-footer { + .datatable-pager { + .pager li a { + margin: 5px; + + .datatable-icon-right, + .datatable-icon-skip, + .datatable-icon-left, + .datatable-icon-prev { + line-height: 30px; + } + } + + li.active a { + background-color: #0d8df3; + transition: 0.25s ease; + color: #ffffff; + box-shadow: 4px 3px 6px 0 rgba(0, 0, 0, 0.2); + } + } + } +} + +.ngx-table-form-select { + margin-top: 0px; + padding-left: 40px !important; +} + +.ngx-search { + margin: 15px auto !important; + width: 30% !important; + font-size: 13px !important; +} + +.ngx-datatable { + .datatable-body-cell { + display: table !important; + } + + .datatable-body-cell-label { + display: table-cell !important; + vertical-align: middle !important; + } + + .datatable-header-cell { + line-height: 2.4 !important; + } +} + +.materialTableHeader { + -webkit-box-align: center; + align-items: center; + border-color: #dae1f3; + background-color: #dae1f3; + display: flex; + flex-wrap: wrap; + text-align: center; + // min-width: 800px; + + .left { + flex: 35%; + height: 60px; + display: table-cell; + vertical-align: middle; + text-align: center; + } + .center { + flex: 40%; + height: 60px; + display: table-cell; + vertical-align: middle; + text-align: left; + } + + .right { + flex: 10%; + height: 60px; + display: table-cell; + vertical-align: middle; + text-align: center; + } + + .tbl-export-btn { + float: right; + margin: 0px 15px; + list-style: none; + height: 100%; + display: flex; + align-items: center; + + li { + display: inline-block; + position: relative; + } + } + + .header-buttons-left { + list-style: none; + height: 100%; + display: flex; + align-items: center; + + .tbl-search-box { + position: relative; + margin-left: 10px; + } + .tbl-title { + vertical-align: middle; + margin-left: 20px; + + h2 { + font-weight: 500; + } + } + .tbl-header-btn { + position: relative; + } + + li { + display: inline-block; + } + + .searchbox { + position: relative; + } + + ::placeholder { + color: rgba(0, 0, 0, 0.54); + } + + .search-icon { + position: absolute; + top: 10px; + padding-left: 10px; + color: rgba(0, 0, 0, 0.54); + } + + input.search-field { + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + border-radius: 5px; + border: 0; + height: 45px; + padding: 8px 8px 8px 50px; + width: 250px; + background: #ffffff; + + &:hover { + background: #fffefe; + } + + // &:focus { + // outline: none; + // width: 380px; + // color: #212121; + // &:hover { + // background: #f7f7f7; + // } + // } + } + } + + .header-buttons-right { + text-align: right; + list-style: none; + height: 100%; + margin: 0px 10px; + + .tbl-header-btn { + position: relative; + top: 12px; + } + + li { + display: inline-block; + } + + h2 { + margin: 0; + font-size: 16px; + font-weight: normal; + color: #5b626b; + } + } + + h2 { + margin: 0; + font-size: 16px; + font-weight: normal; + color: #5b626b; + } +} + +.tbl-checkbox label { + margin-bottom: 0px; +} +.column-nowrap { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.table-tab a { + background-color: #e2e2e2 !important; + color: #868788 !important; + border-radius: 30px; + &.active { + background-color: #7274e2 !important; + box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.2), 0 4px 13px -11px #7197b5; + color: #ffffff !important; + border-radius: 30px; + } +} +.app-list { + display: flex; + flex-direction: row; + align-items: center; + border-radius: 10px; + vertical-align: middle; + padding: 10px; + margin-bottom: 10px; + background: #f9f9f9; + img { + margin: 0px 10px; + } + .set-flex { + flex: 1; + } +} +.lecture-list { + display: flex; + flex-direction: row; + align-items: center; + border-radius: 5px; + vertical-align: middle; + padding: 10px; + margin-bottom: 10px; + background: #f6f4ff; +} +.report-list { + display: flex; + align-items: center; + margin-bottom: 20px; + padding: 12px 12px; + border: 1px dashed #bfc9d4; + border-radius: 6px; + .file-style { + font-size: 20px; + margin: 0px 10px; + } + .ms-auto { + margin-right: 10px; + cursor: pointer; + i { + padding-right: 10px; + } + } +} +.patient-group-list { + display: flex; + align-items: center; + padding: 12px 12px; + border-radius: 6px; + .lbl-bedge { + padding: 10px; + margin: 0px 5px; + border-radius: 50%; + position: relative; + display: inline-block; + width: 38px; + height: 38px; + font-size: 14px; + font-weight: 600; + letter-spacing: 1px; + .lbl-bedge-title { + color: #ffffff; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + } + } + + .group-details { + line-height: 38px; + padding-left: 10px; + font-weight: 500; + } +} +.tbl-spinner { + display: flex; + justify-content: center; + align-items: center; + margin-top: 20px; +} +.doc-file-type { + .d-flex { + margin-bottom: 15px; + padding-bottom: 15px; + border-bottom: 1px solid #d5dadb; + } + .img-icon { + width: 46px; + height: 46px; + line-height: 46px; + border-radius: 10%; + font-size: 23px; + text-align: center; + margin: 0px 15px; + } + .set-flex { + display: block; + color: #000; + height: 30px; + } + .ms-auto { + margin-right: 10px; + cursor: pointer; + } +} +.primary-rgba { + background-color: rgba(110, 129, 220, 0.1); +} +.success-rgba { + background-color: rgba(95, 194, 126, 0.1); +} +.danger-rgba { + background-color: rgba(244, 68, 85, 0.1); +} +.info-rgba { + background-color: rgba(114, 208, 251, 0.1); +} +.timetable-block { + border-radius: 4px; + border: 1px solid #f4f4f4; + padding: 10px; + margin-bottom: 20px; + box-shadow: 0 0.46875rem 2.1875rem rgba(90, 97, 105, 0.1), + 0 0.9375rem 1.40625rem rgba(90, 97, 105, 0.1), + 0 0.25rem 0.53125rem rgba(90, 97, 105, 0.12), + 0 0.125rem 0.1875rem rgba(90, 97, 105, 0.1); + background: #ffffff; +} +.medicine-list td { + padding: 0.4rem; +} +mat-cell > span.truncate-text { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} +.export-button { + cursor: pointer; + img { + height: 32px; + width: 32px; + } +} + +.mobile-label { + display: none; +} + +@media (max-width: 600px) { + .mobile-label { + width: 100px; + display: inline-block; + font-weight: bold; + } + + .mat-mdc-table .mdc-data-table__header-row { + display: none; + } + + .mat-mdc-table .mdc-data-table__row { + flex-direction: column; + align-items: start; + padding: 8px 24px; + } + mat-cell:first-of-type, + mat-header-cell:first-of-type, + mat-footer-cell:first-of-type { + padding-left: 10px; + } + .flex-item-right, + .flex-item-left { + flex: 100%; + } + .tbl-col-width-per-6 { + max-width: 100%; + } + .tbl-col-width-per-7 { + max-width: 100%; + } +} diff --git a/MyOffice.SPA/src/assets/scss/style.scss b/MyOffice.SPA/src/assets/scss/style.scss new file mode 100644 index 0000000..1142689 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/style.scss @@ -0,0 +1,107 @@ +/* + * Document : style.css + * Author : RedStar Template + * Description: This is a main style scss file for import all scss files. + * + * Structure (with shortcodes): + [1. Common ] + [2. Fonts ] + [3. Components ] + [4. Apps] + [5. Pages ] + [6. Pugins ] + [7. UI ] + [8. Browser ] + + +/* [1. Common ] */ + +/* Importing Bootstrap SCSS file. */ +@import "common/_variables"; +@import "common/_mixins"; +@import "common/_customanimate.scss"; +@import "common/_general.scss"; +@import "common/_demo.scss"; +@import "common/_helpers.scss"; +@import "common/_media.scss"; +@import "common/_animation.scss"; +@import "common/_rtl.scss"; + +/* [2. Fonts] */ +// @import "fonts/_material.scss"; +@import "fonts/fontawesome/fontawesome.scss"; +@import "fonts/fontawesome/regular.scss"; +@import "fonts/fontawesome/solid.scss"; +@import "fonts/fontawesome/brands.scss"; + +/* [3. Components ] */ +@import "components/_breadcrumbs.scss"; +@import "components/_checkboxradio.scss"; +@import "components/_dropdownmenu.scss"; +@import "components/_feed.scss"; +@import "components/_formcomponents.scss"; +@import "components/_infobox.scss"; +@import "components/_inputformgroup.scss"; +@import "components/_labels.scss"; +@import "components/_leftsidebaroverlay.scss"; +@import "components/_navbar"; +@import "components/_navtabs.scss"; +@import "components/_noticeboard.scss"; +@import "components/_rightsidebar.scss"; +@import "components/_searchbar.scss"; +@import "components/_switch.scss"; +@import "components/_thumbnails.scss"; +@import "components/_todo.scss"; +@import "components/_settingSidebar.scss"; + +/* [4. Apps] */ +@import "apps/_calendar.scss"; +@import "apps/_chat.scss"; +@import "apps/_contactlist.scss"; +@import "apps/_contactgrid.scss"; +@import "apps/_dragdrop.scss"; +@import "apps/_task.scss"; + +/* [5. Pages ] */ +@import "pages/_dashboard.scss"; +@import "pages/_inbox.scss"; +@import "pages/_pricing.scss"; +@import "pages/_profile.scss"; +@import "pages/_timeline.scss"; +@import "pages/_projects.scss"; +// @import "pages/_extra_pages.scss"; +@import "pages/_auth.scss"; + +/* [6. Pugins ] */ +@import "plugins/_carousel.scss"; +@import "plugins/_charts.scss"; +@import "plugins/_formwizard.scss"; +@import "plugins/_imagegallery.scss"; +@import "plugins/_maps.scss"; +@import "plugins/_tables.scss"; + +/* [7. UI ] */ +@import "ui/_alerts.scss"; +@import "ui/_badgelistgroupitem.scss"; +@import "ui/_buttons.scss"; +@import "ui/_card.scss"; +@import "ui/_collapse.scss"; +@import "ui/_dialogs.scss"; +@import "ui/_expansion.scss"; +@import "ui/_mediaobject.scss"; +@import "ui/_modals.scss"; +@import "ui/_pageloader.scss"; +@import "ui/_pagination.scss"; +@import "ui/_panels.scss"; +@import "ui/_preloaders.scss"; +@import "ui/_progressbars.scss"; +@import "ui/_slider.scss"; +@import "ui/_snackbar.scss"; +@import "ui/_tabs.scss"; +@import "ui/_tooltippopovers.scss"; +@import "ui/_ckeditor.scss"; +@import "ui/_listitems.scss"; + +/* [8. Browser ] */ +@import "browser/_ie10.scss"; +@import "browser/_ie11.scss"; diff --git a/MyOffice.SPA/src/assets/scss/theme/_dark.scss b/MyOffice.SPA/src/assets/scss/theme/_dark.scss new file mode 100644 index 0000000..8e1c5fe --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_dark.scss @@ -0,0 +1,1664 @@ +/* + * Document : dark.scss + * Author : RedStar Template + * Description: This scss file for dark theme style classes + */ +.dark { + background-color: #232b3e; + color: #96a2b4; + padding-top: 1px; + + body, + html { + background-color: #232b3e; + } + + input { + color: #96a2b4 !important; + } + + .dark-font-col { + color: #96a2b4; + } + + .card { + background: #1a202e; + border: none; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); + + .body { + color: #96a2b4; + } + + .header { + color: #96a2b4; + + h2 { + color: #96a2b4; + } + } + + .card-content { + color: #96a2b4; + } + + .card-statistic-3 { + .card-content { + color: #ffffff; + } + } + } + .card-bnner { + background: #1a202e; + } + + .course-card { + background: #1a202e; + + .bg-body-light { + background-color: #292c31; + } + } + + .plain-card { + background: #1a202e; + } + + .people-list { + .chat-list { + li { + &:hover { + background: #3f4650; + cursor: pointer; + } + + &.active { + background: #262b33; + } + } + } + } + + .chat { + .chat-history { + .message-data-time { + color: #96a2b4; + } + } + } + + .contact-usertitle-name { + color: #fff; + } + + .demo-skin { + color: #eaeaea; + + .form-check-label { + color: #eaeaea; + } + } + + .demo-settings { + color: #eaeaea; + } + + .block-header { + padding-bottom: 0px; + + h2 { + color: #96a2b4 !important; + } + } + + .select-wrapper { + input.select-dropdown { + color: #fff; + } + } + + .breadcrumb { + li { + &.active { + color: #a5abb1; + } + } + } + + .dropzone { + border: 1px solid #afacac !important; + background-color: #1a202e !important; + + .dz-message { + min-height: 150px !important; + background: #1a202e !important; + color: white; + } + } + + .sl-item { + .sl-content { + p { + color: #96a2b4; + } + } + } + + .info-box5 { + background-color: #1a202e; + } + + .form-check { + color: #96a2b4; + } + + label { + color: #96a2b4; + } + + .input-field { + input, + textarea { + color: #96a2b4; + } + } + + .input-group { + .input-group-addon { + .material-icons { + color: #96a2b4; + } + } + + input[type="text"], + .form-control { + color: #96a2b4; + } + } + + .container-login100 { + .form-group { + .form-control { + background: transparent; + } + } + } + + .form-group { + .form-control { + color: #96a2b4; + background: #1a202e; + } + + input.form-control { + color: #96a2b4; + border-bottom: 1px solid #9e9e9e; + } + } + + .form-check { + .form-check-sign { + .check { + border: 1px solid #96a2b4; + } + } + } + + .form-control { + color: #96a2b4; + background: #1a202e; + } + + .right-sidebar { + background: #1a202e; + } + + .ms-container { + .ms-selectable, + .ms-selection { + li.ms-hover { + color: #96a2b4 !important; + background-color: #46484e !important; + } + } + } + + .nav-tabs { + li { + a.active { + color: #fff !important; + } + } + } + + .bootstrap-tagsinput { + background-color: #343840 !important; + } + + .to-do-list { + li { + background: #1a202e; + } + } + + #mail-nav { + li { + a { + color: #96a2b4; + } + } + } + + .max-texts { + a { + color: #96a2b4; + } + } + + .pricingTable { + background: #0c0c0c; + + .pricingTable-header { + background: #36373c; + } + } + + .profile-tab-box { + background: #1a202e; + } + + .cd-timeline-content { + background: #10131c; + + .timelineLabelColor strong { + color: #ffffff !important; + } + } + + .timeline > li > .timeline-panel { + border: 1px solid #444444; + } + + .cd-timeline-content h2 { + color: #96a2b4; + } + + .chart-note { + color: #96a2b4; + } + + .chart-statis { + .index { + color: #96a2b4; + } + } + + .dataTables_wrapper { + input[type="search"] { + color: #96a2b4; + } + } + + .page-item.disabled .page-link { + color: #96a2b4; + pointer-events: none; + cursor: auto; + background-color: #1a202e; + } + + .table { + color: #96a2b4; + tbody { + tr { + color: #96a2b4; + + td, + th { + border-top: 1px solid rgb(21 24 29); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + color: #96a2b4; + } + } + } + + thead { + tr { + color: #96a2b4; + + th { + border-bottom: 1px solid #15181d; + border-top: 1px solid #15181d; + background-color: #15181d; + color: #abaaaa; + } + } + } + } + + .table-bordered { + border: 1px solid rgba(120, 130, 140, 0.5); + + tbody { + tr { + td, + th { + border-right: 1px solid rgba(120, 130, 140, 0.5); + border-bottom: none; + } + } + } + + thead { + tr { + th { + border: 1px solid rgba(120, 130, 140, 0.5); + } + } + } + + th { + border: 1px solid rgba(120, 130, 140, 0.5); + color: #96a2b4; + } + } + + tr.group, + tr.group:hover { + background-color: #282d35 !important; + } + + .tableBody { + color: #96a2b4; + } + + $theme-black: #1a202e; + + .card .header h2 strong { + color: #96a2b4 !important; + } + + .breadcrumb-main { + .page-title { + color: #a5abb1; + } + .breadcrumb-icon .feather { + color: #a5abb1 !important; + } + .breadcrumb-item { + color: #a5abb1; + ::before { + color: #a5abb1; + } + } + } + + .counter-box, + .box-part { + background: #1a202e !important; + color: #96a2b4; + } + + .tblActnBtn i { + color: #96a2b4; + } + + .chat .chat-history { + .other-message { + background: #3b4453; + + &:after { + border-bottom-color: #3b4454; + } + } + + .message { + color: #96a2b4; + } + + .my-message { + background: #343840; + + &:after { + border-bottom-color: #343840; + } + } + } + + .task-box { + border-bottom: solid 1px #5e5e5f; + color: #96a2b4; + background: #141a27; + } + + .task-list { + border: solid 1px #10141d; + background: #141a27; + } + + .mat-drawer { + background-color: #141a27; + color: #96a2b4; + border-color: #121315 !important; + } + + .mat-drawer-container { + background-color: #1a202e; + } + + .taskbar .card-footer { + background: #1a202e !important; + } + + .move { + background: #1a202e; + } + + .board { + background-color: #1a202e; + + .drop-card { + background-color: #404754; + } + .list { + .header { + background: #10131c; + } + .project-title { + color: #96a2b4; + } + .project { + background: #10131c; + border: 1px solid #363b47; + } + } + } + + .list-group-item { + background: #1a202e; + } + + .product-grid .product-content { + background-color: #3b4453; + } + + .ibox-title, + .ibox-content { + background: #1a202e; + border-color: #6c757d; + } + + .collapsible-header { + background: #1a202e; + } + + .card .card-inside-title { + color: #96a2b4; + } + + .left-timeline > li { + &:nth-child(odd) { + .left-label { + background: #202529; + + &:after { + border-right-color: #202428; + } + } + + .left-time span:last-child { + color: #eee; + } + } + + .left-label { + background: #303438; + + p { + color: #96a2b4; + } + + &:after { + border-right-color: #303438; + } + } + + .empty span { + color: #96a2b4; + } + + .left-time span { + &:first-child { + color: #96a2b4; + } + + &:last-child { + color: #eae9e9; + } + } + } + + .font-icon .icon-preview i { + color: #96a2b4; + } + + .nav-tabs .nav-link.active, + .nav-tabs .nav-item.show .nav-link { + background-color: transparent; + } + + .panel-group { + .panel-primary .panel-title a { + color: #96a2b4; + background: #32363c; + } + + .panel .panel-body { + color: #96a2b4; + } + } + + .btn-outline-primary { + color: #96a2b4 !important; + border: 1px solid #96a2b4 !important; + } + + .chip { + background-color: #31353a; + color: #96a2b4; + } + + .dropdown-content { + background-color: #31353a; + + li > span { + color: #96a2b4; + } + } + + .autocomplete { + font-size: 13px !important; + color: #96a2b4; + caret-color: #fff; + + &:focus { + color: #96a2b4; + } + } + + .autocomplete-content li { + .highlight { + color: #fff; + } + + :hover { + background-color: #343d44; + } + } + + //select 2 + .select2-container--default { + .select2-selection--single { + background: #1a202e; + color: #96a2b4; + border-bottom: 1px solid #9e9e9e; + + .select2-selection__rendered { + background: #1a202e; + color: #96a2b4; + border-bottom: 1px solid #9e9e9e; + } + } + + .select2-selection--multiple { + background: #1a202e; + color: #96a2b4; + border-bottom: 1px solid #9e9e9e; + + .select2-selection__choice { + background-color: #444141; + border: 1px solid #656464; + } + } + + &.select2-container--focus .select2-selection--multiple { + background: #1a202e; + color: #96a2b4; + border-bottom: 1px solid #9e9e9e; + } + + .select2-results > .select2-results__options { + background-color: #282d35; + } + } + + .select2-search--dropdown { + background-color: #1c1f25; + } + + .flatpickr-input { + border-bottom: 1px solid #9e9e9e !important; + } + + .ngx-datatable.material { + background: #1a202e; + color: #96a2b4; + + .datatable-body .datatable-body-row .datatable-body-cell { + color: #96a2b4; + } + + .datatable-header-cell-label { + color: #96a2b4; + } + + :not(.cell-selection) .datatable-body-row:hover .datatable-row-group { + background-color: #1c1f25; + } + } + + .pagination > li > a:hover { + background-color: #fff; + color: #000; + } + + .dataTables_length .custom-select { + background-color: #1a202e; + color: white; + } + + .ngx-search { + color: #96a2b4; + } + + .ngx-datatable { + &.material { + background: #1a202e; + border: 1px solid #404755; + + .datatable-header { + .datatable-header-cell { + background: #1a202e; + } + + .resize-handle { + border-right: solid 1px #1a202e; + } + } + + .datatable-footer { + color: #fff; + + .datatable-pager { + a { + color: #fff; + } + + li.disabled a { + color: #fff !important; + } + } + } + + .datatable-body .datatable-body-row .datatable-body-cell { + color: #96a2b4; + } + + &:not(.cell-selection) .datatable-body-row:hover { + background: #32383e; + + .datatable-row-group { + background: #32383e; + } + } + + .datatable-body-cell, + .datatable-header-cell { + border: 1px solid #404755; + } + } + + &.fixed-header + .datatable-header + .datatable-header-inner + .datatable-header-cell { + color: #96a2b4; + } + } + + ::-webkit-input-placeholder { + color: #96a2b4; + opacity: 1 !important; + /* for older chrome versions. may no longer apply. */ + } + + :-moz-placeholder { + /* Firefox 18- */ + color: #96a2b4; + opacity: 1 !important; + } + + ::-moz-placeholder { + /* Firefox 19+ */ + color: #96a2b4; + opacity: 1 !important; + } + + :-ms-input-placeholder { + color: #96a2b4; + } + + input, + textarea { + color: #96a2b4; + } + + .flatPicker { + color: #96a2b4; + } + + .modal { + .modal-content { + background: #1a202e; + + .modal-body { + color: #96a2b4; + } + } + + .modal-close-button { + color: #96a2b4; + } + } + + .ngx-search { + color: #96a2b4; + } + + .ngx-datatable { + background: #434f5a; + border: 1px solid #343d45; + + &.material { + background: #1a202e; + + .datatable-header { + .datatable-header-cell { + background: #313742; + } + + .resize-handle { + border-right: solid 1px #434f5a; + } + } + + .datatable-footer { + color: #fff; + + .datatable-pager { + a { + color: #fff; + } + + li.disabled a { + color: #fff !important; + } + } + } + + .datatable-body .datatable-body-row .datatable-body-cell { + color: #96a2b4; + } + + &:not(.cell-selection) .datatable-body-row:hover { + background: #32383e; + + .datatable-row-group { + background: #32383e; + } + } + } + + &.fixed-header + .datatable-header + .datatable-header-inner + .datatable-header-cell { + color: #96a2b4; + } + } + + .ngxTableHeader { + background-color: #242931; + + .header-buttons-left strong, + .header-buttons { + color: #96a2b4; + + .material-icons { + color: #96a2b4; + } + + .dropdown-menu li span { + color: #000000; + } + } + .header-buttons-left { + input.search-field { + background-color: #000000; + } + .search-icon { + color: rgba(255, 255, 255, 0.55); + } + input.search-field:focus:hover { + background: #000000; + } + } + } + + .navbar-nav { + .dropdown-menu { + background-color: #1a202e; + border: 1px solid #292a2a; + + &::after { + border-bottom: 6px solid #10131c; + } + + .header { + color: #96a2b4; + border-bottom: 1px solid #232a31; + } + + ul.menu { + .menu-info .menu-title { + color: #fff; + } + + li a { + border-bottom: 1px solid #232a31; + + &:hover { + background-color: #141820; + } + } + .msg-unread { + background-color: #141820; + } + .menu-info .menu-desc { + color: rgb(255, 255, 255, 0.5); + .material-icons { + color: rgb(255, 255, 255, 0.5); + } + } + } + .nfc-read-more { + color: #96a2b4; + } + } + + .user_dw_menu li { + border-bottom: 1px solid #232a31; + + a { + color: #96a2b4; + } + } + } + .fc .fc-col-header-cell-cushion { + color: #fff; + } + + .fc-daygrid-day-top .fc-daygrid-day-number { + color: #96a2b4; + } + .fc-theme-standard .fc-scrollgrid { + border: 1px solid #5c5c5c; + } + .fc-view > table td { + color: #96a2b4; + } + .fc-unthemed td { + &.fc-today { + background: transparent; + } + + &.fc-day-top .fc-day-number { + color: #ffffff; + } + } + + .fc-button-primary { + background-color: #151414 !important; + border-color: #4a4a4a !important; + color: #fff !important; + } + + .fc-view > table { + td { + border-color: #65686d; + } + + th { + color: #fff; + border-color: #65686d; + } + } + + /* Material Design Form style */ + + .mat-checkbox-frame { + border-color: #96a2b4; + } + + .mat-radio-outer-circle { + border-color: #96a2b4; + } + + .mat-datepicker-content { + .mat-calendar-next-button { + color: #96a2b4; + } + + .mat-calendar-previous-button { + color: #96a2b4; + } + + .time-container { + background-color: #12161f; + } + + .actions { + background-color: #12161f; + + .mat-button-wrapper { + .material-icons { + color: white; + } + } + + .mat-stroked-button:not([disabled]) { + border-color: rgba(255, 255, 255, 0.37); + } + } + } + + .mat-datepicker-toggle { + color: #96a2b4; + } + + .mat-select-value { + color: #96a2b4; + } + + .mat-form-field-appearance-legacy { + .mat-hint { + color: #96a2b4; + } + + .mat-form-field-label { + color: #96a2b4; + } + + .mat-form-field-underline { + background-color: #96a2b4; + } + } + + .mat-form-field-appearance-outline { + .mat-form-field-outline-thick { + color: #b7b7b7; + } + + .mat-form-field-outline { + color: #96a2b4; + } + + &.mat-focused .mat-form-field-outline-thick { + color: #96a2b4; + } + } + + .mat-stepper-horizontal { + background-color: #1a202e; + } + + .mat-stepper-vertical { + background-color: #1a202e; + } + + .mat-horizontal-stepper-header::after { + border-top-color: rgba(255, 255, 255, 0.12); + } + + .mat-horizontal-stepper-header::before { + border-top-color: rgba(255, 255, 255, 0.12); + } + + .mat-stepper-horizontal-line { + border-top-color: rgba(255, 255, 255, 0.12); + } + + .mat-form-field-ripple { + background-color: #96a2b4; + } + + .mat-select-arrow { + color: #96a2b4; + } + + input { + caret-color: #96a2b4; + } + + .mat-input-element { + caret-color: #96a2b4; + } + + .mat-hint { + color: #96a2b4; + } + + .mat-mdc-table { + background: #1a202e; + } + + .mat-mdc-cell { + color: #96a2b4; + border-bottom-color: rgba(234, 229, 229, 0.12); + } + + .mat-mdc-footer-cell { + color: #96a2b4; + } + + .mat-mdc-header-cell { + color: #96a2b4; + border-bottom: 1px solid #2a3040; + border-top: 1px solid #2a3040; + background-color: #2a3040; + font-weight: 500; + } + + .mat-mdc-paginator { + color: #96a2b4; + background: #1a202e; + } + + .mat-form-field-type-mat-native-select .mat-form-field-infix::after { + color: #96a2b4; + } + + .mat-form-field.mat-focused .mat-form-field-label { + color: #96a2b4; + } + + .mat-form-field-appearance-fill { + .mat-form-field-flex { + background-color: rgba(0, 0, 0, 0.25); + } + + .mat-form-field-underline::before { + background-color: #96a2b4; + } + } + + .mat-step-header .mat-step-label.mat-step-label-active { + color: #96a2b4; + } + + .mat-paginator-page-size .mat-select-trigger { + color: #96a2b4; + } + + .mat-dialog-container { + background: #1a202e; + color: #96a2b4; + } + + .mat-expansion-panel { + background: #101217; + color: #96a2b4; + border-bottom: 1px solid #31384b; + } + + .mat-expansion-panel-header-title { + color: #96a2b4; + } + + .mat-expansion-panel-header-description { + color: #96a2b4; + } + + .mat-card { + background: #12161f; + color: #96a2b4; + } + + .mat-card-subtitle { + color: #96a2b4; + } + + .mat-list-base .mat-list-option { + color: #96a2b4; + } + + .mat-list-base .mat-list-item { + color: #96a2b4; + } + + .list-group { + a.list-group-item { + color: #96a2b4; + } + + button.list-group-item { + color: #96a2b4; + } + + .list-group-item:hover { + background-color: rgba(10, 10, 10, 0.5); + } + } + + .mat-tab-label, + .mat-tab-link { + color: #96a2b4; + } + + .materialTableHeader { + background-color: #020910; + + h2 { + color: #96a2b4; + } + + ::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + color: #96a2b4; + opacity: 1; + /* Firefox */ + } + + :-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #96a2b4; + } + + ::-ms-input-placeholder { + /* Microsoft Edge */ + color: #96a2b4; + } + + .header-buttons-left { + input.search-field { + background: #12161f; + color: #96a2b4; + } + + .search-icon { + color: #96a2b4; + } + } + } + + .mat-menu-panel { + background: #12161f; + } + + .mat-menu-item { + color: #96a2b4; + + .mat-icon { + color: #96a2b4; + } + } + + .mat-menu-item-submenu-trigger::after { + color: #96a2b4; + } + + .mat-datepicker-content { + .mat-calendar { + background: #12161f; + color: #b8bbbd; + + .mat-calendar-body-cell-content { + color: #b8bbbd; + } + + .mat-calendar-table-header { + color: #b8bbbd; + } + + .mat-calendar-body-label { + color: #b8bbbd; + } + + .mat-calendar-body-today:not(.mat-calendar-body-selected) { + border-color: rgba(255, 255, 255, 0.32); + } + + .mat-calendar-arrow { + border-top-color: #b8bbbd; + } + } + } + + .mat-select-panel { + background: #12161f; + color: #b8bbbd; + + .mat-option { + color: #b8bbbd; + } + + .mat-option.mat-active { + color: #b8bbbd; + background: rgba(0, 0, 0, 0.4); + } + } + + .mat-pseudo-checkbox { + color: #b8bbbd; + } + + .mat-autocomplete-panel { + background: #12161f; + color: #b8bbbd; + + .mat-option-text { + color: #b8bbbd; + } + } + + .container-login100 { + background: #12161f; + } + + .login100-form { + background-color: #1a202e; + } + + .login100-form-title, + .error-header, + .error-subheader { + color: #ffffff; + } + + .txt1 { + color: #96a2b4; + } + + .apexcharts-legend-text { + color: #96a2b4 !important; + } + + .mat-button[disabled], + .mat-icon-button[disabled], + .mat-stroked-button[disabled], + .mat-flat-button[disabled], + .mat-raised-button[disabled], + .mat-fab[disabled], + .mat-mini-fab[disabled], + .mat-flat-button[disabled], + .mat-raised-button[disabled], + .mat-fab[disabled], + .mat-mini-fab[disabled], + .mat-flat-button[disabled], + .mat-raised-button[disabled], + .mat-fab[disabled], + .mat-mini-fab[disabled] { + color: rgba(255, 255, 255, 0.23); + } + + .mat-stroked-button:not([disabled]) { + border-color: rgba(255, 255, 255, 0.3); + } + + .mat-bottom-sheet-container { + background: #12161f; + } + + .mat-row { + border-bottom-color: rgba(255, 255, 255, 0.12); + } + // .material-icons-two-tone { + // filter: invert(99%) sepia(95%) saturate(4461%) hue-rotate(181deg) + // brightness(134%) contrast(83%); + // } + .appointment-tab-box { + background-color: #11141b; + } + .owl-dt-calendar-table { + .owl-dt-calendar-cell { + color: #96a2b4; + } + .owl-dt-calendar-header { + color: #96a2b4; + } + } + .owl-dt-container { + background: #11141b; + } + .owl-dt-calendar-control { + color: #ffffff; + } + .owl-dt-timer-content .owl-dt-timer-input { + border: 1px solid #717070; + background-color: #000000; + } + .owl-dt-container-buttons { + color: #ffffff; + } + .show-pwd-icon { + color: #96a2b4; + } + .mat-form-field-prefix, + .mat-form-field-suffix { + color: #96a2b4; + } + .app-list { + background: #181c27; + } + .lecture-list { + background: #181c27; + } + .media .media-body { + color: #96a2b4; + } + .auth-form-section { + background-color: #11141b; + } + .lang-item .lang-item-list { + color: #96a2b4; + &.active { + background-color: #10131c; + } + &:hover { + background-color: #171a21; + span.mdc-list-item__primary-text { + color: #ffffff; + } + } + } + .settingSidebar { + background: #1a202e; + .setting-panel-header { + color: #ffffff; + border: 1px solid #000000; + background: #000000; + } + .border-bottom { + border-bottom: 1px solid #3b434a !important; + } + } + .breadcrumb { + color: #96a2b4; + } + .breadcrumb-icon .feather { + color: #96a2b4; + } + .contact-details-field .color-icon { + filter: invert(68%) sepia(6%) saturate(787%) hue-rotate(177deg) + brightness(94%) contrast(86%); + } + .material-icons-two-tone { + filter: invert(68%) sepia(6%) saturate(787%) hue-rotate(177deg) + brightness(94%) contrast(86%); + } + .doc-file-type { + .d-flex { + border-bottom: 1px solid #15181d; + } + .set-flex { + color: #96a2b4; + } + } + .feed-element .well { + border: 1px solid #10131c; + background: #10131c; + } + .feed-activity-list .feed-element { + border-bottom: 1px solid #525252; + } + .project-activity { + border: 1px solid #525252; + margin-top: 20px; + } + .project-card-header { + color: #96a2b4; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + + .mat-mdc-dialog-container { + .mdc-dialog__surface { + background: #1a202e; + color: #96a2b4; + } + .mdc-dialog__content { + background: #1a202e; + color: #96a2b4 !important; + } + } + .mdc-text-field--outlined:not(.mdc-text-field--disabled) + .mdc-notched-outline__leading, + .mdc-text-field--outlined:not(.mdc-text-field--disabled) + .mdc-notched-outline__notch, + .mdc-text-field--outlined:not(.mdc-text-field--disabled) + .mdc-notched-outline__trailing { + border-color: rgba(255, 255, 255, 0.38); + } + + .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( + .mdc-text-field--focused + ):hover + .mdc-notched-outline + .mdc-notched-outline__leading, + .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( + .mdc-text-field--focused + ):hover + .mdc-notched-outline + .mdc-notched-outline__notch, + .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( + .mdc-text-field--focused + ):hover + .mdc-notched-outline + .mdc-notched-outline__trailing { + border-color: #96a2b4; + } + + .mdc-text-field--outlined:not(.mdc-text-field--disabled):not( + .mdc-text-field--focused + ):hover + .mdc-notched-outline + .mdc-notched-outline__notch { + border-left: none; + } + .mat-mdc-dialog-container .mdc-dialog__title { + color: #96a2b4; + } + .mat-button-toggle-appearance-standard { + color: #96a2b4; + background: #1d1d1d; + } + .mat-button-toggle-checked { + background: #000000 !important; + color: #96a2b4; + } + .mat-button-toggle-standalone.mat-button-toggle-appearance-standard, + .mat-button-toggle-group-appearance-standard { + border: solid 1px #4a4a4a; + } + .mat-button-toggle-group-appearance-standard + .mat-button-toggle + + .mat-button-toggle { + border: solid 1px #4a4a4a; + } + .mat-button-toggle-disabled .mat-button-toggle-button { + background-color: #565656; + color: white; + } + + .mdc-text-field:not(.mdc-text-field--disabled) .mdc-floating-label { + color: #96a2b4; + } + .mdc-text-field:not(.mdc-text-field--disabled) .mdc-text-field__input { + color: #96a2b4; + } + .mat-mdc-select-value { + color: #96a2b4; + } + .mdc-text-field--filled:not(.mdc-text-field--disabled) { + background-color: #181b24; + } + .mat-mdc-checkbox + .mdc-checkbox + .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not( + [data-indeterminate="true"] + ) + ~ .mdc-checkbox__background { + border-color: #96a2b4; + } + .mat-mdc-checkbox + .mdc-checkbox:hover + .mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate):not( + [data-indeterminate="true"] + ) + ~ .mdc-checkbox__background { + border-color: #96a2b4; + } + + .mat-mdc-paginator-icon { + fill: #96a2b4; + } + .mat-mdc-radio-button + .mdc-radio + .mdc-radio__native-control:enabled:not(:checked) + + .mdc-radio__background + .mdc-radio__outer-circle { + border-color: #96a2b4; + } + .mat-mdc-select-arrow { + color: #96a2b4; + } + .mat-mdc-icon-button[disabled] .mat-mdc-paginator-icon { + fill: rgba(255, 255, 255, 0.15); + } + .mat-mdc-tab:not(.mat-mdc-tab-disabled) .mdc-tab__text-label { + color: #96a2b4; + } + .order-list li { + .badge { + background: rgb(12, 12, 12, 0.8); + } + img { + border: 2px solid #545454; + } + } + .mat-mdc-raised-button:disabled { + color: #7c7c7c; + } + + .nfc-menu { + .nfc-dropdown { + background-color: #1b1e27; + .menu { + button { + &:hover { + background-color: #10131c; + } + } + .msg-read { + background-color: #1b1e27; + border-bottom: 1px solid #5e5e5e; + } + .menu-info { + h4 { + color: #96a2b4; + } + .menu-title { + color: #96a2b4; + } + p { + color: rgba(255, 255, 255, 0.55); + } + .menu-desc { + color: rgba(255, 255, 255, 0.55); + .material-icons { + color: #979797; + } + } + } + .msg-unread { + background-color: #000000; + border-bottom: 1px solid #5e5e5e; + } + } + } + .nfc-footer { + background-color: #1b1e27; + border-top: 1px solid #363636; + .nfc-read-all { + color: rgb(181 181 181); + } + } + } + .user_dw_menu { + .mat-mdc-menu-item.mdc-list-item { + background-color: #1b1e27; + &:hover { + background-color: #10131c; + } + } + .mat-mdc-menu-item .mdc-list-item__primary-text { + color: #d5d5d5; + } + } + .mat-mdc-select-panel-above .mdc-menu-surface.mat-mdc-select-panel { + background-color: #10131c; + } + .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not( + .mdc-list-item--disabled + ) { + background: rgb(0 0 0); + } + .mat-mdc-option.mat-mdc-option-active { + background: rgb(0 0 0); + } + .mat-mdc-option.mdc-list-item { + background-color: #10131c; + } + .mdc-menu-surface.mat-mdc-select-panel { + background-color: #10131c; + } + .mat-mdc-option:hover:not(.mdc-list-item--disabled) { + background: rgb(0 0 0); + } + .mat-mdc-option .mdc-list-item__primary-text { + color: #d5d5d5 !important; + } + .mat-mdc-menu-panel.mat-mdc-menu-panel { + background-color: #10131c; + } + .mat-mdc-menu-item .mdc-list-item__primary-text { + color: white; + } + .mat-mdc-menu-item[disabled] .mat-icon-no-color { + color: #d5d5d5; + } + .mat-mdc-menu-item .mat-icon { + color: white; + } + nav.navbar { + box-shadow: 0 -18px 1px 5px rgb(35 43 62); + } + .app-dropdown { + .app-icons:hover { + background-color: #000000; + } + p { + color: #d5d5d5; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss new file mode 100644 index 0000000..b7b27b4 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-black.scss @@ -0,0 +1,235 @@ +/* + * Document : theme-black.scss + * Author : RedStar Template + * Description: This scss file for black theme style classes + */ +@import "_theme-color-variables"; + +.theme-black { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + + .navbar.active { + background: #485563; + /* fallback for old browsers */ + background: -webkit-linear-gradient(to right, #1c212d, #1a202e); + /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #1c212d, #1a202e); + + .nav { + > li { + > a { + color: #fff; + } + } + } + + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .navbar-brand { + color: $theme-black-navbar-brand; + + &:hover { + color: $theme-black-navbar-brand_hover; + } + + &:active { + color: $theme-black-navbar-brand_active; + } + + &:focus { + color: $theme-black-navbar-brand_focus; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-black-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-black-nav-anchor_focus; + text-decoration: none; + } + } + } + + .open { + > a { + background-color: $theme-black-nav-anchor-opened; + + &:hover { + background-color: $theme-black-nav-anchor-opened_hover; + } + + &:focus { + background-color: $theme-black-nav-anchor-opened_focus; + } + } + } + } + + .bars { + color: $theme-black-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-black-menu-list-active; + } + + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + + &:hover { + color: $theme-black-sidebar-menu-hover; + // i, + // span { + // color: $theme-black-sidebar-menu-hover; + // } + } + } + } + + .ml-menu { + background-color: $theme-black-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-black-legal-bg; + + .copyright { + a { + color: $theme-black !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-black !important; + } + + .page-item.active .page-link { + background-color: $theme-black; + border-color: $theme-black; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-black-button-color !important; + color: #fff !important; + border-color: $theme-black !important; + + &:hover { + background-color: $theme-black !important; + color: #fff !important; + } + + &:active { + background-color: $theme-black !important; + color: #fff !important; + } + + &:focus { + background-color: $theme-black !important; + color: #fff !important; + } + + &:disabled { + background-color: $theme-black !important; + color: #fff !important; + } + } + + .btn-outline-primary { + background: 0 0 !important; + color: $theme-black !important; + border: 1px solid $theme-black !important; + + &:hover { + background: $theme-black !important; + color: #fff !important; + border: 1px solid $theme-black !important; + } + } + + .timelineLabelColor strong { + color: $theme-black !important; + } + + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-black; + } + } + + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + + &:hover { + color: $theme-black; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-black; + } +} + +/*Logo Header Background Color*/ +.logo-black { + .navbar-header { + background-color: #1a202e; + border-right: 1px solid #323538; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-blue.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-blue.scss new file mode 100644 index 0000000..ca4dd56 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-blue.scss @@ -0,0 +1,184 @@ +/* + * Document : theme-blue.scss + * Author : RedStar Template + * Description: This scss file for blue theme style classes + */ +@import "_theme-color-variables"; + +.theme-blue { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + .navbar.active { + // background-color: $theme-blue !important; + background: #00b4db; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #048efb, + #08b1d6 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #048efb, #08b1d6); + + .nav { + > li { + > a { + color: #fff; + } + } + } + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-blue-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-blue-nav-anchor_focus; + text-decoration: none; + } + } + } + } + + .bars { + color: $theme-blue-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-blue-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + + .ml-menu { + background-color: $theme-blue-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-blue-legal-bg; + + .copyright { + a { + color: $theme-blue !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-blue !important; + } + + .page-item.active .page-link { + background-color: $theme-blue; + border-color: $theme-blue; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-blue !important; + color: #fff !important; + border-color: $theme-blue !important; + &:hover { + background-color: $theme-blue !important; + color: #fff !important; + } + &:active { + background-color: $theme-blue !important; + color: #fff !important; + } + &:focus { + background-color: $theme-blue !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-blue !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-blue !important; + border: 1px solid $theme-blue !important; + &:hover { + background: $theme-blue !important; + color: #fff !important; + border: 1px solid $theme-blue !important; + } + } + .timelineLabelColor strong { + color: $theme-blue !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-blue; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-blue; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-blue; + } +} +/*Logo Header Background Color*/ +.logo-blue { + .navbar-header { + background-color: $theme-blue; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss new file mode 100644 index 0000000..8c5a655 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-color-variables.scss @@ -0,0 +1,132 @@ +//Theme white +$theme-white: #fff; +$theme-white-active-color: #00bcd4; +$theme-white-sidemenu-active-color: #ffffff; +$theme-white-legal-bg: #2c303b; +$theme-white-bar: #2c303b; +$theme-white-navbar-brand: #2c303b; +$theme-white-navbar-brand_active: #2c303b; +$theme-white-navbar-brand_hover: #2c303b; +$theme-white-navbar-brand_focus: #2c303b; +$theme-white-nav-anchor: #3a2c70; +$theme-white-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-white-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-white-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-white-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-white-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-white-menu-list-active: rgba(0, 0, 0, 0); +$theme-white-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-white-menu-list-submenu: rgba(0, 0, 0, 0); +$theme-white-sidebar-menu-active: #5783c7; +$theme-white-sidebar-menu-hover: #5783c7; + +//Theme Black +$theme-black: #1a202e; +$theme-black-legal-bg: #fff; +$theme-black-bar: #fff; +$theme-black-button-color: #5783c7; +$theme-black-navbar-brand: #fff; +$theme-black-navbar-brand_active: #fff; +$theme-black-navbar-brand_hover: #fff; +$theme-black-navbar-brand_focus: #fff; +$theme-black-nav-anchor: #fff; +$theme-black-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-black-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-black-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-black-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-black-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-black-menu-list-active: rgba(0, 0, 0, 0); +$theme-black-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-black-menu-list-submenu: rgba(0, 0, 0, 0); +$theme-black-sidebar-menu-active: #5783c7; +$theme-black-sidebar-menu-hover: #5783c7; + +//Theme Purple +$theme-purple: #909de4; +$theme-purple-legal-bg: #fff; +$theme-purple-bar: #fff; +$theme-purple-navbar-brand: #fff; +$theme-purple-navbar-brand_active: #fff; +$theme-purple-navbar-brand_hover: #fff; +$theme-purple-navbar-brand_focus: #fff; +$theme-purple-nav-anchor: #fff; +$theme-purple-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-purple-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-purple-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-purple-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-purple-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-purple-menu-list-active: rgba(0, 0, 0, 0); +$theme-purple-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-purple-menu-list-submenu: rgba(0, 0, 0, 0); + +//Theme Blue +$theme-blue: #03a9f3; +$theme-blue-legal-bg: #fff; +$theme-blue-bar: #fff; +$theme-blue-navbar-brand: #fff; +$theme-blue-navbar-brand_active: #fff; +$theme-blue-navbar-brand_hover: #fff; +$theme-blue-navbar-brand_focus: #fff; +$theme-blue-nav-anchor: #fff; +$theme-blue-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-blue-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-blue-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-blue-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-blue-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-blue-menu-list-active: rgba(0, 0, 0, 0); +$theme-blue-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-blue-menu-list-submenu: rgba(0, 0, 0, 0); + +//Theme Cyan +$theme-cyan: #01d8da; +$theme-cyan-legal-bg: #fff; +$theme-cyan-bar: #fff; +$theme-cyan-navbar-brand: #fff; +$theme-cyan-navbar-brand_active: #fff; +$theme-cyan-navbar-brand_hover: #fff; +$theme-cyan-navbar-brand_focus: #fff; +$theme-cyan-nav-anchor: #fff; +$theme-cyan-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-cyan-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-cyan-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-cyan-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-cyan-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-cyan-menu-list-active: rgba(0, 0, 0, 0); +$theme-cyan-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-cyan-menu-list-submenu: rgba(0, 0, 0, 0); + +//Theme Green +$theme-green: #11a37d; +$theme-green-legal-bg: #fff; +$theme-green-bar: #fff; +$theme-green-navbar-brand: #fff; +$theme-green-navbar-brand_active: #fff; +$theme-green-navbar-brand_hover: #fff; +$theme-green-navbar-brand_focus: #fff; +$theme-green-nav-anchor: #fff; +$theme-green-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-green-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-green-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-green-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-green-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-green-menu-list-active: rgba(0, 0, 0, 0); +$theme-green-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-green-menu-list-submenu: rgba(0, 0, 0, 0); + +//Theme Orange +$theme-orange: #f16735; +$theme-orange-legal-bg: #fff; +$theme-orange-bar: #fff; +$theme-orange-navbar-brand: #fff; +$theme-orange-navbar-brand_active: #fff; +$theme-orange-navbar-brand_hover: #fff; +$theme-orange-navbar-brand_focus: #fff; +$theme-orange-nav-anchor: #fff; +$theme-orange-nav-anchor_hover: rgba(0, 0, 0, 0); +$theme-orange-nav-anchor_focus: rgba(0, 0, 0, 0); +$theme-orange-nav-anchor-opened: rgba(0, 0, 0, 0); +$theme-orange-nav-anchor-opened_hover: rgba(0, 0, 0, 0); +$theme-orange-nav-anchor-opened_focus: rgba(0, 0, 0, 0); +$theme-orange-menu-list-active: rgba(0, 0, 0, 0); +$theme-orange-menu-list-toggled: rgba(0, 0, 0, 0); +$theme-orange-menu-list-submenu: rgba(0, 0, 0, 0); diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-cyan.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-cyan.scss new file mode 100644 index 0000000..9117829 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-cyan.scss @@ -0,0 +1,182 @@ +/* + * Document : theme-cyan.scss + * Author : RedStar Template + * Description: This scss file for cyan theme style classes + */ +@import "_theme-color-variables"; + +.theme-cyan { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + .navbar.active { + // background-color: $theme-cyan !important; + background: #4cb8c4; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #0fdbdc, + #1ab5b9 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #0fdbdc, #1ab5b9); + .nav { + > li { + > a { + color: #fff; + } + } + } + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-cyan-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-cyan-nav-anchor_focus; + text-decoration: none; + } + } + } + } + + .bars { + color: $theme-cyan-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-cyan-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + .ml-menu { + background-color: $theme-cyan-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-cyan-legal-bg; + + .copyright { + a { + color: $theme-cyan !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-cyan !important; + } + + .page-item.active .page-link { + background-color: $theme-cyan; + border-color: $theme-cyan; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-cyan !important; + color: #fff !important; + border-color: $theme-cyan !important; + &:hover { + background-color: $theme-cyan !important; + color: #fff !important; + } + &:active { + background-color: $theme-cyan !important; + color: #fff !important; + } + &:focus { + background-color: $theme-cyan !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-cyan !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-cyan !important; + border: 1px solid $theme-cyan !important; + &:hover { + background: $theme-cyan !important; + color: #fff !important; + border: 1px solid $theme-cyan !important; + } + } + .timelineLabelColor strong { + color: $theme-cyan !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-cyan; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-cyan; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-cyan; + } +} +/*Logo Header Background Color*/ +.logo-cyan { + .navbar-header { + background-color: $theme-cyan; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-green.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-green.scss new file mode 100644 index 0000000..bb72d84 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-green.scss @@ -0,0 +1,183 @@ +/* + * Document : theme-green.scss + * Author : RedStar Template + * Description: This scss file for green theme style classes + */ +@import "_theme-color-variables"; + +.theme-green { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + .navbar.active { + // background-color: $theme-green !important; + background: #11998e; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #10bf52, + #11998e + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #10bf52, #11998e); + .nav { + > li { + > a { + color: #fff; + } + } + } + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-green-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-green-nav-anchor_focus; + text-decoration: none; + } + } + } + } + + .bars { + color: $theme-green-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-green-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + + .ml-menu { + background-color: $theme-green-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-green-legal-bg; + + .copyright { + a { + color: $theme-green !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-green !important; + } + + .page-item.active .page-link { + background-color: $theme-green; + border-color: $theme-green; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-green !important; + color: #fff !important; + border-color: $theme-green !important; + &:hover { + background-color: $theme-green !important; + color: #fff !important; + } + &:active { + background-color: $theme-green !important; + color: #fff !important; + } + &:focus { + background-color: $theme-green !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-green !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-green !important; + border: 1px solid $theme-green !important; + &:hover { + background: $theme-green !important; + color: #fff !important; + border: 1px solid $theme-green !important; + } + } + .timelineLabelColor strong { + color: $theme-green !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-green; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-green; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-green; + } +} +/*Logo Header Background Color*/ +.logo-green { + .navbar-header { + background-color: $theme-green; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-orange.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-orange.scss new file mode 100644 index 0000000..6a79c84 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-orange.scss @@ -0,0 +1,183 @@ +/* + * Document : theme-orange.scss + * Author : RedStar Template + * Description: This scss file for orange theme style classes + */ +@import "_theme-color-variables"; + +.theme-orange { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + .navbar.active { + // background-color: $theme-orange !important; + background: #fc4a1a; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #ea581e, + #ff8a61 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #ea581e, #ff8a61); + .nav { + > li { + > a { + color: #fff; + } + } + } + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-orange-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-orange-nav-anchor_focus; + text-decoration: none; + } + } + } + } + + .bars { + color: $theme-orange-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-orange-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + + .ml-menu { + background-color: $theme-orange-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-orange-legal-bg; + + .copyright { + a { + color: $theme-orange !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-orange !important; + } + + .page-item.active .page-link { + background-color: $theme-orange; + border-color: $theme-orange; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-orange !important; + color: #fff !important; + border-color: $theme-orange !important; + &:hover { + background-color: $theme-orange !important; + color: #fff !important; + } + &:active { + background-color: $theme-orange !important; + color: #fff !important; + } + &:focus { + background-color: $theme-orange !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-orange !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-orange !important; + border: 1px solid $theme-orange !important; + &:hover { + background: $theme-orange !important; + color: #fff !important; + border: 1px solid $theme-orange !important; + } + } + .timelineLabelColor strong { + color: $theme-orange !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-orange; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-orange; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-orange; + } +} +/*Logo Header Background Color*/ +.logo-orange { + .navbar-header { + background-color: $theme-orange; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-purple.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-purple.scss new file mode 100644 index 0000000..4f8656c --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-purple.scss @@ -0,0 +1,182 @@ +/* + * Document : theme-purple.scss + * Author : RedStar Template + * Description: This scss file for purple theme style classes + */ +@import "_theme-color-variables"; + +.theme-purple { + .navbar { + background-color: transparent; + .icon-color { + color: #fff; + } + .navbar-nav.navbar-right .user_profile span { + color: #fff; + } + } + .navbar.active { + background: #8e2de2; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #4a00e0, + #8e2de2 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient(to right, #4a00e0, #8e2de2); + .nav { + > li { + > a { + color: #fff; + } + } + } + .collapse-menu-icon .mat-icon { + color: #fff; + } + .collapse-menu-icon .feather { + color: #fff; + } + .nav-notification-icons .mat-icon { + color: #fff; + } + .nav-notification-icons .feather { + color: #fff; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-purple-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-purple-nav-anchor_focus; + text-decoration: none; + } + } + } + } + + .bars { + color: $theme-purple-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-purple-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + + .ml-menu { + background-color: $theme-purple-menu-list-submenu; + } + } + } + + .legal { + background-color: $theme-purple-legal-bg; + + .copyright { + a { + color: $theme-purple !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-purple !important; + } + + .page-item.active .page-link { + background-color: $theme-purple; + border-color: $theme-purple; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + + .btn-primary { + background-color: $theme-purple !important; + color: #fff !important; + border-color: $theme-purple !important; + &:hover { + background-color: $theme-purple !important; + color: #fff !important; + } + &:active { + background-color: $theme-purple !important; + color: #fff !important; + } + &:focus { + background-color: $theme-purple !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-purple !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-purple !important; + border: 1px solid $theme-purple !important; + &:hover { + background: $theme-purple !important; + color: #fff !important; + border: 1px solid $theme-purple !important; + } + } + .timelineLabelColor strong { + color: $theme-purple !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-purple; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-purple; + } + } + } + } + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-purple; + } +} +/*Logo Header Background Color*/ +.logo-purple { + .navbar-header { + background-color: $theme-purple; + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss b/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss new file mode 100644 index 0000000..4651044 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/_theme-white.scss @@ -0,0 +1,231 @@ +/* + * Document : theme-white.scss + * Author : RedStar Template + * Description: This scss file for white theme style classes + */ +@import "_theme-color-variables"; + +.theme-white { + .navbar { + background-color: transparent; + .header-icon .feather { + color: black; + } + } + .navbar-right .user_profile span { + color: rgb(0, 0, 0) !important; + } + .navbar.active { + background-color: $theme-white !important; + .nav { + > li { + > a { + color: #3a2c70; + } + } + } + .collapse-menu-icon .mat-icon { + color: #3a2c70; + } + .nav-notification-icons .mat-icon { + color: #3a2c70; + } + } + + .navbar-brand { + color: $theme-white-navbar-brand; + + &:hover { + color: $theme-white-navbar-brand_hover; + } + + &:active { + color: $theme-white-navbar-brand_active; + } + + &:focus { + color: $theme-white-navbar-brand_focus; + } + } + + .nav { + > li { + > a { + &:hover { + background-color: $theme-white-nav-anchor_hover; + text-decoration: none; + } + + &:focus { + background-color: $theme-white-nav-anchor_focus; + text-decoration: none; + } + } + } + + .open { + > a { + background-color: $theme-white-nav-anchor-opened; + + &:hover { + background-color: $theme-white-nav-anchor-opened_hover; + } + + &:focus { + background-color: $theme-white-nav-anchor-opened_focus; + } + } + } + } + + .bars { + color: $theme-white-bar; + } + + .sidebar { + .menu { + .list { + li { + &.active { + background-color: $theme-white-menu-list-active; + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + i, + span { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + } + } + } + + .ml-menu { + background-color: $theme-white-menu-list-submenu; + + // li.active a:not(.menu-toggle):before { + // content: "\f068"; + // font-family: "Font Awesome 5 Free"; + // font-size: 11px; + // display: block; + // width: 7px; + // height: 7px; + // position: absolute; + // left: 10%; + // font-weight: 900; + // } + } + } + } + + .legal { + background-color: $theme-white-legal-bg; + + .copyright { + a { + color: $theme-white !important; + } + } + } + } + + .breadcrumb li a { + color: $theme-white-active-color !important; + } + .page-item.active .page-link { + background-color: $theme-white-active-color; + border-color: $theme-white-active-color; + border-radius: 50%; + margin: 5px; + box-shadow: 0 4px 5px 0 #d4d8da, 0 1px 10px 0 #d4d8da, + 0 2px 4px -1px #d4d8da; + padding: 0px 12px; + min-width: 30px; + line-height: 30px; + color: #ffffff; + text-transform: uppercase; + } + + .btn-primary { + background-color: $theme-white-active-color !important; + color: #fff !important; + border-color: $theme-white-active-color !important; + &:hover { + background-color: $theme-white-active-color !important; + color: #fff !important; + } + &:active { + background-color: $theme-white-active-color !important; + color: #fff !important; + } + &:focus { + background-color: $theme-white-active-color !important; + color: #fff !important; + } + &:disabled { + background-color: $theme-white-active-color !important; + color: #fff !important; + } + } + .btn-outline-primary { + background: 0 0 !important; + color: $theme-white-bar !important; + border: 1px solid $theme-white-active-color !important; + &:hover { + background: $theme-white-active-color !important; + color: #fff !important; + border: 1px solid $theme-white !important; + } + } + .timelineLabelColor strong { + color: $theme-white-active-color !important; + } + .top-sidebar { + .horizontal-menu { + li { + &.active { + > a { + color: $theme-white-active-color; + } + } + a { + -moz-transition: all 0.3s; + -o-transition: all 0.3s; + -webkit-transition: all 0.3s; + transition: all 0.3s; + &:hover { + color: $theme-white-active-color; + } + } + } + } + } + .demo-choose-skin li.actived:after { + color: #000; + } + + .nav-tabs > li > a:before { + border-bottom: 2px solid $theme-white-active-color; + } + .search-box input#search { + color: gray; + background: #edecec; + } + .settingSidebar ul.choose-theme li.active div::after { + color: #000; + } +} +/*Logo Header Background Color*/ +.logo-white { + .navbar-header { + background-color: $theme-white; + + .logo-name { + color: #000; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/theme/all-themes.scss b/MyOffice.SPA/src/assets/scss/theme/all-themes.scss new file mode 100644 index 0000000..c481d55 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/theme/all-themes.scss @@ -0,0 +1,31 @@ +/* + * Document : all-themes.scss + * Author : RedStar Template + * Description: This scss file for import all theme style scss files + + [1. Purple Theme] + [2. Blue Theme] + [3. Cyan Theme] + [4. Green Theme] + [5. Orange Theme] + [6. Black Theme] + [7. White Theme] + [8. Dark Template Theme] + */ + +/* [1. Purple Theme] */ +@import "theme-purple"; +/* [2. Blue Theme] */ +@import "theme-blue"; +/* [3. Cyan Theme] */ +@import "theme-cyan"; +/* [4. Green Theme] */ +@import "theme-green"; +/* [5. Orange Theme] */ +@import "theme-orange"; +/* [6. Black Theme] */ +@import "theme-black"; +/* [7. White Theme] */ +@import "theme-white"; +/* [8. Dark Template Theme] */ +@import "dark"; diff --git a/MyOffice.SPA/src/assets/scss/ui/_alerts.scss b/MyOffice.SPA/src/assets/scss/ui/_alerts.scss new file mode 100644 index 0000000..96edb3e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_alerts.scss @@ -0,0 +1,42 @@ +/* + * Document : alert.scss + * Author : RedStar Template + * Description: This scss file for alert style classes + */ +.alert { + @include border-radius(0); + @include box-shadow(none); + border: none; + color: #fff !important; + + .alert-link { + color: #fff; + text-decoration: underline; + font-weight: bold; + } +} + +.alert-success { + background-color: rgba(24, 206, 15, 0.8); +} + +.alert-info { + background-color: rgba(44, 168, 255, 0.8); +} + +.alert-warning { + background-color: rgba(255, 178, 54, 0.8); +} + +.alert-danger { + background-color: rgba(255, 54, 54, 0.8); +} + +.alert-dismissible { + .close { + color: #fff; + opacity: 1; + border: none; + text-shadow: none; + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss b/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss new file mode 100644 index 0000000..10db563 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_badgelistgroupitem.scss @@ -0,0 +1,238 @@ +/* + * Document : badgelistgroupitem.scss + * Author : RedStar Template + * Description: This scss file for badge style classes + */ +.badge { + padding: 5px 8px; + line-height: 12px; + border: 1px solid; + font-weight: 400; + font-size: 13px; +} + +.list-group-item { + @include border-radius(0); + @include transition(0.5s); +} + +.list-group { + .active, + .list-group-item.active { + background-color: #2196f3; + border-color: #2196f3; + + &:hover, + &:focus, + &:active { + background-color: #2196f3; + border-color: #2196f3; + } + + .list-group-item-text { + color: #dfe9f1; + font-size: 13px; + + &:hover, + &:active, + &:focus { + color: #dfe9f1; + } + } + } + a, + button { + &.list-group-item { + color: #555; + } + &.list-group-item.active { + color: #dfe9f1; + } + } + + .list-group-item.active { + &:hover, + &:focus, + &:active { + .list-group-item-text { + color: #dfe9f1; + } + } + } + + .list-group-item { + &:first-child, + &:last-child { + @include border-radius(0); + } + + .list-group-item-heading { + font-weight: bold; + font-size: 17px; + } + text-align: left; + &:focus, + &:hover { + background-color: #f5f5f5; + } + } + + .list-group-item-success { + background-color: #2b982b; + border: none; + color: #fff; + + &:hover, + &:focus { + background-color: #2b982b; + color: #fff; + opacity: 0.8; + } + } + + .list-group-item-info { + background-color: #00b0e4; + border: none; + color: #fff; + + &:hover, + &:focus { + background-color: #00b0e4; + color: #fff; + opacity: 0.8; + } + } + + .list-group-item-warning { + background-color: #ff9600; + border: none; + color: #fff; + + &:hover, + &:focus { + background-color: #ff9600; + color: #fff; + opacity: 0.8; + } + } + + .list-group-item-danger { + background-color: #fb483a; + border: none; + color: #fff; + + &:hover, + &:focus { + background-color: #fb483a; + color: #fff; + opacity: 0.8; + } + } + + @each $key, $val in $colors { + .pl-#{$key} { + stroke: $val; + } + + .list-group-bg-#{$key} { + background-color: $val; + border: none; + color: #fff; + + &:hover, + &:focus { + background-color: $val; + color: #fff; + opacity: 0.8; + } + } + } +} +span.badge { + min-width: auto; + float: none; + font-size: 13px; +} +.list-group span.badge { + float: right; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.badge-solid-red { + color: #f11541; + background-color: rgba(241, 21, 65, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-purple { + color: #6f42c1; + background-color: rgba(111, 66, 193, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-green { + color: #198754; + background-color: rgba(25, 135, 84, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-blue { + color: #0d6efd; + background-color: rgba(13, 110, 253, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-pink { + color: #fd0dfd; + background-color: rgba(253, 13, 253, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-orange { + color: #fd7e14; + background-color: rgba(253, 126, 20, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-cyan { + color: #0dcaf0; + background-color: rgba(13, 202, 240, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} +.badge-solid-brown { + color: #964b00; + background-color: rgba(150, 75, 0, 0.15); + border: none; + padding: 5px 12px; + font-weight: 500; + line-height: 1.2; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_buttons.scss b/MyOffice.SPA/src/assets/scss/ui/_buttons.scss new file mode 100644 index 0000000..a7a2c5e --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_buttons.scss @@ -0,0 +1,23 @@ +/* + * Document : _buttons.scss + * Author : RedStar Template + * Description: This scss file for button style classes + */ +.example-button-row button, +.example-button-row a { + margin-right: 8px; +} + +.btn:focus, +.btn.focus { + box-shadow: none; +} + +.btn-space { + margin-right: 10px !important; +} +.big-button { + width: 200px !important; + min-width: unset !important; + height: 45px; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_card.scss b/MyOffice.SPA/src/assets/scss/ui/_card.scss new file mode 100644 index 0000000..f5fb0be --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_card.scss @@ -0,0 +1,320 @@ +/* + * Document : _card.scss + * Author : RedStar Template + * Description: This scss file for card style classes + */ +.card { + background: #fff; + min-height: 50px; + position: relative; + margin-bottom: 24px; + border: 1px solid #f2f4f9; + border-radius: 10px; + box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); + -webkit-box-shadow: 0 0 10px 0 rgba(183, 192, 206, 0.2); + + .card-inside-title { + margin-top: 25px; + margin-bottom: 15px; + display: block; + font-size: 15px; + color: #000; + + small { + color: #999; + display: block; + font-size: 11px; + margin-top: 5px; + + a { + color: #777; + font-weight: bold; + } + } + } + + .card-inside-title:first-child { + margin-top: 0; + } + + .bg-red, + .bg-pink, + .bg-purple, + .bg-indigo, + .bg-blue, + .bg-cyan, + .bg-teal, + .bg-green, + .bg-yellow, + .bg-orange, + .bg-deep-orange, + .bg-brown, + .bg-grey, + .bg-black { + border-bottom: none !important; + color: #fff !important; + + h2, + small, + .material-icons { + color: #fff !important; + } + + .badge { + background-color: #fff; + color: #555; + } + } + + .header { + position: relative; + display: flex; + width: 100%; + color: #555; + padding: 10px 15px; + line-height: 30px; + border-bottom: 1px solid; + border-color: rgba(82, 63, 105, 0.06); + + .header-dropdown { + position: absolute; + top: 0px; + right: 0px; + list-style: none; + + .dropdown-menu { + li { + display: block !important; + } + } + + li { + display: inline-block; + } + + i { + font-size: 20px; + color: #999; + @include transition(all 0.5s); + + &:hover { + color: #000; + } + } + } + + h2 { + margin: 0; + color: #5b626b; + font-size: 17px; + line-height: 28px; + padding-right: 10px; + font-weight: 500; + + small { + display: block; + font-size: 12px; + margin-top: 5px; + color: #999; + line-height: 15px; + + a { + font-weight: bold; + color: #777; + } + } + } + + .col-xs-12 { + h2 { + margin-top: 5px; + } + } + } + + .body { + font-size: 14px; + color: #555; + padding: 15px; + + @for $i from 1 through 12 { + .col-xs-#{$i}, + .col-sm-#{$i}, + .col-md-#{$i}, + .col-lg-#{$i} { + margin-bottom: 20px; + } + } + } + .list-body { + padding: 0px 10px; + } + &.card-statistic-1 .card-header, + &.card-statistic-2 .card-header { + border-color: transparent; + padding-bottom: 0; + height: auto; + min-height: auto; + display: block; + } + + &.card-statistic-1 .card-icon { + width: 30px; + height: 30px; + margin: 10px 0px 0px 20px; + border-radius: 3px; + line-height: 78px; + text-align: center; + float: left; + font-size: 30px; + } + + &.card-statistic-1 .card-header h4, + &.card-statistic-2 .card-header h4 { + line-height: 1.2; + color: color(muted); + } + + &.card-statistic-1 .card-body, + &.card-statistic-2 .card-body { + padding-top: 0; + } + + &.card-statistic-1 .card-body, + &.card-statistic-2 .card-body { + font-size: 26px; + font-weight: 700; + color: color(fontdark); + padding-bottom: 0; + } + + &.card-statistic-1, + &.card-statistic-2 { + display: inline-block; + width: 100%; + } + + &.card-statistic-1 .card-icon, + &.card-statistic-2 .card-icon { + width: 80px; + height: 80px; + margin: 10px; + border-radius: 3px; + line-height: 94px; + text-align: center; + float: left; + border-radius: 50px; + margin-right: 15px; + + .ion, + .fas, + .far, + .fab, + .fal { + font-size: 22px; + color: #fff; + } + } + + &.card-statistic-1 .card-icon { + line-height: 90px; + } + + &.card-statistic-2 .card-icon { + width: 50px; + height: 50px; + line-height: 50px; + font-size: 22px; + margin: 25px; + box-shadow: 5px 3px 10px 0 rgba(21, 15, 15, 0.3); + border-radius: 10px; + background: #6777ef; + } + &.card-statistic-2 .card-icon-only { + font-size: 35px; + margin: 20px; + } + + &.card-statistic-1 .card-header, + &.card-statistic-2 .card-header { + padding-bottom: 0; + padding-top: 25px; + } + + &.card-statistic-2 .card-header + .card-body, + &.card-statistic-2 .card-body + .card-header { + padding-top: 0; + } + + &.card-statistic-1 .card-header h4, + &.card-statistic-2 .card-header h4 { + font-weight: 600; + font-size: 13px; + letter-spacing: 0.5px; + } + + &.card-statistic-1 .card-header h4 { + margin-bottom: 0; + } + + &.card-statistic-2 .card-header h4 { + text-transform: none; + margin-bottom: 0; + } + + &.card-statistic-1 .card-body { + font-size: 20px; + } + + &.card-statistic-2 { + .card-chart { + margin-left: -10px; + margin-right: -1px; + margin-bottom: -7px; + + canvas { + height: 70px !important; + } + } + .card-right { + float: right; + margin: 15px 15px 15px 0px; + } + } +} +.plain-card { + box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1); + padding: 20px; + border-radius: 10px; + background: #fff; + overflow: hidden; + margin: 0.5rem 0 1rem 0; +} +.card-inner .progress { + height: 10px; + margin: 0px; +} +.col-block { + margin-left: 5px; +} +.card-height-100 { + height: 100px; +} +.doc-card-title { + color: #00bdf2; + font-size: 16px; +} +.doc-card-image { + background: #fff; + position: inherit; + padding: 2px; + box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.2); +} +.card-spacing { + padding-right: 0px; +} +.card-bnner { + background: white; + padding: 15px; + border-radius: 10px; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss b/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss new file mode 100644 index 0000000..2aa06c8 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_ckeditor.scss @@ -0,0 +1,18 @@ +.ck.ck-content ul, +.ck.ck-content ul li { + list-style-type: inherit; +} + +.ck.ck-content ul { + /* Default user agent stylesheet, you can change it to your needs. */ + padding-left: 40px; +} +.ck.ck-content ol, +.ck.ck-content ol li { + list-style-type: decimal; +} + +.ck.ck-content ol { + /* Default user agent stylesheet, you can change it to your needs. */ + padding-left: 40px; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_collapse.scss b/MyOffice.SPA/src/assets/scss/ui/_collapse.scss new file mode 100644 index 0000000..3de6549 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_collapse.scss @@ -0,0 +1,16 @@ +/* + * Document : _collapse.scss + * Author : RedStar Template + * Description: This scss file for collapse style classes + */ +.collapse, +.collapse.in, +.collapsing { + .well { + @include border-radius(0); + margin-bottom: 0; + } + &.show { + display: block; + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss b/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss new file mode 100644 index 0000000..06d4c71 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_dialogs.scss @@ -0,0 +1,29 @@ +/* + * Document : _dialogs.scss + * Author : RedStar Template + * Description: This scss file for dialogs style classes + */ +.sweet-alert { + @include border-radius(0 !important); + + p { + font-size: 14px !important; + } + + .sa-input-error { + top: 23px !important; + right: 13px !important; + } + + h2 { + font-size: 18px !important; + margin: 0 0 5px 0 !important; + line-height: 40px; + } + + button { + font-size: 15px !important; + @include border-radius(0 !important); + padding: 5px 20px !important; + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_expansion.scss b/MyOffice.SPA/src/assets/scss/ui/_expansion.scss new file mode 100644 index 0000000..4dfda30 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_expansion.scss @@ -0,0 +1,19 @@ +/* + * Document : _expansion + * Author : RedStar Template + * Description: This scss file for collapse style classes + */ + +.example-headers-align .mat-expansion-panel-header-title, +.example-headers-align .mat-expansion-panel-header-description { + flex-basis: 0; +} + +.example-headers-align .mat-expansion-panel-header-description { + justify-content: space-between; + align-items: center; +} + +.example-headers-align .mat-form-field + .mat-form-field { + margin-left: 8px; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_listItems.scss b/MyOffice.SPA/src/assets/scss/ui/_listItems.scss new file mode 100644 index 0000000..aaa37bc --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_listItems.scss @@ -0,0 +1,26 @@ +.icon-box { + position: relative; + line-height: 1; + padding: 8px; + border-radius: 5px; +} +.icon-box-orange { + background-color: #ffe3db; +} +.icon-box-green { + background-color: #e1fbe2; +} +.icon-box-purple { + background-color: #dfceff; +} +.icon-box-blue { + background-color: #cbe8ff; +} +.icon-box-red { + background-color: #ffe5e4; +} +.amount-section { + .material-icons { + font-size: 10px; + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss b/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss new file mode 100644 index 0000000..f416071 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_mediaobject.scss @@ -0,0 +1,23 @@ +/* + * Document : _mediaobject.scss + * Author : RedStar Template + * Description: This scss file for media object style classes + */ +.media { + margin-bottom: 25px; + margin-top: 15px; + + .media-left { + padding-right: 10px; + } + .media-body { + color: #777; + font-size: 13px; + + .media-heading { + font-size: 16px; + font-weight: bold; + color: #333; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_modals.scss b/MyOffice.SPA/src/assets/scss/ui/_modals.scss new file mode 100644 index 0000000..6e9d8ed --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_modals.scss @@ -0,0 +1,109 @@ +/* + * Document : _modals.scss + * Author : RedStar Template + * Description: This scss file for modals style classes + */ +.modal { + background-color: rgba(238, 238, 238, 0.41); + //padding: 100px 0 0; + max-height: 100%; + width: 100%; + .modal-header { + border: none; + padding: 0px; + border-bottom: 1px solid #eee; + + .modal-title { + font-weight: bold; + font-size: 16px; + } + } + + .modal-content { + border-radius: 10px; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.31) !important; + border: none; + padding: 10px; + + .modal-body { + color: #777; + padding: 15px 25px; + } + } + + .modal-footer { + border: none; + background-color: transparent; + .btn { + margin: 10px; + } + } +} +.addContainer { + display: flex; + flex-direction: column; + overflow: hidden; + .form { + display: flex; + padding-top: 6px; + } + + .mat-form-field { + flex-grow: 1; + } + .modalHeader img { + border-radius: 50%; + } +} + +.modalHeader { + display: flex; + align-items: flex-start; + // justify-content: space-between; + padding: 0px 10px 0px 10px; + margin: 10px 10px 0px 10px; + .modal-about { + padding: 5px; + font-weight: 500; + font-size: 16px; + } +} +.modal-close-button { + background-color: transparent !important; + box-shadow: none !important; + color: #161d38; + right: 10px; + position: absolute !important; +} + +@each $key, $val in $colors { + .modal-col-#{$key} { + background-color: $val; + + .modal-body, + .modal-title { + color: #fff !important; + } + + .modal-footer { + background-color: rgba(0, 0, 0, 0.12); + + .btn-link { + color: #fff !important; + + &:hover, + &:active, + &:focus { + background-color: rgba(0, 0, 0, 0.12); + } + } + } + } +} +.cdk-overlay-connected-position-bounding-box { + z-index: 1052 !important; +} +.mat-dialog-content { + margin: 0px !important; + padding: 0px !important; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss b/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss new file mode 100644 index 0000000..0246382 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_pageloader.scss @@ -0,0 +1,30 @@ +/* + * Document : _pageloader.scss + * Author : RedStar Template + * Description: This scss file for page loader style classes + */ +.page-loader-wrapper { + z-index: 99999999; + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + width: 100%; + height: 100%; + background: #eee; + overflow: hidden; + text-align: center; + + p { + font-size: 13px; + margin-top: 10px; + font-weight: bold; + color: #444; + } + + .loader { + position: relative; + // top: calc(50% - 30px); + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_pagination.scss b/MyOffice.SPA/src/assets/scss/ui/_pagination.scss new file mode 100644 index 0000000..d07c9a2 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_pagination.scss @@ -0,0 +1,169 @@ +/* + * Document : _pagination.scss + * Author : RedStar Template + * Description: This scss file for pagination style classes + */ +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; + + li { + display: inline; + + > a { + @include border-radius(0); + border: none; + background-color: transparent; + color: #222; + font-weight: bold; + display: inline-block; + padding: 5px 14px; + } + + a:focus, + a:active { + background-color: transparent; + } + } + .previous { + > a, + > span { + float: left; + } + } + .next { + > a, + > span { + float: right; + } + } +} + +.pagination { + margin: 20px 0; + + .disabled { + a, + a:hover, + a:focus, + a:active { + color: #bbb; + } + } + + li.active { + background-color: transparent !important; + a { + background-color: #ffc107; + border-color: #ffc107; + color: #ffffff; + border-radius: 50%; + box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.2); + } + } + + li { + @include border-radius(0); + + // a:focus, + // a:active { + // background-color: transparent; + // color: #555; + // } + } + + > li { + > a { + border: none; + font-weight: bold; + color: #555; + font-size: 14px; + margin: 0px 3px; + color: gray; + margin: 5px; + border-radius: 50%; + color: gray; + min-width: 30px; + text-transform: uppercase; + padding: 0.5rem 0.75rem; + line-height: 1.25; + } + } + > li { + > a:hover { + font-weight: bold; + background-color: transparent; + color: #8c8b8b; + border-radius: 50%; + font-size: 14px; + } + } + + > li:first-child, + > li:last-child { + > a { + width: auto; + height: 32px; + @include border-radius(0); + + .material-icons { + position: relative; + bottom: 0px; + } + } + } +} + +.pagination-sm { + > li:first-child, + > li:last-child { + > a { + width: 28px; + height: 28px; + + .material-icons { + position: relative; + top: 4px; + left: -6px; + font-size: 20px; + } + } + } + > li > a, + > li > span { + padding: 5px 10px; + font-size: 12px; + } +} + +.pagination-lg { + > li:first-child, + > li:last-child { + > a { + width: 44px; + height: 44px; + + .material-icons { + font-size: 30px; + position: relative; + top: 0px; + left: -10px; + } + } + } + > li > a, + > li > span { + padding: 10px 16px; + font-size: 18px; + } +} +.page-link:focus, +.page-link:hover { + color: #65686b; + text-decoration: none; + background-color: #e3eaf1; + border-color: #e3eaf1; + border-radius: 50%; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_panels.scss b/MyOffice.SPA/src/assets/scss/ui/_panels.scss new file mode 100644 index 0000000..8ecbc63 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_panels.scss @@ -0,0 +1,149 @@ +/* + * Document : _panels.scss + * Author : RedStar Template + * Description: This scss file for panels style classes + */ +.panel-group { + @each $key, $val in $colors { + .panel-col-#{$key} { + border: 1px solid $val; + + .panel-title { + background-color: $val !important; + color: #fff; + } + + .panel-body { + border-top-color: transparent !important; + } + } + } + + .panel { + @include border-radius(0); + margin-top: 5px; + + .panel-title { + margin-bottom: 0; + font-size: 16px; + .material-icons { + float: left; + line-height: 16px; + margin-right: 8px; + } + > a, + > small, + > .small, + > small > a, + > .small > a { + color: #fff; + } + } + + .panel-heading { + padding: 0; + @include border-radius(0); + + a { + display: block; + padding: 10px 15px; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } + } + } + + .panel-body { + color: #555; + border-top: 1px solid #ddd; + padding: 15px; + } + } + + .panel-primary { + border: none; + + .panel-title { + background-color: #f5f5f5; + a { + color: #757575; + font-weight: 400; + font-size: 16px; + } + } + } + + .panel-success { + border: 1px solid #2b982b; + + .panel-title { + background-color: #2b982b; + color: #fff; + } + } + + .panel-warning { + border: 1px solid #ff9600; + + .panel-title { + background-color: #ff9600; + color: #fff; + } + } + + .panel-danger { + border: 1px solid #fb483a; + + .panel-title { + background-color: #fb483a; + color: #fff; + } + } +} + +.full-body { + @each $key, $val in $colors { + .panel-col-#{$key} { + .panel-body { + border-top-color: #fff !important; + background-color: $val; + color: #fff; + } + } + } + + .panel-primary { + .panel-body { + border-top-color: #fff !important; + background-color: #7861a9; + color: #fff; + } + } + + .panel-success { + .panel-body { + border-top-color: #fff !important; + background-color: #2b982b; + color: #fff; + } + } + + .panel-warning { + .panel-body { + border-top-color: #fff !important; + background-color: #ff9600; + color: #fff; + } + } + + .panel-danger { + .panel-body { + border-top-color: #fff !important; + background-color: #fb483a; + color: #fff; + } + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss b/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss new file mode 100644 index 0000000..7a850c8 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_preloaders.scss @@ -0,0 +1,378 @@ +/* + * Document : _preloaders.scss + * Author : RedStar Template + * Description: This scss file for preloaders style classes + */ +.md-preloader { + @each $key, $val in $colors { + .pl-#{$key} { + stroke: $val; + } + } +} + +.preloader { + display: inline-block; + position: relative; + width: 50px; + height: 50px; + -webkit-animation: container-rotate 1568ms linear infinite; + -moz-animation: container-rotate 1568ms linear infinite; + -o-animation: container-rotate 1568ms linear infinite; + animation: container-rotate 1568ms linear infinite; + + &.pl-size-xl { + width: 75px; + height: 75px; + } + + &.pl-size-l { + width: 60px; + height: 60px; + } + + &.pl-size-md { + width: 50px; + height: 50px; + } + + &.pl-size-sm { + width: 40px; + height: 40px; + } + + &.pl-size-xs { + width: 25px; + height: 25px; + } +} + +.spinner-layer { + position: absolute; + width: 100%; + height: 100%; + border-color: #f44336; + -ms-opacity: 1; + opacity: 1; + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) + infinite both; + -moz-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) + infinite both; + -o-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + + @each $key, $val in $colors { + &.pl-#{$key} { + border-color: $val; + } + } +} + +.right { + float: right !important; +} + +.gap-patch { + position: absolute; + top: 0; + left: 45%; + width: 10%; + height: 100%; + overflow: hidden; + border-color: inherit; + + &.circle { + width: 1000%; + left: -450%; + } +} + +.circle-clipper { + display: inline-block; + position: relative; + width: 50%; + height: 100%; + overflow: hidden; + border-color: inherit; + + .circle { + width: 200%; + height: 100%; + border-width: 3px; + border-style: solid; + border-color: inherit; + border-bottom-color: transparent !important; + -ms-border-radius: 50%; + border-radius: 50%; + -webkit-animation: none; + animation: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; + } + + &.left { + .circle { + left: 0; + border-right-color: transparent !important; + -webkit-transform: rotate(129deg); + -moz-transform: rotate(129deg); + -ms-transform: rotate(129deg); + -o-transform: rotate(129deg); + transform: rotate(129deg); + -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + -moz-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + -o-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + } + } + + &.right { + .circle { + left: -100%; + border-left-color: transparent !important; + -webkit-transform: rotate(-129deg); + -moz-transform: rotate(-129deg); + -ms-transform: rotate(-129deg); + -o-transform: rotate(-129deg); + transform: rotate(-129deg); + -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + -moz-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite + both; + -o-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + } + } +} + +@-webkit-keyframes container-rotate { + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes container-rotate { + to { + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@-webkit-keyframes fill-unfill-rotate { + 12.5% { + -webkit-transform: rotate(135deg); + transform: rotate(135deg); + } + + 25% { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + } + + 37.5% { + -webkit-transform: rotate(405deg); + transform: rotate(405deg); + } + + 50% { + -webkit-transform: rotate(540deg); + transform: rotate(540deg); + } + + 62.5% { + -webkit-transform: rotate(675deg); + transform: rotate(675deg); + } + + 75% { + -webkit-transform: rotate(810deg); + transform: rotate(810deg); + } + + 87.5% { + -webkit-transform: rotate(945deg); + transform: rotate(945deg); + } + + to { + -webkit-transform: rotate(1080deg); + transform: rotate(1080deg); + } +} + +@keyframes fill-unfill-rotate { + 12.5% { + transform: rotate(135deg); + } + + 25% { + transform: rotate(270deg); + } + + 37.5% { + transform: rotate(405deg); + } + + 50% { + transform: rotate(540deg); + } + + 62.5% { + transform: rotate(675deg); + } + + 75% { + transform: rotate(810deg); + } + + 87.5% { + transform: rotate(945deg); + } + + to { + transform: rotate(1080deg); + } +} + +@-webkit-keyframes left-spin { + from { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); + } + + 50% { + -webkit-transform: rotate(-5deg); + -moz-transform: rotate(-5deg); + -ms-transform: rotate(-5deg); + -o-transform: rotate(-5deg); + transform: rotate(-5deg); + } + + to { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); + } +} + +@keyframes left-spin { + from { + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + -webkit-transform: rotate(130deg); + transform: rotate(130deg); + } + + 50% { + -moz-transform: rotate(-5deg); + -ms-transform: rotate(-5deg); + -o-transform: rotate(-5deg); + -webkit-transform: rotate(-5deg); + transform: rotate(-5deg); + } + + to { + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + -webkit-transform: rotate(130deg); + transform: rotate(130deg); + } +} + +@-webkit-keyframes right-spin { + from { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); + } + + 50% { + -webkit-transform: rotate(5deg); + -moz-transform: rotate(5deg); + -ms-transform: rotate(5deg); + -o-transform: rotate(5deg); + transform: rotate(5deg); + } + + to { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); + } +} + +@-moz-keyframes right-spin { + from { + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } + + 50% { + -moz-transform: rotate(5deg); + -ms-transform: rotate(5deg); + -o-transform: rotate(5deg); + -webkit-transform: rotate(5deg); + transform: rotate(5deg); + } + + to { + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } +} + +@keyframes right-spin { + from { + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } + + 50% { + -moz-transform: rotate(5deg); + -ms-transform: rotate(5deg); + -o-transform: rotate(5deg); + -webkit-transform: rotate(5deg); + transform: rotate(5deg); + } + + to { + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss b/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss new file mode 100644 index 0000000..c597502 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_progressbars.scss @@ -0,0 +1,126 @@ +/* + * Document : _progressbars.scss + * Author : RedStar Template + * Description: This scss file for progress bars style classes + */ + +.mat-mdc-progress-bar { + &.progress-xs { + height: 4px; + } + &.progress-s { + height: 5px; + } + &.progress-m { + height: 10px; + .mdc-linear-progress__bar-inner { + border-top-width: var(--mdc-linear-progress-track-height, 10px); + } + } + &.progress-l { + height: 15px; + .mdc-linear-progress__bar-inner { + border-top-width: 15px; + } + } + + &.progress-round { + border-radius: 7px; + } + + &.green-progress .mdc-linear-progress__bar-inner { + border-color: #0af30a !important; + } + &.sky-progress .mdc-linear-progress__bar-inner { + border-color: #248afd !important; + } + &.orange-progress .mdc-linear-progress__bar-inner { + border-color: #ffc100 !important; + } + &.red-progress .mdc-linear-progress__bar-inner { + border-color: #ff4747 !important; + } + + &.l-green-progress .mdc-linear-progress__bar-inner { + background: #11998e; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #38ef7d, + #11998e + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #38ef7d, + #11998e + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + } + &.l-sky-progress .mat-progress-bar-fill::after { + background: #36d1dc; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #5b86e5, + #36d1dc + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #5b86e5, + #36d1dc + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + } + &.l-orange-progress .mat-progress-bar-fill::after { + background: #f12711; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #f5af19, + #f12711 + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #f5af19, + #f12711 + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + } + &.l-red-progress .mat-progress-bar-fill::after { + background: #ff416c; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #ff4b2b, + #ff416c + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #ff4b2b, + #ff416c + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + } + &.l-purple-progress .mat-progress-bar-fill::after { + background: #7f00ff; /* fallback for old browsers */ + background: -webkit-linear-gradient( + to right, + #e100ff, + #7f00ff + ); /* Chrome 10-25, Safari 5.1-6 */ + background: linear-gradient( + to right, + #e100ff, + #7f00ff + ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + } + + &.progress-shadow { + box-shadow: 0.4rem 0.4rem 0.8rem rgb(0 0 0 / 10%); + } +} + +.progress-list { + position: relative; + + .status { + display: inline-block; + font-size: 12px; + padding: 6px; + position: absolute; + right: 0; + top: 0; + } +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_slider.scss b/MyOffice.SPA/src/assets/scss/ui/_slider.scss new file mode 100644 index 0000000..a7b85e1 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_slider.scss @@ -0,0 +1,3 @@ +mat-slider { + width: 300px; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss b/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss new file mode 100644 index 0000000..c845b43 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_snackbar.scss @@ -0,0 +1,19 @@ +.mat-mdc-snack-bar-container.snackbar-success .mdc-snackbar__surface { + background-color: rgba(24, 206, 15, 0.8); + color: #ffffff; +} + +.mat-mdc-snack-bar-container.snackbar-info .mdc-snackbar__surface { + background-color: rgba(44, 168, 255, 0.8); + color: #ffffff; +} + +.mat-mdc-snack-bar-container.snackbar-warning .mdc-snackbar__surface { + background-color: rgba(255, 230, 0, 0.8); + color: #ffffff; +} + +.mat-mdc-snack-bar-container.snackbar-danger .mdc-snackbar__surface { + background-color: rgba(255, 0, 0, 0.8); + color: #ffffff; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_tabs.scss b/MyOffice.SPA/src/assets/scss/ui/_tabs.scss new file mode 100644 index 0000000..ff4da90 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_tabs.scss @@ -0,0 +1,29 @@ +.example-small-box, +.example-large-box { + display: flex; + align-items: center; + justify-content: center; + margin: 16px; + padding: 16px; + border-radius: 8px; +} + +.example-small-box { + height: 100px; + width: 100px; +} + +.example-large-box { + height: 300px; + width: 300px; +} +.appointment-tab-box { + background-color: #eff1f7; + width: 100%; + padding: 10px; +} +.tab-header { + color: #555; + padding: 15px; + position: relative; +} diff --git a/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss b/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss new file mode 100644 index 0000000..56e4d01 --- /dev/null +++ b/MyOffice.SPA/src/assets/scss/ui/_tooltippopovers.scss @@ -0,0 +1,30 @@ +/* + * Document : _tooltippopovers.scss + * Author : RedStar Template + * Description: This scss file for tooltip pop overs style classes + */ +.tooltip { + font-size: 13px; + + .tooltip-inner { + @include border-radius(0); + } +} + +.popover { + @include border-radius(0); + border: 1px solid rgba(0, 0, 0, 0.08); + + .popover-title { + font-weight: bold; + @include border-radius(0); + background-color: #e9e9e9; + border-bottom: 1px solid #ddd; + } + + .popover-content { + font-size: 13px; + color: #777; + @include border-radius(0); + } +} diff --git a/MyOffice.SPA/src/favicon.ico b/MyOffice.SPA/src/favicon.ico new file mode 100644 index 0000000..997406a Binary files /dev/null and b/MyOffice.SPA/src/favicon.ico differ diff --git a/MyOffice.SPA/src/index.html b/MyOffice.SPA/src/index.html new file mode 100644 index 0000000..89b374c --- /dev/null +++ b/MyOffice.SPA/src/index.html @@ -0,0 +1,21 @@ + + + + + MyOffice + + + + + + + + + + + diff --git a/MyOffice.SPA/src/main.ts b/MyOffice.SPA/src/main.ts new file mode 100644 index 0000000..45e7c01 --- /dev/null +++ b/MyOffice.SPA/src/main.ts @@ -0,0 +1,7 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/MyOffice.SPA/src/polyfills.ts b/MyOffice.SPA/src/polyfills.ts new file mode 100644 index 0000000..f85b963 --- /dev/null +++ b/MyOffice.SPA/src/polyfills.ts @@ -0,0 +1,53 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/MyOffice.SPA/src/proxy.conf.js b/MyOffice.SPA/src/proxy.conf.js new file mode 100644 index 0000000..f54007d --- /dev/null +++ b/MyOffice.SPA/src/proxy.conf.js @@ -0,0 +1,15 @@ +const PROXY_CONFIG = [ + { + context: [ + '/api', + '/authorize', + '/.well-known', + '/connect', + '/weatherforecast', + ], + target: 'https://localhost:9101', + secure: false + } +]; + +module.exports = PROXY_CONFIG; diff --git a/MyOffice.SPA/src/silent-refresh.html b/MyOffice.SPA/src/silent-refresh.html new file mode 100644 index 0000000..0c2ab58 --- /dev/null +++ b/MyOffice.SPA/src/silent-refresh.html @@ -0,0 +1,31 @@ + + + + + + + diff --git a/MyOffice.SPA/src/styles.scss b/MyOffice.SPA/src/styles.scss new file mode 100644 index 0000000..1287a6a --- /dev/null +++ b/MyOffice.SPA/src/styles.scss @@ -0,0 +1,27 @@ +/* You can add global styles to this file, and also import other style files */ + +.mdc-text-field--disabled.mdc-text-field--filled { + background-color: #4c4f57; +} + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} + +.spinner:before { + content: ''; + box-sizing: border-box; + position: absolute; + top: 50%; + left: 50%; + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + border-radius: 50%; + border: 2px solid #ffffff; + border-top-color: #000000; + animation: spinner .8s linear infinite; +} diff --git a/MyOffice.SPA/src/styles/_variables.scss b/MyOffice.SPA/src/styles/_variables.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/styles/global.scss b/MyOffice.SPA/src/styles/global.scss new file mode 100644 index 0000000..6c384d0 --- /dev/null +++ b/MyOffice.SPA/src/styles/global.scss @@ -0,0 +1,277 @@ +@import '@angular/material/theming'; +@include mat-core(); + +/* You can add global styles to this file, and also import other style files */ +html, body { + height: 100%; +} + +body { + margin: 0; + font-family: Roboto, "Helvetica Neue", sans-serif; +} + +.app-header { + justify-content: space-between; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 2; + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, .2), 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12); +} + +.login-wrapper { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.mat-card-content-center { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.primary-content { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + min-width: 600px; + padding: 30px 40px 30px 40px; +} + +.box { + position: relative; + top: 0; + opacity: 1; + float: left; + padding: 30px 40px 30px 40px; + width: 100%; + background: #fff; + border-radius: 10px; + transform: scale(1); + -webkit-transform: scale(1); + -ms-transform: scale(1); + z-index: 5; + max-width: 330px; +} + +.box.back { + transform: scale(.95); + -webkit-transform: scale(.95); + -ms-transform: scale(.95); + top: -20px; + opacity: .8; + z-index: -1; +} + +.box:before { + content: ""; + width: 100%; + height: 30px; + border-radius: 10px; + position: absolute; + top: -10px; + background: rgba(255, 255, 255, .6); + left: 0; + transform: scale(.95); + -webkit-transform: scale(.95); + -ms-transform: scale(.95); + z-index: -1; +} + +mat-form-field { + width: 350px !important; +} + +.mat-mdc-form-field-infix { +} + +/* margins */ +.m-5 { + margin: 5px; +} + +.m-10 { + margin: 10px; +} + +.m-15 { + margin: 15px; +} + +.m-20 { + margin: 20px; +} + +.m-25 { + margin: 25px; +} + +.m-30 { + margin: 30px; +} + +.mt-5 { + margin-top: 5px; +} + +.mt-10 { + margin-top: 10px; +} + +.mt-15 { + margin-top: 15px; +} + +.mt-20 { + margin-top: 20px; +} + +.mt-25 { + margin-top: 25px; +} + +.mt-30 { + margin-top: 30px; +} + +.mb-5 { + margin-bottom: 5px; +} + +.mb-10 { + margin-bottom: 10px; +} + +.mb-15 { + margin-bottom: 15px; +} + +.mb-20 { + margin-bottom: 20px; +} + +.mb-25 { + margin-bottom: 25px; +} + +.mb-30 { + margin-bottom: 30px; +} + +.ml-5 { + margin-left: 5px; +} + +.ml-10 { + margin-left: 10px; +} + +.ml-15 { + margin-left: 15px; +} + +.ml-20 { + margin-left: 20px; +} + +.ml-25 { + margin-left: 25px; +} + +.ml-30 { + margin-left: 30px; +} + +.mr-5 { + margin-right: 5px; +} + +.mr-10 { + margin-right: 10px; +} + +.mr-15 { + margin-right: 15px; +} + +.mr-20 { + margin-right: 20px; +} + +.mr-25 { + margin-right: 25px; +} + +.mr-30 { + margin-right: 30px; +} + +.ml-a { + margin-left: auto; +} +/* paddings */ + +/* min-width */ +.w-50 { + width: 50px; +} + +.w-75 { + width: 75px; +} + +.w-100 { + width: 100px; +} + +.w-100p { + width: 100%; +} + +/* min-width */ +.mw-50 { + min-width: 50px; +} + +.mw-75 { + min-width: 75px; +} + +.mw-100 { + min-width: 100px; +} + +.mw-50-imp { + min-width: 50px !important; +} + +.mw-75-imp { + min-width: 75px !important; +} + +.mw-100-imp { + min-width: 100px !important; +} + +.fl-l { + float: left +} + +.fl-r { + float: right +} + +/* colors */ + +$primary: mat-palette($mat-blue,800); + +.color-warn { + color: mat-color($primary, default); +} diff --git a/MyOffice.SPA/src/styles/reset.scss b/MyOffice.SPA/src/styles/reset.scss new file mode 100644 index 0000000..e69de29 diff --git a/MyOffice.SPA/src/styles/styles.scss b/MyOffice.SPA/src/styles/styles.scss new file mode 100644 index 0000000..b794247 --- /dev/null +++ b/MyOffice.SPA/src/styles/styles.scss @@ -0,0 +1,18 @@ +@import "src/styles/_variables"; + +// Import functions, variables, and mixins needed by other Bootstrap files +@import "bootstrap/scss/functions"; +@import "bootstrap/scss/variables"; +@import "bootstrap/scss/maps"; +@import "bootstrap/scss/mixins"; + +// Import Bootstrap Reboot +@import "bootstrap/scss/root"; // Contains :root CSS variables used by other Bootstrap files +@import "bootstrap/scss/reboot"; + +@import "bootstrap/scss/containers"; // Add .container and .container-fluid classes +@import "bootstrap/scss/grid"; // Add the grid system + +@import "src/styles/reset"; + +@import "src/styles/global"; diff --git a/MyOffice.SPA/src/styles/theme.scss b/MyOffice.SPA/src/styles/theme.scss new file mode 100644 index 0000000..5955c8a --- /dev/null +++ b/MyOffice.SPA/src/styles/theme.scss @@ -0,0 +1,36 @@ +// Custom Theming for Angular Material +// For more information: https://material.angular.io/guide/theming +@use '@angular/material' as mat; +// Plus imports for other components in your app. + +// Include the common styles for Angular Material. We include this here so that you only +// have to load a single css file for Angular Material in your app. +// Be sure that you only ever include this mixin once! +// TODO(v15): As of v15 mat.legacy-core no longer includes default typography styles. +// The following line adds: +// 1. Default typography styles for all components +// 2. Styles for typography hierarchy classes (e.g. .mat-headline-1) +// If you specify typography styles for the components you use elsewhere, you should delete this line. +// If you don't need the default component typographies but still want the hierarchy styles, +// you can delete this line and instead use: +// `@include mat.legacy-typography-hierarchy(mat.define-typography-config());` +@include mat.all-component-typographies(); +@include mat.core(); + +// Define the palettes for your theme using the Material Design palettes available in palette.scss +// (imported above). For each palette, you can optionally specify a default, lighter, and darker +// hue. Available color palettes: https://material.io/design/color/ +$theme-primary: mat.define-palette(mat.$deep-purple-palette); +$theme-accent: mat.define-palette(mat.$amber-palette, A200, A100, A400); + +// The warn palette is optional (defaults to red). +$theme-warn: mat.define-palette(mat.$red-palette); + +// Create the theme object. A theme consists of configurations for individual +// theming systems such as "color" or "typography". +$theme: mat.define-light-theme(( color: ( primary: $theme-primary, accent: $theme-accent, warn: $theme-warn, ), typography: mat.define-typography-config(), )); + +// Include theme styles for core and each component used in your app. +// Alternatively, you can import and @include the theme mixins for each component +// that you are using. +@include mat.all-component-themes($theme); diff --git a/MyOffice.SPA/src/test.ts b/MyOffice.SPA/src/test.ts new file mode 100644 index 0000000..ffa954b --- /dev/null +++ b/MyOffice.SPA/src/test.ts @@ -0,0 +1,14 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); diff --git a/MyOffice.SPA/tsconfig.app.json b/MyOffice.SPA/tsconfig.app.json new file mode 100644 index 0000000..90880d5 --- /dev/null +++ b/MyOffice.SPA/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/MyOffice.SPA/tsconfig.json b/MyOffice.SPA/tsconfig.json new file mode 100644 index 0000000..57621c1 --- /dev/null +++ b/MyOffice.SPA/tsconfig.json @@ -0,0 +1,33 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "es2020", + "lib": [ + "es2020", + "dom" + ], + "useDefineForClassFields": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/MyOffice.SPA/tsconfig.spec.json b/MyOffice.SPA/tsconfig.spec.json new file mode 100644 index 0000000..c1fdd7e --- /dev/null +++ b/MyOffice.SPA/tsconfig.spec.json @@ -0,0 +1,18 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/MyOffice.Services/MyOffice.Services.csproj b/MyOffice.Services/MyOffice.Services.csproj new file mode 100644 index 0000000..7349330 --- /dev/null +++ b/MyOffice.Services/MyOffice.Services.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs b/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs new file mode 100644 index 0000000..b90155f --- /dev/null +++ b/MyOffice.Services/Users/Domain/AddUserExternalStatusEnum.cs @@ -0,0 +1,8 @@ +namespace MyOffice.Services.Users.Domain; + +public enum AddUserExternalStatusEnum +{ + success, + externalid_used, + user_not_valid +} \ No newline at end of file diff --git a/MyOffice.Services/Users/UserService.cs b/MyOffice.Services/Users/UserService.cs new file mode 100644 index 0000000..a4cf880 --- /dev/null +++ b/MyOffice.Services/Users/UserService.cs @@ -0,0 +1,91 @@ +namespace MyOffice.Services.Users; + +using Domain; +using Core; +using Data.Models.Users; +using Data.Repositories.Users; + +public class UserService +{ + private readonly IUserRepository _userRepository; + private readonly IUserExternalRepository _userExternalRepository; + + public UserService( + IUserRepository userRepository, + IUserExternalRepository userExternalRepository + ) + { + _userRepository = userRepository; + _userExternalRepository = userExternalRepository; + } + + public async Task Get(Guid id) + { + return await _userRepository.GetUserAsync(id); + } + + public async Task> GetUserExternals(Guid userId) + { + return await _userExternalRepository.GetUserExternalsByUserIdAsync(userId); + } + + public async Task GetUserExternal(Guid userId, string provider) + { + return await _userExternalRepository.GetByUserIdAsync(userId, provider); + } + + public async Task> RemoveUserExternal(Guid userId, string provider) + { + var result = new Exec(); + + var userExternal = await _userExternalRepository.GetByUserIdAsync(userId, provider); + if (userExternal == null) return result.Set(GeneralExecStatus.not_found); + + _userExternalRepository.RemoveUserExternal(userExternal); + + return result.Set(userExternal); + } + + private readonly object _lock = new(); + + public Exec AddUserExternal( + Guid userId, + string provider, + string externalId, + string email + ) + { + var result = new Exec(AddUserExternalStatusEnum.success); + + var externalLogin = _userExternalRepository.GetByUserId(userId, provider); + + if (externalLogin != null) return result.Set(externalLogin); + + lock (_lock) + { + externalLogin = _userExternalRepository.GetByUserId(userId, provider); + // externalLogin exists + if (externalLogin != null) return result.Set(externalLogin); + + externalLogin = _userExternalRepository.GetByExternalId(externalId, provider); + // externalId connected to another user + if (externalLogin != null) return result.Set(AddUserExternalStatusEnum.externalid_used); + + var user = _userRepository.GetByUserUserName(email); + // there are another user with that email + if (user?.Id != userId) return result.Set(AddUserExternalStatusEnum.user_not_valid); + + externalLogin = new UserExternal + { + UserId = userId, + CreatedOn = DateTime.UtcNow, + Provider = provider.ToLower(), + ExternalId = externalId, + Email = email + }; + _userExternalRepository.AddUserExternal(externalLogin); + } + + return result; + } +} \ No newline at end of file diff --git a/MyOffice.Shared/Configuration.cs b/MyOffice.Shared/Configuration.cs new file mode 100644 index 0000000..979e875 --- /dev/null +++ b/MyOffice.Shared/Configuration.cs @@ -0,0 +1,28 @@ +namespace MyOffice.Shared; + +using Microsoft.Extensions.Configuration; + +public static class SharedConfiguration +{ + public static IConfiguration ConfigurationContainer { get; private set; } + + public static IConfiguration CreateConfigurationContainer() + { + try + { + var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + if (string.IsNullOrWhiteSpace(environment)) + return ConfigurationContainer = new ConfigurationBuilder() + .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) + .AddJsonFile($"appsettings.shared.json").Build(); + + return ConfigurationContainer = new ConfigurationBuilder() + .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) + .AddJsonFile($"appsettings.shared.{environment}.json").Build(); + } + catch (Exception ex) + { + throw; + } + } +} \ No newline at end of file diff --git a/MyOffice.Shared/MyOffice.Shared.csproj b/MyOffice.Shared/MyOffice.Shared.csproj new file mode 100644 index 0000000..1bab03d --- /dev/null +++ b/MyOffice.Shared/MyOffice.Shared.csproj @@ -0,0 +1,45 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + Always + true + + + Always + true + PreserveNewest + + + Always + true + + + + + + + + + + + C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.15\Microsoft.Extensions.Configuration.dll + + + C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.15\Microsoft.Extensions.Configuration.Abstractions.dll + + + + diff --git a/MyOffice.Shared/appsettings.shared.json b/MyOffice.Shared/appsettings.shared.json new file mode 100644 index 0000000..4c8cd57 --- /dev/null +++ b/MyOffice.Shared/appsettings.shared.json @@ -0,0 +1,7 @@ +{ + "ConnectionStrings": { + "sqlite": "Filename=AppDbContext.Dev.db", + "mssql": "", + "npgsql": "" + } +} \ No newline at end of file diff --git a/MyOffice.Web/App.Config b/MyOffice.Web/App.Config new file mode 100644 index 0000000..cae4452 --- /dev/null +++ b/MyOffice.Web/App.Config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MyOffice.Web/Controllers/BaseApiController.cs b/MyOffice.Web/Controllers/BaseApiController.cs new file mode 100644 index 0000000..8b89c40 --- /dev/null +++ b/MyOffice.Web/Controllers/BaseApiController.cs @@ -0,0 +1,26 @@ +namespace MyOffice.Web.Controllers; + +using System.Security.Authentication; +using Core.Extensions; +using IdentityModel; +using Microsoft.AspNetCore.Mvc; +using static IdentityServer4.Models.IdentityResources; + +public class BaseApiController : ControllerBase +{ + public Guid UserId + { + get + { + var subject = User.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject)?.Value; + if (subject.IsPresent() && Guid.TryParse(subject, out var guid)) return guid; + + throw new AuthenticationException("Get UserId failed"); + } + } + + public ObjectResult ProblemBadRequest(string? detail = null) + { + return Problem(detail, statusCode: StatusCodes.Status400BadRequest); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Controllers/UserController.cs b/MyOffice.Web/Controllers/UserController.cs new file mode 100644 index 0000000..df383bf --- /dev/null +++ b/MyOffice.Web/Controllers/UserController.cs @@ -0,0 +1,169 @@ +namespace MyOffice.Web.Controllers; + +using Models.Auth; +using Identity.Domain; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using MyOffice.Data.Models.Users; +using Core.Extensions; +using MyOffice.Core.Identity; +using Core; +using Services.Users; +using Services.Users.Domain; + +[ApiController] +[Route("api/[controller]")] +public class UserController : BaseApiController +{ + private readonly UserManager> _userManager; + private readonly UserService _userService; + private readonly IEnumerable _externalProviderValidators; + + public UserController( + UserManager> userManager, + UserService userService, + IEnumerable externalProviderValidators + ) + { + _userManager = userManager; + _userService = userService; + _externalProviderValidators = externalProviderValidators; + } + + [HttpPost("~/api/user/register")] + public async Task Register([FromBody] RegisterModel request) + { + var user = new ApplicationUser + { + Id = Guid.NewGuid(), + UserName = request.UserName, + Email = request.UserName + }; + + var result = await _userManager.CreateAsync(user, request.Password); + + return new + { + result.Succeeded, + Errors = result.Errors.Where(x => !x.Code.Equals("DuplicateUserName")) + }; + } + + [Authorize] + [HttpGet("~/api/user/profile")] + public async Task ProfileGet() + { + var user = await _userManager.GetUserAsync(User); + + return user.ToModel(await _userService.GetUserExternals(user.Id)); + } + + [Authorize] + [HttpPost("~/api/user/profile")] + public async Task ProfileUpdate([FromBody] ProfileModel model) + { + var user = await _userManager.GetUserAsync(User); + + user.FirstName = model.FirstName; + user.LastName = model.LastName; + user.FullName = model.FullName.NullIfEmpty() ?? $"{model.FirstName} {model.LastName}"; + + await _userManager.UpdateAsync(user); + + return user.ToModel(await _userService.GetUserExternals(user.Id)); + } + + [Authorize] + [HttpPost("~/api/user/attach")] + public async Task AttachProvider([FromBody] AttachModel model) + { + var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(model.Provider)); + if (validator == null) return ProblemBadRequest("Provider not supported"); + + var result = await validator.ValidateAsync(model.Token); + if (!result.IsSuccessed) return ProblemBadRequest("Token not valid"); + + var execResult = _userService.AddUserExternal(UserId, model.Provider, result.ExternalId!, result.Email!); + switch (execResult.Status) + { + case AddUserExternalStatusEnum.success: + return Ok(new + { + success = true + }); + + case AddUserExternalStatusEnum.externalid_used: + case AddUserExternalStatusEnum.user_not_valid: + return ProblemBadRequest("Provider already connected"); + + default: + throw new NotSupportedException(execResult.Status.ToString()); + } + } + + [Authorize] + [HttpPost("~/api/user/deattach")] + public async Task DeattachProvider([FromBody] DeattachModel model) + { + var exec = await _userService.RemoveUserExternal(UserId, model.Provider); + + if (exec.Status == GeneralExecStatus.not_found) return ProblemBadRequest("Provider not connected"); + + return Ok(new + { + success = true + }); + } +} + +public class DeattachModel +{ + [Required] public string Provider { get; set; } = null!; +} + +public class AttachModel +{ + [Required] public string Provider { get; set; } = null!; + [Required] public string Token { get; set; } = null!; +} + +public class ProfileModel +{ + public class ProviderModel + { + public string Provider { get; set; } = null!; + + public DateTime CreatedOn { get; set; } + } + + public string? Email { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? FullName { get; set; } + public bool? IsEmailConfirmed { get; set; } + + public List? Providers { get; set; } +} + +public static class ProfileModelExtensions +{ + public static ProfileModel ToModel(this ApplicationUser user, List userClaims) + { + return new ProfileModel + { + Email = user.Email, + FirstName = user.FirstName, + LastName = user.LastName, + FullName = user.FullName, + IsEmailConfirmed = user.IsEmailConfirmed, + Providers = userClaims?.Select(x => new ProfileModel.ProviderModel + { + Provider = x.Provider, + CreatedOn = x.CreatedOn + }).ToList() + }; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Controllers/WeatherForecastController.cs b/MyOffice.Web/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..bd092cb --- /dev/null +++ b/MyOffice.Web/Controllers/WeatherForecastController.cs @@ -0,0 +1,47 @@ +namespace MyOffice.Web.Controllers; + +using Models.WeatherForecast; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet("~/api/weatherforecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + + [HttpGet("~/api/weatherforecast/auth")] + [Authorize] + public IEnumerable GetAuth() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Configure/ConfigureIdentityServerOptions.cs b/MyOffice.Web/Identity/Configure/ConfigureIdentityServerOptions.cs new file mode 100644 index 0000000..7b04fac --- /dev/null +++ b/MyOffice.Web/Identity/Configure/ConfigureIdentityServerOptions.cs @@ -0,0 +1,34 @@ +namespace MyOffice.Web.Identity.Configure; + +using MyOffice.Web.Infrastructure; +using IdentityServer4.AccessTokenValidation; +using Microsoft.Extensions.Options; + +public class ConfigureIdentityServerOptions : IConfigureNamedOptions +{ + readonly GlobalSettings _globalSettings; + readonly ILogger _logger; + + public ConfigureIdentityServerOptions( + GlobalSettings globalSettings, + ILogger logger + ) + { + _globalSettings = globalSettings; + _logger = logger; + } + + public void Configure(string? name, IdentityServerAuthenticationOptions options) + { + //_logger.LogError($"Configure: {_globalSettings.Host}"); + if (name == IdentityServerAuthenticationDefaults.AuthenticationScheme) + { + options.RequireHttpsMetadata = false; + options.ApiName = IdentityServerConfig.ApiName; + options.Authority = _globalSettings.Host; + } + } + + // This won't be called, but is required for the IConfigureNamedOptions interface + public void Configure(IdentityServerAuthenticationOptions options) => Configure(Options.DefaultName, options); +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Configure/IdentityServerConfig.cs b/MyOffice.Web/Identity/Configure/IdentityServerConfig.cs new file mode 100644 index 0000000..dff956e --- /dev/null +++ b/MyOffice.Web/Identity/Configure/IdentityServerConfig.cs @@ -0,0 +1,107 @@ +namespace MyOffice.Web.Identity.Configure; + +using IdentityModel; +using IdentityServer4; +using IdentityServer4.Models; + +public class IdentityServerConfig +{ + public static class ClaimConstants + { + public const string Subject = "subject"; + public const string Permission = "permission"; + } + + public static class ScopeConstants + { + public const string Roles = "roles"; + } + + public const string ApiName = "api"; + public const string ApiFriendlyName = "MyOffice.Web API"; + public const string AppClientID = "angulartemplate_spa"; + + public static IEnumerable GetIdentityResources() + { + return new List + { + new IdentityResources.OpenId(), + new IdentityResources.Profile(), + new IdentityResources.Phone(), + new IdentityResources.Email(), + new(ScopeConstants.Roles, new List { JwtClaimTypes.Role }) + }; + } + + public static IEnumerable GetApiScopes() + { + return new List + { + new(ApiName, ApiFriendlyName) + { + UserClaims = + { + JwtClaimTypes.Name, + JwtClaimTypes.Email, + JwtClaimTypes.PhoneNumber, + JwtClaimTypes.Role, + ClaimConstants.Permission + } + } + }; + } + + public static IEnumerable GetApiResources() + { + return new List + { + new(ApiName) + { + Scopes = { ApiName } + } + }; + } + + public static IEnumerable GetClients() + { + return new List + { + new() + { + ClientId = AppClientID, + ClientSecrets = new List + { + new Secret("secret".Sha256()) + }, + AllowedGrantTypes = new[] + { + GrantType.AuthorizationCode, + GrantType.ClientCredentials, + GrantType.DeviceFlow, + GrantType.ResourceOwnerPassword, + "external" + }, + AllowAccessTokensViaBrowser = true, + RequireClientSecret = false, + + RedirectUris = new[] + { + "http://localhost:4200/silent-refresh.html", + }, + + AllowedScopes = + { + IdentityServerConstants.StandardScopes.OpenId, + IdentityServerConstants.StandardScopes.Profile, + IdentityServerConstants.StandardScopes.Phone, + IdentityServerConstants.StandardScopes.Email, + ScopeConstants.Roles, + ApiName + }, + AllowOfflineAccess = true, + RefreshTokenExpiration = TokenExpiration.Sliding, + RefreshTokenUsage = TokenUsage.OneTimeOnly + } + }; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/CorsPolicyService .cs b/MyOffice.Web/Identity/CorsPolicyService .cs new file mode 100644 index 0000000..9d68994 --- /dev/null +++ b/MyOffice.Web/Identity/CorsPolicyService .cs @@ -0,0 +1,27 @@ +namespace MyOffice.Web.Identity; + +using Core.Extensions; +using IdentityServer4.Services; +using Infrastructure; + +public class CorsPolicyService : ICorsPolicyService +{ + private readonly ILogger _logger; + private readonly GlobalSettings _globalSettings; + + public CorsPolicyService( + ILogger logger, + GlobalSettings globalSettings + ) + { + _logger = logger; + _globalSettings = globalSettings; + } + + public Task IsOriginAllowedAsync(string origin) + { + + var result = origin.EqualsIgnoreCase(_globalSettings.Host); + return Task.FromResult(result); + } +} diff --git a/MyOffice.Web/Identity/Domain/ApplicationRole.cs b/MyOffice.Web/Identity/Domain/ApplicationRole.cs new file mode 100644 index 0000000..ddd8f96 --- /dev/null +++ b/MyOffice.Web/Identity/Domain/ApplicationRole.cs @@ -0,0 +1,5 @@ +namespace MyOffice.Web.Identity.Domain; + +public class ApplicationRole +{ +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Domain/ApplicationUser.cs b/MyOffice.Web/Identity/Domain/ApplicationUser.cs new file mode 100644 index 0000000..b0b1e59 --- /dev/null +++ b/MyOffice.Web/Identity/Domain/ApplicationUser.cs @@ -0,0 +1,16 @@ +namespace MyOffice.Web.Identity.Domain; + +public class ApplicationUser +{ +#pragma warning disable CS8618 // Non-nullable property 'Id' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. + public TKey Id { get; set; } +#pragma warning restore CS8618 // Non-nullable property 'Id' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. + public string UserName { get; set; } = null!; + public string Email { get; set; } = null!; + public string PasswordHash { get; set; } = null!; + + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? FullName { get; set; } + public bool IsEmailConfirmed { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs b/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs new file mode 100644 index 0000000..af1b964 --- /dev/null +++ b/MyOffice.Web/Identity/Domain/ExternalProvidersConfig.cs @@ -0,0 +1,19 @@ +namespace MyOffice.Web.Identity.Domain; + +public class ExternalProvidersConfig +{ + public class Auth0Config + { + public string? ClientId { get; set; } + public string? Domain { get; set; } + public string? SecretKey { get; set; } + } + + public class GoogleConfig + { + public string? ClientId { get; set; } + } + + public Auth0Config? Auth0 { get; set; } + public GoogleConfig? Google { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExtensionGrantValidator.cs b/MyOffice.Web/Identity/ExtensionGrantValidator.cs new file mode 100644 index 0000000..d2d7cf4 --- /dev/null +++ b/MyOffice.Web/Identity/ExtensionGrantValidator.cs @@ -0,0 +1,167 @@ +namespace MyOffice.Web.Identity; + +using MyOffice.Data.Models.Users; +using Domain; +using Data.Repositories.Users; +using Repositories; +using IdentityModel; +using IdentityServer4.Models; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; +using System.Security.Claims; +using Core.Extensions; +using Core.Identity; + +public class ExtensionGrantValidator : IExtensionGrantValidator +{ + private readonly IUserStore> _userStore; + private readonly ILogger _logger; + private readonly AppUserManager _appUserManager; + private readonly IUserExternalRepository _userExternalRepository; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ExternalProvidersConfig _externalProvidersConfig; + private readonly IEnumerable _externalProviderValidators; + + public ExtensionGrantValidator( + ILogger logger, + IUserStore> userStore, + AppUserManager appUserManager, + IUserExternalRepository userExternalRepository, + IHttpContextAccessor httpContextAccessor, + IOptions externalProvidersConfig, + IEnumerable externalProviderValidators + ) + { + if (externalProvidersConfig == null) + throw new ArgumentNullException(nameof(externalProvidersConfig)); + + _userStore = userStore ?? throw new ArgumentNullException(nameof(userStore)); + _appUserManager = appUserManager ?? throw new ArgumentNullException(nameof(appUserManager)); + _userExternalRepository = + userExternalRepository ?? throw new ArgumentNullException(nameof(userExternalRepository)); + _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); + _externalProvidersConfig = externalProvidersConfig.Value; + _externalProviderValidators = externalProviderValidators; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public string GrantType => "external"; + + public async Task ValidateAsync(ExtensionGrantValidationContext context) + { + var provider = context.Request.Raw["provider"]; + if (provider == null) + throw new ArgumentNullException("provider not found"); + + var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(provider)); + if (validator == null || !validator.IsConfigured) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, + $"Provider not supported: {provider}"); + return; + } + + var token = context.Request.Raw["token"]; + if (token == null) + throw new ArgumentNullException("token not found"); + + var result = await validator.ValidateAsync(token); + if (!result.IsSuccessed) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, $"Token not valid"); + return; + } + + context.Result = await ProcessAsync(result.Email!, result.ExternalId!, provider, result.EmailVerified, + result.FullName); + } + + private readonly object _lock = new(); + + private async Task ProcessAsync( + string email, + string externlaId, + string provider, + bool isEmailConfirmed, + string? fullName + ) + { + // connect to exists user + if (_httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated == true) + { + return new GrantValidationResult(TokenRequestErrors.InvalidRequest, $"Authentication failed"); + } + else + { + var user = await _appUserManager.FindByEmailAsync(email); + if (user == null) + { + if (!isEmailConfirmed) + return new GrantValidationResult(TokenRequestErrors.InvalidRequest, "Email not confirmed"); + + user = await CreateUser(email, isEmailConfirmed, fullName); + if (user == null) return new GrantValidationResult(TokenRequestErrors.InvalidRequest); + } + + var claim = await _userExternalRepository.GetByUserIdAsync(user.Id, provider); + if (claim == null) claim = AddClaim(user, email, externlaId, provider); + + return ClaimToGrantValidationResult(claim.UserId, "", ""); + } + } + + private async Task?> CreateUser(string email, bool isEmailConfirmed, string? fullName) + { + var user = new ApplicationUser + { + Id = Guid.NewGuid(), + UserName = email, + Email = email, + IsEmailConfirmed = isEmailConfirmed, + FullName = fullName + }; + var password = "Qq1!_" + Guid.NewGuid(); + var result = await _appUserManager.CreateAsync(user, password); + if (!result.Succeeded) return null; + + return user; + } + + private UserExternal AddClaim(ApplicationUser user, string email, string externalId, string provider) + { + lock (_lock) + { + var claim = _userExternalRepository.GetByUserId(user.Id, provider); + + if (claim != null) return claim; + + claim = new UserExternal + { + UserId = user.Id, + CreatedOn = DateTime.UtcNow, + Provider = provider.ToLower(), + ExternalId = externalId, + Email = email + }; + _userExternalRepository.AddUserExternal(claim); + + return claim; + } + } + + private GrantValidationResult ClaimToGrantValidationResult(Guid userId, string provider, string email) + { + var userIdStr = userId.ToString(); + var claims = new List + { + new(JwtClaimTypes.Id, userIdStr), + new(JwtClaimTypes.Subject, userIdStr), + new(JwtClaimTypes.Email, email) + }; + + var grantValidationResult = new GrantValidationResult(userIdStr, provider, claims); + + return grantValidationResult; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs new file mode 100644 index 0000000..efff106 --- /dev/null +++ b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorAuth0.cs @@ -0,0 +1,69 @@ +namespace MyOffice.Web.Identity.ExternalProviders; + +using Domain; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Protocols; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Text; +using Core.Extensions; +using Core.Identity; + +public class ExternalProviderValidatorAuth0 : IExternalProviderValidator +{ + private readonly ExternalProvidersConfig _externalProvidersConfig; + private readonly ILogger _logger; + + public ExternalProviderValidatorAuth0( + ILogger logger, + IOptions externalProvidersConfig + ) + { + _externalProvidersConfig = externalProvidersConfig.Value; + _logger = logger; + + Provider = ExternalProvidersConst.PROVIDER_AUTH0; + IsConfigured = _externalProvidersConfig.IsAuth0Configured(); + } + + public string Provider { get; } + public bool IsConfigured { get; } + + public async Task ValidateAsync(string token) + { + var auth0Domain = _externalProvidersConfig.Auth0!.Domain!; + var secretKey = _externalProvidersConfig.Auth0!.SecretKey!; + var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); + var configurationManager = new ConfigurationManager( + $"{auth0Domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever()); + var openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None); + + var validations = new TokenValidationParameters + { + ValidIssuer = auth0Domain, + ValidAudiences = new[] { _externalProvidersConfig.Auth0!.ClientId }, + IssuerSigningKeys = openIdConfig.SigningKeys, + TokenDecryptionKey = securityKey + }; + + var tokenHandler = new JwtSecurityTokenHandler(); + var user = tokenHandler.ValidateToken(token, validations, out var validatedToken); + if (user.Identity?.IsAuthenticated != true) + { + return ExternalProviderValidatorResult.Failed(); + } + + var email = user.Claims.GetEmail(); + var emailVerified = user.Claims.GetValue("email_verified").AsBool(); + var fullName = user.Claims.GetValue("name")?.ToString(); + var externalId = user.Claims.GetSID(); + + if (email == null || externalId == null) + { + return ExternalProviderValidatorResult.Failed(); + } + + return ExternalProviderValidatorResult.Success(email, emailVerified, externalId, fullName); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs new file mode 100644 index 0000000..d5e6c4d --- /dev/null +++ b/MyOffice.Web/Identity/ExternalProviders/ExternalProviderValidatorGoogle.cs @@ -0,0 +1,36 @@ +namespace MyOffice.Web.Identity.ExternalProviders; + +using MyOffice.Core.Identity; +using Domain; +using Google.Apis.Auth; +using Microsoft.Extensions.Options; + +public class ExternalProviderValidatorGoogle : IExternalProviderValidator +{ + private readonly ExternalProvidersConfig _externalProvidersConfig; + + public ExternalProviderValidatorGoogle( + IOptions externalProvidersConfig + ) + { + _externalProvidersConfig = externalProvidersConfig.Value; + + Provider = ExternalProvidersConst.PROVIDER_GOOGLE; + IsConfigured = _externalProvidersConfig.IsGoogleConfigured(); + } + + public string Provider { get; } + public bool IsConfigured { get; } + + public async Task ValidateAsync(string token) + { + var settings = new GoogleJsonWebSignature.ValidationSettings() + { + Audience = new List() { _externalProvidersConfig.Google!.ClientId! } + }; + var result = await GoogleJsonWebSignature.ValidateAsync(token, settings); + if (!result.EmailVerified) return ExternalProviderValidatorResult.Failed(); + + return ExternalProviderValidatorResult.Success(result.Email, result.EmailVerified, result.Subject, result.Name); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs b/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs new file mode 100644 index 0000000..261bc0a --- /dev/null +++ b/MyOffice.Web/Identity/ExternalProviders/ExternalProvidersConst.cs @@ -0,0 +1,7 @@ +namespace MyOffice.Web.Identity.ExternalProviders; + +public class ExternalProvidersConst +{ + public const string PROVIDER_GOOGLE = "google"; + public const string PROVIDER_AUTH0 = "auth0"; +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs b/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs new file mode 100644 index 0000000..49c8a0d --- /dev/null +++ b/MyOffice.Web/Identity/ExternalProvidersConfigExtensions.cs @@ -0,0 +1,24 @@ +using MyOffice.Web.Identity.Domain; + +namespace MyOffice.Web.Identity; + +using Core.Extensions; + +public static class ExternalProvidersConfigExtensions +{ + public static bool IsGoogleConfigured(this ExternalProvidersConfig? config) + { + return config != null + && config.Google != null + && config.Google.ClientId.IsPresent(); + } + + public static bool IsAuth0Configured(this ExternalProvidersConfig? config) + { + return config != null + && config.Auth0 != null + && config.Auth0.ClientId.IsPresent() + && config.Auth0.Domain.IsPresent() + && config.Auth0.SecretKey.IsPresent(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/PersistedGrantStore.cs b/MyOffice.Web/Identity/PersistedGrantStore.cs new file mode 100644 index 0000000..d48fbda --- /dev/null +++ b/MyOffice.Web/Identity/PersistedGrantStore.cs @@ -0,0 +1,54 @@ +namespace MyOffice.Web.Identity; + +using System.Collections.Concurrent; +using Core.Extensions; +using IdentityServer4.Models; +using IdentityServer4.Stores; + +public class PersistedGrantStore : IPersistedGrantStore +{ + private static ConcurrentDictionary _store = new ConcurrentDictionary(); + + public Task StoreAsync(PersistedGrant grant) + { + _store.AddOrUpdate(grant.Key, grant, (key, oldValue) => grant); + + return Task.CompletedTask; + } + + public Task GetAsync(string key) + { + if (!_store.TryGetValue(key, out var grant)) + throw new Exception($"Key '{key}' not found"); + + return Task.FromResult(grant); + } + + public Task> GetAllAsync(PersistedGrantFilter filter) + { + var list = _store.Values.Where(x => + (filter.ClientId.IsMissing() || filter.ClientId == x.ClientId) + && (filter.SessionId.IsMissing() || filter.SessionId == x.SessionId) + && (filter.SubjectId.IsMissing() || filter.SubjectId == x.SubjectId) + && (filter.Type.IsMissing() || filter.Type == x.Type) + ); + + return Task.FromResult(list); + } + + public Task RemoveAsync(string key) + { + _store.TryRemove(key, out _); + + return Task.CompletedTask; + } + + public async Task RemoveAllAsync(PersistedGrantFilter filter) + { + var list = await GetAllAsync(filter); + foreach (var item in list) + { + await RemoveAsync(item.Key); + } + } +} diff --git a/MyOffice.Web/Identity/ProfileService.cs b/MyOffice.Web/Identity/ProfileService.cs new file mode 100644 index 0000000..dc0cadf --- /dev/null +++ b/MyOffice.Web/Identity/ProfileService.cs @@ -0,0 +1,36 @@ +namespace MyOffice.Web.Identity; + +using Data.Repositories.Users; +using IdentityModel; +using IdentityServer4.Models; +using IdentityServer4.Services; +using System.Security.Claims; + +public class ProfileService : IProfileService +{ + private readonly IUserRepository _userRepository; + + public ProfileService( + IUserRepository userRepository + ) + { + _userRepository = userRepository; + } + + public async Task GetProfileDataAsync(ProfileDataRequestContext context) + { + var sub = context.Subject.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); + if (sub != null && Guid.TryParse(sub.Value, out var id)) + { + var user = await _userRepository.GetUserAsync(id); + if (user != null) + if (context.RequestedClaimTypes.Contains(JwtClaimTypes.Email)) + context.IssuedClaims.Add(new Claim(JwtClaimTypes.Email, user.Email)); + } + } + + public Task IsActiveAsync(IsActiveContext context) + { + return Task.FromResult(0); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Repositories/AppUserManager.cs b/MyOffice.Web/Identity/Repositories/AppUserManager.cs new file mode 100644 index 0000000..916b095 --- /dev/null +++ b/MyOffice.Web/Identity/Repositories/AppUserManager.cs @@ -0,0 +1,83 @@ +namespace MyOffice.Web.Identity.Repositories; + +using System.Security.Cryptography; +using Domain; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; + +public class PasswordHasher : IPasswordHasher> +{ + public string HashPassword(ApplicationUser user, string password) + { + byte[] salt; + salt = RandomNumberGenerator.GetBytes(16); + + var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100000); + var hash = pbkdf2.GetBytes(20); + + var hashBytes = new byte[36]; + Array.Copy(salt, 0, hashBytes, 0, 16); + Array.Copy(hash, 0, hashBytes, 16, 20); + + var passwordHash = Convert.ToBase64String(hashBytes); + + return passwordHash; + } + + private bool IsValidHash(string password, string passwordHash) + { + /* Fetch the stored value */ + /* Extract the bytes */ + var hashBytes = Convert.FromBase64String(passwordHash); + /* Get the salt */ + var salt = new byte[16]; + Array.Copy(hashBytes, 0, salt, 0, 16); + /* Compute the hash on the password the user entered */ + var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100000); + var hash = pbkdf2.GetBytes(20); + /* Compare the results */ + for (var i = 0; i < 20; i++) + if (hashBytes[i + 16] != hash[i]) + return false; + + return true; + } + + public PasswordVerificationResult VerifyHashedPassword( + ApplicationUser user, + string hashedPassword, + string providedPassword + ) + { + if (IsValidHash(providedPassword, hashedPassword)) return PasswordVerificationResult.Success; + + return PasswordVerificationResult.Failed; + } +} + +public class AppUserManager : UserManager> +{ + public AppUserManager( + IUserStore> store, + IOptions optionsAccessor, + IPasswordHasher> passwordHasher, + IEnumerable>> userValidators, + IEnumerable>> passwordValidators, + ILookupNormalizer keyNormalizer, + IdentityErrorDescriber errors, + IServiceProvider services, + ILogger>> logger) : + base( + store, + optionsAccessor, + passwordHasher, + userValidators, + passwordValidators, + keyNormalizer, + errors, + services, + logger + ) + { + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Repositories/RoleStore.cs b/MyOffice.Web/Identity/Repositories/RoleStore.cs new file mode 100644 index 0000000..285f433 --- /dev/null +++ b/MyOffice.Web/Identity/Repositories/RoleStore.cs @@ -0,0 +1,62 @@ +namespace MyOffice.Web.Identity.Repositories; + +using Domain; +using Microsoft.AspNetCore.Identity; + +public class RoleStore : IRoleStore +{ + public void Dispose() + { + } + + public Task CreateAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task GetRoleIdAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName, + CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task FindByIdAsync(string roleId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Identity/Repositories/UserStore.cs b/MyOffice.Web/Identity/Repositories/UserStore.cs new file mode 100644 index 0000000..53ca962 --- /dev/null +++ b/MyOffice.Web/Identity/Repositories/UserStore.cs @@ -0,0 +1,192 @@ +namespace MyOffice.Web.Identity.Repositories; + +using Data.Models.Users; +using Data.Repositories.Users; +using Domain; +using Microsoft.AspNetCore.Identity; + +public class UserStore : + IUserStore>, + IUserPasswordStore>, + IUserEmailStore> +{ + private readonly IUserRepository _userRepository; + + public UserStore( + IUserRepository userRepository + ) + { + _userRepository = userRepository; + } + + public void Dispose() + { + } + + public Task GetUserIdAsync(ApplicationUser user, CancellationToken cancellationToken) + { + return Task.FromResult(user.Id.ToString()); + } + + public Task GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) + { + return Task.FromResult(user.UserName); + } + + public Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task GetNormalizedUserNameAsync(ApplicationUser user, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task SetNormalizedUserNameAsync(ApplicationUser user, string normalizedName, + CancellationToken cancellationToken) + { + user.UserName = normalizedName; + return Task.FromResult(0); + } + + public async Task CreateAsync(ApplicationUser user, CancellationToken cancellationToken) + { + var result = await _userRepository.AddUserAsync(new User + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + PasswordHash = user.PasswordHash, + FirstName = user.FirstName, + LastName = user.LastName, + FullName = user.FullName, + IsEmailConfirmed = user.IsEmailConfirmed + }); + + return result == 1 ? IdentityResult.Success : IdentityResult.Failed(); + } + + public async Task UpdateAsync(ApplicationUser user, CancellationToken cancellationToken) + { + var userDb = new User + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + PasswordHash = user.PasswordHash, + FirstName = user.FirstName, + LastName = user.LastName, + FullName = user.FullName, + IsEmailConfirmed = user.IsEmailConfirmed + }; + + var result = await _userRepository.UpdateUserAsync(userDb); + return result == 1 ? IdentityResult.Success : IdentityResult.Failed(); + } + + public Task DeleteAsync(ApplicationUser user, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public async Task> FindByIdAsync(string userId, CancellationToken cancellationToken) + { + var user = await _userRepository.GetUserAsync(Guid.Parse(userId)); + if (user == null) + { +#pragma warning disable CS8603 // Possible null reference return. + return null; +#pragma warning restore CS8603 // Possible null reference return. + } + + return new ApplicationUser + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + PasswordHash = user.PasswordHash, + FirstName = user.FirstName, + LastName = user.LastName, + FullName = user.FullName, + IsEmailConfirmed = user.IsEmailConfirmed + }; + } + + public async Task> FindByNameAsync(string normalizedUserName, + CancellationToken cancellationToken) + { + var user = await _userRepository.GetByUserUserNameAsync(normalizedUserName); + if (user == null) + { +#pragma warning disable CS8603 // Possible null reference return. + return null; +#pragma warning restore CS8603 // Possible null reference return. + } + + return new ApplicationUser + { + Id = user.Id, + UserName = user.UserName, + Email = user.Email, + PasswordHash = user.PasswordHash, + FirstName = user.FirstName, + LastName = user.LastName, + FullName = user.FullName, + IsEmailConfirmed = user.IsEmailConfirmed + }; + } + + public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash, + CancellationToken cancellationToken) + { + user.PasswordHash = passwordHash; + return Task.FromResult(0); + } + + public Task GetPasswordHashAsync(ApplicationUser user, CancellationToken cancellationToken) + { + return Task.FromResult(user.PasswordHash); + } + + public Task HasPasswordAsync(ApplicationUser user, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task SetEmailAsync(ApplicationUser user, string email, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task GetEmailAsync(ApplicationUser user, CancellationToken cancellationToken) + { + return Task.FromResult(user.Email); + } + + public Task GetEmailConfirmedAsync(ApplicationUser user, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task SetEmailConfirmedAsync(ApplicationUser user, bool confirmed, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken) + { + return FindByNameAsync(normalizedEmail, cancellationToken); + } + + public Task GetNormalizedEmailAsync(ApplicationUser user, CancellationToken cancellationToken) + { + return Task.FromResult(user?.Email); + } + + public Task SetNormalizedEmailAsync(ApplicationUser user, string normalizedEmail, + CancellationToken cancellationToken) + { + return Task.FromResult(0); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Infrastructure/GlobalSettings.cs b/MyOffice.Web/Infrastructure/GlobalSettings.cs new file mode 100644 index 0000000..afa20c2 --- /dev/null +++ b/MyOffice.Web/Infrastructure/GlobalSettings.cs @@ -0,0 +1,6 @@ +namespace MyOffice.Web.Infrastructure; + +public class GlobalSettings +{ + public string? Host { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Auth/LoginModel.cs b/MyOffice.Web/Models/Auth/LoginModel.cs new file mode 100644 index 0000000..7127c9c --- /dev/null +++ b/MyOffice.Web/Models/Auth/LoginModel.cs @@ -0,0 +1,7 @@ +namespace MyOffice.Web.Models.Auth; + +public class LoginModel +{ + public string? UserName { get; set; } + public string? Password { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Auth/RegisterModel.cs b/MyOffice.Web/Models/Auth/RegisterModel.cs new file mode 100644 index 0000000..0c50f2b --- /dev/null +++ b/MyOffice.Web/Models/Auth/RegisterModel.cs @@ -0,0 +1,8 @@ +namespace MyOffice.Web.Models.Auth; + +public class RegisterModel +{ + public string UserName { get; set; } = null!; + public string Password { get; set; } = null!; + public string ConfirmPassword { get; set; } = null!; +} \ No newline at end of file diff --git a/MyOffice.Web/Models/WeatherForecast/WeatherForecast.cs b/MyOffice.Web/Models/WeatherForecast/WeatherForecast.cs new file mode 100644 index 0000000..f4d8836 --- /dev/null +++ b/MyOffice.Web/Models/WeatherForecast/WeatherForecast.cs @@ -0,0 +1,12 @@ +namespace MyOffice.Web.Models.WeatherForecast; + +public class WeatherForecast +{ + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } +} \ No newline at end of file diff --git a/MyOffice.Web/MyOffice.Web.csproj b/MyOffice.Web/MyOffice.Web.csproj new file mode 100644 index 0000000..be0616e --- /dev/null +++ b/MyOffice.Web/MyOffice.Web.csproj @@ -0,0 +1,54 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + Never + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MyOffice.Web/Program.cs b/MyOffice.Web/Program.cs new file mode 100644 index 0000000..04f12c8 --- /dev/null +++ b/MyOffice.Web/Program.cs @@ -0,0 +1,353 @@ +namespace MyOffice.Web; + +using System.IO; +using System.Linq; +using Core.Extensions; +using System.Collections.Concurrent; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.FileProviders.Physical; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Logging; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Identity; +using Identity.Domain; +using Identity.ExternalProviders; +using Identity.Repositories; +using IdentityServer4.AccessTokenValidation; +using IdentityServer4.Configuration; +using IdentityServer4.Extensions; +using IdentityServer4.Models; +using Microsoft.IdentityModel.Tokens; +using System.Security.Cryptography; +using Core.Identity; +using Data.Repositories.Users; +using DbContext; +using Services.Users; +using Shared; +using Identity.Configure; +using Infrastructure; +using Microsoft.Extensions.Logging.Console; +using IdentityServer4.Services; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + AddServices(builder); + + var app = builder.Build(); + Configure(app); + + app.Run(); + } + + private static void AddServices(WebApplicationBuilder builder) + { + builder.Services.AddLogging(logging => + logging.AddSimpleConsole(options => + { + //options.SingleLine = true; + options.TimestampFormat = "[HH:mm:ss] "; + options.ColorBehavior = LoggerColorBehavior.Enabled; + }) + ); + //File Logger + builder.Logging.AddFile(builder.Configuration.GetSection("Logging")); + + // shared configuration + builder.Configuration.AddConfiguration(SharedConfiguration.CreateConfigurationContainer()); + + // Database + var databaseProvider = builder.Configuration["DatabaseProvider"]; + if (databaseProvider == null) + throw new NullReferenceException($"Configuration DatabaseProvider {databaseProvider}"); + + var connectionString = builder.Configuration.GetConnectionString(databaseProvider); + if (connectionString == null) + throw new NullReferenceException($"Configuration ConnectionString {databaseProvider}"); + + var connectionConfiguration = new ConnectionConfiguration(databaseProvider, connectionString); + RepositoryInitializer.Initialize(builder.Services, connectionConfiguration); + + // Configurations + builder.Services.Configure( + builder.Configuration.GetSection("ExternalProviders") + ); + + InitializeGlobalSettings(builder); + + AddIdentityServices(builder); + + AddRepositories(builder); + + AddBusinessServices(builder); + + builder.Services + .AddControllers() + .AddJsonOptions(options => + { + options.AllowInputFormatterExceptionMessages = builder.Environment.IsDevelopment(); + }); + + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + //builder.Services.AddEndpointsApiExplorer(); + //builder.Services.AddSwaggerGen(); + + builder.Services.AddCors(); + } + + private static void InitializeGlobalSettings(WebApplicationBuilder builder) + { + builder.Services.Configure(_ => { }); + builder.Services.AddSingleton(resolver => resolver.GetRequiredService>().Value); + } + + private static void AddIdentityServices(WebApplicationBuilder builder) + { + // add identity + builder.Services + .AddIdentity, ApplicationRole>() + .AddUserStore() + .AddRoleStore() + .AddUserManager() + .AddDefaultTokenProviders(); + + builder.Services.AddScoped(); + builder.Services.AddScoped>, PasswordHasher>(); + + // Identity Services + builder.Services.AddScoped>, UserStore>(); + builder.Services.AddScoped, RoleStore>(); + + // External providers + builder.Services.AddScoped(); + builder.Services.AddScoped(); + + // Configure Identity options and password complexity here + builder.Services.Configure(options => + { + // User settings + options.User.RequireUniqueEmail = true; + + // Password settings + options.Password.RequireDigit = true; + options.Password.RequiredLength = 8; + options.Password.RequireNonAlphanumeric = true; + options.Password.RequireUppercase = true; + options.Password.RequireLowercase = true; + + // Lockout settings + options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); + options.Lockout.MaxFailedAccessAttempts = 10; + }); + + // Adds IdentityServer. + builder.Services + .AddIdentityServer(o => + { + o.UserInteraction = new UserInteractionOptions() + { + LoginUrl = "/authentication/signin", + LoginReturnUrlParameter = "returnUrl" + }; + }) + .AddSigningCredential(CreateSigningCredential()) + .AddPersistedGrantStore() + .AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources()) + .AddInMemoryApiScopes(IdentityServerConfig.GetApiScopes()) + .AddInMemoryApiResources(IdentityServerConfig.GetApiResources()) + .AddInMemoryClients(IdentityServerConfig.GetClients()) + .AddAspNetIdentity>() + .AddProfileService() + .AddExtensionGrantValidator(); + + var authentication = builder.Services + .AddAuthentication(options => + { + options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; + options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; + }); + + var frontEndHost = builder.Configuration.GetValue("FrontEnd:Host"); + var isDynamicFrontEndHost = frontEndHost.IsMissing(); + if (isDynamicFrontEndHost) + { + builder.Services.ConfigureOptions(); + authentication.AddIdentityServerAuthentication(); + } + else + { + authentication.AddIdentityServerAuthentication(options => + { + options.RequireHttpsMetadata = false; + options.ApiName = IdentityServerConfig.ApiName; + options.Authority = frontEndHost; + }); + } + } + + private static void AddRepositories(WebApplicationBuilder builder) + { + builder.Services.AddScoped(); + builder.Services.AddScoped(); + } + + private static void AddBusinessServices(WebApplicationBuilder builder) + { + builder.Services.AddScoped(); + } + + private static readonly ConcurrentDictionary _staticFilesCache = new(); + + private static bool _firstRequest = true; + private static readonly object LockFirstRequest = new(); + + private static void Configure(WebApplication app) + { + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + IdentityModelEventSource.ShowPII = true; + } + else + { + IdentityModelEventSource.ShowPII = true; + app.UseExceptionHandler("/Error"); + } + + app.UseDefaultFiles(); + app.UseStaticFiles(); + + // configuration on first request + app.Use(async (ctx, next) => + { + var path = ctx.Request.Path; + + GlobalSettings? globalSettings = null; + + if (_firstRequest) + { + // lock + lock (LockFirstRequest) + { + // recheck + if (_firstRequest) + { + _firstRequest = false; + + // set real frontend host + globalSettings = ctx.RequestServices.GetRequiredService(); + globalSettings.Host = GetFrontendHost(ctx); + + // update identity server + var options = ctx.RequestServices.GetRequiredService(); + options.IssuerUri = globalSettings.Host; + + // update identity server client redirect uri + var clients = ctx.RequestServices.GetRequiredService>(); + var client = clients.FirstOrDefault()!; + client.RedirectUris = new List + { + $"{globalSettings.Host}/silent-refresh.html" + }; + } + } + } + + // + if (path.Value.EqualsIgnoreCase("/.well-known/openid-configuration")) + { + globalSettings ??= ctx.RequestServices.GetRequiredService(); + ctx.SetIdentityServerOrigin(globalSettings.Host); + } + + await next(); + }); + + // send index.html to any routes except coreRoutes + var coreRoutes = new[] + { + // API routes + new PathString("/api"), + // Identity server routes + new PathString("/.well-known"), + new PathString("/connect"), + new PathString("/silent-refresh.html") + }; + + var webRootPath = app.Configuration.GetValue(WebHostDefaults.ContentRootKey); + var wwwrootPath = Path.Combine(webRootPath, "wwwroot"); + app.Use(async (context, next) => + { + //app.Logger.LogWarning($"?path: {context.Request.Path}"); + var path = context.Request.Path; + + if (path.Value == null) return; + if (coreRoutes.Any(x => path.StartsWithSegments(x, StringComparison.OrdinalIgnoreCase))) + { + //app.Logger.LogWarning($"*path: {path.Value}"); + await next(); + } + else + { + if (!_staticFilesCache.TryGetValue(path.Value, out var physicalFileInfo)) + { + var segments = path.Value.Split('/', '\\'); + var fileInfo = new FileInfo(Path.Combine(wwwrootPath, segments.LastOrDefault()!)); + if (!fileInfo.Exists) + { + //app.Logger.LogWarning($"-path: {fileInfo.FullName}"); + return; + } + + //app.Logger.LogWarning($"+path: {fileInfo.FullName}"); + physicalFileInfo = new PhysicalFileInfo(fileInfo); + _staticFilesCache.TryAdd(path.Value, physicalFileInfo); + } + + await context.Response.SendFileAsync(physicalFileInfo); + await context.Response.CompleteAsync(); + } + }); + + app.UseCors(builder => builder + .AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod()); + + app.UseIdentityServer(); + app.UseAuthorization(); + + app.MapControllers(); + } + + private static string GetFrontendHost(HttpContext ctx) + { + // get X-Forwarded-Proto when reversed proxy used + // internet <-> nginx (https) <-> site(http) + var host = $"{ctx.Request.Headers["X-Forwarded-Proto"]}"; + + host = host.IsMissing() + ? ctx.Request.IsHttps ? "https" : "http" + : host!; + + host += $"://{ctx.Request.Host.Value}"; + + return host; + } + + private static SigningCredentials CreateSigningCredential() + { + var rsaSecurityKey = new RsaSecurityKey(new RSACryptoServiceProvider(2048)); + var credentials = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSha256); + + return credentials; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Properties/launchSettings.json b/MyOffice.Web/Properties/launchSettings.json new file mode 100644 index 0000000..cc2f5f7 --- /dev/null +++ b/MyOffice.Web/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "profiles": { + "MyOffice.Web": { + "commandName": "Project", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:7097;http://localhost:5097", + "dotnetRunMessages": true + }, + "MyOffice.SPA": { + "commandName": "Project" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS": { + "commandName": "IIS", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iis": { + "applicationUrl": "http://localhost:9100", + "sslPort": 9101 + }, + "iisExpress": { + "applicationUrl": "http://localhost:9100", + "sslPort": 9101 + } + } +} \ No newline at end of file diff --git a/MyOffice.Web/appsettings.json b/MyOffice.Web/appsettings.json new file mode 100644 index 0000000..e229a54 --- /dev/null +++ b/MyOffice.Web/appsettings.json @@ -0,0 +1,31 @@ +{ + "DatabaseProvider": "sqlite", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Kestrel": { + "EndPoints": { + "Http": { + "Url": "http://*:9100" + } + /*, + "Https": { + "Url": "https://*:9101" + }*/ + } + }, + "AllowedHosts": "*", + "ExternalProviders": { + "Auth0": { + "ClientId": "", + "Domain": "", + "SecretKey": "" + }, + "Google": { + "ClientId": "" + } + } +} \ No newline at end of file diff --git a/MyOffice.Web/web.Release.config b/MyOffice.Web/web.Release.config new file mode 100644 index 0000000..a7c2127 --- /dev/null +++ b/MyOffice.Web/web.Release.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MyOffice.Web/web.config b/MyOffice.Web/web.config new file mode 100644 index 0000000..30e51e4 --- /dev/null +++ b/MyOffice.Web/web.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MyOffice.Web/wwwroot/index.html b/MyOffice.Web/wwwroot/index.html new file mode 100644 index 0000000..80b20c7 --- /dev/null +++ b/MyOffice.Web/wwwroot/index.html @@ -0,0 +1,23 @@ + + + + + MyOffice + + + + + + +

DEVELOPER INDEX.HTML

+ + \ No newline at end of file diff --git a/MyOffice.sln b/MyOffice.sln new file mode 100644 index 0000000..665f355 --- /dev/null +++ b/MyOffice.sln @@ -0,0 +1,93 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "MyOffice.SPA", "MyOffice.SPA\MyOffice.SPA.esproj", "{B02D9868-26CB-4E98-95D8-7286BF255F89}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Web", "MyOffice.Web\MyOffice.Web.csproj", "{BCF0590C-5F6A-49BA-A05B-F333865ABEDB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Core", "MyOffice.Core\MyOffice.Core.csproj", "{0347A25D-12D5-4FE0-92F3-102F9F35DCE9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Data.Models", "MyOffice.Data.Models\MyOffice.Data.Models.csproj", "{3D1626CF-1FC3-45D5-A479-65EB955CCFD9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Data.Repositories", "MyOffice.Data.Repositories\MyOffice.Data.Repositories.csproj", "{B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Services", "MyOffice.Services\MyOffice.Services.csproj", "{0442839B-7509-4E76-9EA9-66DAD9F74031}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EF", "EF", "{89463832-F443-478A-AF0D-F2BC209237C8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Migrations.Sqlite", "MyOffice.Migration.Sqlite\MyOffice.Migrations.Sqlite.csproj", "{4CAEC4BF-E3BA-4027-8628-F307075C1D9F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Migrations.Postgres", "MyOffice.Migration.Postgres\MyOffice.Migrations.Postgres.csproj", "{030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.DbContext", "MyOffice.DbContext\MyOffice.DbContext.csproj", "{1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyOffice.Shared", "MyOffice.Shared\MyOffice.Shared.csproj", "{8D8D816F-837D-43CA-8F59-3C78DEB9D48A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{06517FE0-8E41-4124-A482-F21382A62687}" + ProjectSection(SolutionItems) = preProject + gulpfile.js = gulpfile.js + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.Build.0 = Release|Any CPU + {B02D9868-26CB-4E98-95D8-7286BF255F89}.Release|Any CPU.Deploy.0 = Release|Any CPU + {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BCF0590C-5F6A-49BA-A05B-F333865ABEDB}.Release|Any CPU.Build.0 = Release|Any CPU + {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0347A25D-12D5-4FE0-92F3-102F9F35DCE9}.Release|Any CPU.Build.0 = Release|Any CPU + {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D1626CF-1FC3-45D5-A479-65EB955CCFD9}.Release|Any CPU.Build.0 = Release|Any CPU + {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6C7263F-4ED5-4EF3-93E3-25E1A9036A97}.Release|Any CPU.Build.0 = Release|Any CPU + {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0442839B-7509-4E76-9EA9-66DAD9F74031}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0442839B-7509-4E76-9EA9-66DAD9F74031}.Release|Any CPU.Build.0 = Release|Any CPU + {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CAEC4BF-E3BA-4027-8628-F307075C1D9F}.Release|Any CPU.Build.0 = Release|Any CPU + {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Debug|Any CPU.Build.0 = Debug|Any CPU + {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|Any CPU.ActiveCfg = Release|Any CPU + {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18}.Release|Any CPU.Build.0 = Release|Any CPU + {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF}.Release|Any CPU.Build.0 = Release|Any CPU + {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D8D816F-837D-43CA-8F59-3C78DEB9D48A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {4CAEC4BF-E3BA-4027-8628-F307075C1D9F} = {89463832-F443-478A-AF0D-F2BC209237C8} + {030C3E7B-5CED-4A9D-BBE6-A9879F3CDF18} = {89463832-F443-478A-AF0D-F2BC209237C8} + {1EC878BB-CFE1-40AC-A091-0BEE3403DEAF} = {89463832-F443-478A-AF0D-F2BC209237C8} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6EAF5FD7-426A-4EA9-9A73-63854C47CDED} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md new file mode 100644 index 0000000..d8061b9 --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# MyOffice + +**Layers** +Frontend <-> Backend <-> Services <-> Repositories <-> Database + +*1. MyOffice.SPA* +Frontend layer +Angular + +*2. MyOffice.Web* +Backend layer +ASP Core + +*3. MyOffice.Data.Services* +Services layer + +*5. MyOffice.Data.Models* +Models + +*6. MyOffice.Data.Repositories* +Database layer + +*7. MyOffice.DbContext* +AppDbContext +EntityFramework Core + +*8. MyOffice.Migrations.Postgres* +Postgres Migrations + +*9. MyOffice.Migrations.Sqlite* +Sqlite Migrations + + +**DataBase** +1. SQLite +2. PostgreSql +3. MS SQL + +**Develompent** +1. Local IIS +2. Express IIS + +**Authentication & Authorization** + +1. Identity Server 4 +2. Custom UserStore +3. Login with Google +4. Login with Auth0 + +**Build & Deploy** +1. Build with .bat +2. Deploy to Linux + +**Get started** +1. create new project +*dotnet new angular-template.ase.com.ua -p MyProject* +2. Build (restore nuget and npm packages) +3. Run Frontend, in Terminal ".\spa_start.bat" (default http://localhost:4200) +2. Set startup project to MyProject.Web +5. Select 'IIS Express', Run Backend (F5) +6. open in browser http://localhost:4200 + +**add site to IIS** +1. add +Site name:myproject +Physical path:...\MyProject\MyProject.Web +Port:9100 +2. Select 'IIS', Run Backend (F5) + +**Settings** +1. launchSettings.json +2. appsettings +appsettings.json +appsettings.Development.json +appsettings.Production.json + +**External providers** +1. Auth0 +appsettings ExternalProviders:Auth0 +2. Google +appsettings ExternalProviders:Google + +**PowerShell scripts** +1. use 'Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass' to allow run *.ps1 +2. params.txt +2.1. publish_folder=_Published (folder to publish) +2.2. linux_user=root (linux user) +2.3. linux_host=192.168.1.215 (linux host) +2.4. linux_folder=/var/www/MyProject (folder in linux) + +**Build** +1. .\build.ps1 +1.1. '.\build.ps1' - build Backend + Frontend +1.2. '.\build.ps1 dotnet' build Backend +1.3. '.\build.ps1 spa' build Frontend + +**Deploy to linux** +1. linux_deploy.ps1 +1.1. '.\linux_deploy.ps1' - copy to linux and run +1.2. '.\linux_deploy.ps1 copy' copy to linux +1.3. '.\linux_deploy.ps1 run' run at linux diff --git a/add_migration_postgres.bat b/add_migration_postgres.bat new file mode 100644 index 0000000..cf1a3a0 --- /dev/null +++ b/add_migration_postgres.bat @@ -0,0 +1,2 @@ +cd ./MyOffice.Migration.Postgres +dotnet ef migrations add %1 -- %2 \ No newline at end of file diff --git a/add_migration_sqlite.bat b/add_migration_sqlite.bat new file mode 100644 index 0000000..08a4d64 --- /dev/null +++ b/add_migration_sqlite.bat @@ -0,0 +1,2 @@ +cd ./MyOffice.Migration.Sqlite +dotnet ef migrations add %1 -- %2 \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..f08980a --- /dev/null +++ b/build.ps1 @@ -0,0 +1,50 @@ +$params = @{ + "publish_folder" = "_Published" +}; + +function Write2 { + Param ([string] $str1) + + Write-Output "-----------------------------------------------" + Write-Output $str1 + Write-Output "-----------------------------------------------" +} + +function ReadParams { + Param ([string] $str1) + + Get-Content -Path $str1| ForEach-Object { + $x = $_.split('='); + $params[$x[0]] = $x[1]; + } +} + +$publish_folder="_Published" +$params_file="params.txt" + +$dotnet = $args | where { $_ -eq "dotnet" } +$spa = $args | where { $_ -eq "spa" } +$file = $args | where { ($_ -ne "dotnet" -and $_ -ne "spa") } + +if ($file) { + $params_file = $file +} + +ReadParams($params_file) + +if ((!$dotnet) -and (!$spa)) { + $dotnet = "dotnet" + $spa = "spa" +} + +if ($dotnet -eq "dotnet") { + Write2 "dotnet publish" + dotnet publish MyOffice.Web\MyOffice.Web.csproj -c Release -f net6.0 -o $params["publish_folder"] +} +if ($spa -eq "spa") { + Write2 "ng build" + cd MyOffice.SPA + $path = "..\" + $params["publish_folder"] + "\wwwroot" + ng build --output-path $path + cd .. +} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..b51ca03 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,15 @@ +// JavaScript source code + +/// +//"use strict"; + +var gulp = require('gulp'); +var exec = require('child_process').exec; + +gulp.task('test', + function() { + return new Promise(function(resolve, reject) { + console.log('done'); + resolve(); + }); + }); \ No newline at end of file diff --git a/linux_deploy.ps1 b/linux_deploy.ps1 new file mode 100644 index 0000000..fb60b23 --- /dev/null +++ b/linux_deploy.ps1 @@ -0,0 +1,62 @@ +$params = @{ + "publish_folder" = "_Published" +}; + +$params_file="params.txt" + +$linux_run1 = "#!/bin/sh" +$linux_run2 = "cd /var/www/MyOffice/" +$linux_run3 = "dotnet MyOffice.Web.dll" +$linux_run4 = "exit" + +function Write2 { + Param ([string[]] $str1) + + Write-Output "-----------------------------------------------" + Write-Output $str1 + Write-Output "-----------------------------------------------" +} + +function ReadParams { + Param ([string] $str1) + + Get-Content -Path $str1| ForEach-Object { + $x = $_.split('='); + $params[$x[0]] = $x[1]; + } +} + +$copy = $args | where { $_ -eq "copy" } +$run = $args | where { $_ -eq "run" } +$file = $args | where { ($_ -ne "copy" -and $_ -ne "run") } + +if ($file) { + $params_file = $file +} +ReadParams($params_file) + +if ((!$copy) -and (!$run)) { + $copy = "copy" + $run = "run" +} + + +$linux_host = $params["linux_user"] + "@" + $params["linux_host"] +$from = $params["publish_folder"] + "\*" +$to = $linux_host + ":" + $params["linux_folder"] + +if ($copy -eq "copy") { + Write2 "Copy files" + scp -r $from $to +} + +if ($run -eq "run") { + Write2 "Run" + # create run script + $run_file = $params["linux_folder"] + "/run.sh""" + $cmd = """printf '#/bin/sh\ncd " + $params["linux_folder"] + "\ndotnet MyOffice.Web.dll\nexit' > " + $run_file + ssh $linux_host $cmd + + # run and wait + ssh $linux_host bash $run_file +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1c98d5c --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "@ngx-loading-bar/router": "^6.0.2", + "angular-feather": "^6.5.0", + "gulp": "^4.0.2", + "ng-apexcharts": "^1.7.4", + "ngx-mask": "^14.2.4", + "ngx-scrollbar": "^11.0.0" + } +} diff --git a/params.txt b/params.txt new file mode 100644 index 0000000..9257750 --- /dev/null +++ b/params.txt @@ -0,0 +1,4 @@ +publish_folder=_Published +linux_user=root +linux_host=192.168.1.215 +linux_folder=/var/www/MyOffice \ No newline at end of file diff --git a/spa_start.bat b/spa_start.bat new file mode 100644 index 0000000..3bf2fd3 --- /dev/null +++ b/spa_start.bat @@ -0,0 +1,2 @@ +cd MyOffice.SPA +npm start \ No newline at end of file