├── Src
├── Template.WebUI.Client
│ ├── Shared
│ │ ├── AccessDenied.razor
│ │ ├── EmptyLayout.razor
│ │ ├── TopBar.razor
│ │ └── MainLayout.razor
│ ├── wwwroot
│ │ ├── appsettings.Development.json
│ │ ├── favicon.ico
│ │ ├── icon-512.png
│ │ ├── fonts
│ │ │ ├── BHoma.eot
│ │ │ ├── BHoma.ttf
│ │ │ ├── BHoma.woff
│ │ │ ├── BHoma.woff2
│ │ │ ├── Aeonik-Bold.otf
│ │ │ ├── Iran-Yekan.eot
│ │ │ ├── Iran-Yekan.ttf
│ │ │ ├── Iran-Yekan.woff
│ │ │ ├── Aeonik-Light.otf
│ │ │ ├── Aeonik-Medium.otf
│ │ │ ├── Iran-Yekan.woff2
│ │ │ └── Aeonik-Regular.otf
│ │ ├── appsettings.json
│ │ ├── images
│ │ │ ├── layout
│ │ │ │ ├── 404.png
│ │ │ │ ├── user.png
│ │ │ │ ├── user-blue.png
│ │ │ │ ├── ata-header-bg.jpg
│ │ │ │ ├── ata_loading.png
│ │ │ │ ├── ataairlines_main.png
│ │ │ │ ├── ataairlines_white.png
│ │ │ │ ├── logo-header-main.png
│ │ │ │ ├── logo-header-white.png
│ │ │ │ ├── home.svg
│ │ │ │ ├── notifications-white.svg
│ │ │ │ └── home-border.svg
│ │ │ └── pages
│ │ │ │ ├── login
│ │ │ │ └── avatar.png
│ │ │ │ ├── main
│ │ │ │ └── ATA-logo.png
│ │ │ │ └── workflow
│ │ │ │ └── receive-reterive-workflow.jpeg
│ │ ├── css
│ │ │ ├── utils
│ │ │ │ ├── _base.scss
│ │ │ │ ├── _alertify-custom.scss
│ │ │ │ └── _bit-custom.scss
│ │ │ ├── pages
│ │ │ │ ├── settings
│ │ │ │ │ └── _roles-page.scss
│ │ │ │ ├── food
│ │ │ │ │ └── _tbz-food-menu-page.scss
│ │ │ │ ├── dashboard
│ │ │ │ │ └── _dashboard-page.scss
│ │ │ │ └── report
│ │ │ │ │ ├── _personnel-report-page.scss
│ │ │ │ │ └── _report-statistical-page.scss
│ │ │ ├── components
│ │ │ │ ├── _Confirm.scss
│ │ │ │ ├── _Loading.scss
│ │ │ │ └── _Toast.scss
│ │ │ ├── abstracts
│ │ │ │ ├── _variables.scss
│ │ │ │ ├── _functions.scss
│ │ │ │ ├── _mixins.scss
│ │ │ │ ├── _fonts.scss
│ │ │ │ └── _responsive.scss
│ │ │ └── site.scss
│ │ ├── icons
│ │ │ ├── dark_right_arrow.svg
│ │ │ ├── pale_right_arrow.svg
│ │ │ ├── arrow_down.svg
│ │ │ ├── close.svg
│ │ │ ├── toast
│ │ │ │ ├── success-notif-icon.svg
│ │ │ │ ├── error-notif-icon.svg
│ │ │ │ ├── info-notif-icon.svg
│ │ │ │ └── warning-notif-icon.svg
│ │ │ ├── back.svg
│ │ │ ├── close-white.svg
│ │ │ ├── search.svg
│ │ │ ├── close-menu.svg
│ │ │ ├── report.svg
│ │ │ ├── borrows_active.svg
│ │ │ ├── borrows_inactive.svg
│ │ │ ├── comment.svg
│ │ │ ├── pen_gray.svg
│ │ │ ├── pen_white.svg
│ │ │ ├── folder-close.svg
│ │ │ ├── home_active.svg
│ │ │ ├── home_inactive.svg
│ │ │ ├── request_active.svg
│ │ │ ├── request_inactive.svg
│ │ │ ├── dashboard_active.svg
│ │ │ ├── dashboard_inactive.svg
│ │ │ ├── samples_active.svg
│ │ │ ├── samples_inactive.svg
│ │ │ ├── curved_right_arrow.svg
│ │ │ ├── role.svg
│ │ │ ├── folder-open.svg
│ │ │ ├── trash_gray.svg
│ │ │ ├── trash_white.svg
│ │ │ ├── add-circle.svg
│ │ │ ├── logo_inverse.svg
│ │ │ ├── customize.svg
│ │ │ ├── logo_main.svg
│ │ │ ├── import.svg
│ │ │ ├── user.svg
│ │ │ ├── export.svg
│ │ │ └── my-foods.svg
│ │ ├── manifest.json
│ │ ├── service-worker.published.min.js
│ │ ├── service-worker.js
│ │ ├── service-worker.published.js
│ │ └── ImageUrls.cs
│ ├── compilerconfig.json
│ ├── Contracts
│ │ ├── IAppDataService.cs
│ │ └── INotificationService.cs
│ ├── Components
│ │ ├── PageNotFound.razor
│ │ ├── HeaderAddOrEdit.razor.cs
│ │ ├── Confirm.razor
│ │ ├── HeaderAddOrEdit.razor
│ │ ├── Loading.razor
│ │ ├── Confirm.razor.cs
│ │ ├── Modal.razor.cs
│ │ ├── Modal.razor
│ │ ├── Toast.razor
│ │ ├── TelerikComponents
│ │ │ └── CustomDropDownListPopupSettings.cs
│ │ ├── ConfirmDialog.razor.cs
│ │ └── ConfirmDialog.razor
│ ├── Enums
│ │ ├── NotificationType.cs
│ │ ├── OperationType.cs
│ │ └── AlertifyPosition.cs
│ ├── Models
│ │ ├── HostClient.cs
│ │ └── AppData.cs
│ ├── ConfigureServices
│ │ ├── BrokersInstaller.cs
│ │ ├── TelerikInstaller.cs
│ │ ├── ExcelWizardInstaller.cs
│ │ ├── LoadingBarInstaller.cs
│ │ ├── ClientAppSettingsInstaller.cs
│ │ ├── ModalInstaller.cs
│ │ ├── LocalStorageInstaller.cs
│ │ ├── BitInstaller.cs
│ │ ├── NotificationInstaller.cs
│ │ ├── CacheInstaller.cs
│ │ ├── HttpClientFactoryInstaller.cs
│ │ ├── AutoRegisterDiInstaller.cs
│ │ └── AuthInstaller.cs
│ ├── compilerconfig.json.defaults
│ ├── Extensions
│ │ ├── NavigationManagerExtensions.cs
│ │ ├── JsRuntimeExtensions.cs
│ │ └── AuthStateTaskExtensions.cs
│ ├── Implementations
│ │ ├── AppDataService.cs
│ │ └── NotificationService.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── App.razor
│ ├── _Imports.razor
│ ├── Pages
│ │ ├── PageUrls.cs
│ │ └── PageTitles.cs
│ └── Program.cs
├── Template.WebUI.API
│ ├── APIAssemblyEntryPoint.cs
│ ├── IdentityServerCertificate.pfx
│ ├── AppStartup.cs
│ ├── appsettings.Production.json
│ ├── appsettings.json
│ ├── appsettings.Development.json
│ ├── ConfigureServices
│ │ ├── AppSettingsJsonInstaller.cs
│ │ └── NamePatternRegisterInstaller.cs
│ ├── Extensions
│ │ ├── AppModuleExtensions.cs
│ │ └── ATAExceptionToHttpErrorMapper.cs
│ ├── Controllers
│ │ └── Order
│ │ │ └── OrderController.cs
│ ├── ActionFilters
│ │ ├── ATAExceptionHandlerFilterAttribute.cs
│ │ └── ModelStateValidatorAttribute.cs
│ ├── !app_offline.htm
│ ├── Program.cs
│ ├── web.config
│ └── Properties
│ │ └── launchSettings.json
├── Template.Application
│ ├── ApplicationAssemblyEntryPoint.cs
│ ├── Common
│ │ ├── Mappings
│ │ │ ├── MappingExtensions.cs
│ │ │ └── OrderMapperProfile.cs
│ │ ├── Contracts
│ │ │ ├── IStringProvider.cs
│ │ │ └── IInstaller.cs
│ │ ├── Localization
│ │ │ ├── Resources
│ │ │ │ └── StringResourceType.cs
│ │ │ ├── Attributes
│ │ │ │ └── LocalizedRequiredAttribute.cs
│ │ │ └── Extensions
│ │ │ │ └── ValidationContextExtension.cs
│ │ ├── PipelineBehaviours
│ │ │ └── ValidationBehaviour.cs
│ │ └── Implementations
│ │ │ └── StringProvider.cs
│ ├── Order
│ │ ├── Queries
│ │ │ ├── GetOrders
│ │ │ │ └── GetOrdersQuery.cs
│ │ │ └── GetUserLastOrder
│ │ │ │ ├── GetUserLastOrderQuery.cs
│ │ │ │ └── GetUserLastOrderQueryHandler.cs
│ │ └── DTOs
│ │ │ ├── GetOrdersQuery.cs
│ │ │ └── OrderDto.cs
│ ├── User
│ │ └── Queries
│ │ │ └── GetIdentityTokenById
│ │ │ ├── GetIdentityTokenByIdQuery.cs
│ │ │ ├── GetIdentityTokenByIdQueryHandler.cs
│ │ │ └── GetIdentityTokenByIdQueryValidator.cs
│ ├── ConfigureServices
│ │ ├── Installers
│ │ │ ├── AutoMapperInstaller.cs
│ │ │ ├── FluentValidationInstaller.cs
│ │ │ ├── MediatRInstaller.cs
│ │ │ ├── AutoRegisterInstaller.cs
│ │ │ └── LocalizationInstaller.cs
│ │ └── ConfigureServicesExtension.cs
│ ├── CurrentApp
│ │ └── DTOs
│ │ │ └── AppVersioningDto.cs
│ └── Template.Application.csproj
├── Template.Infrastructure
│ ├── Persistence
│ │ ├── EF
│ │ │ ├── DataSeeder.cs
│ │ │ ├── Configuration
│ │ │ │ ├── IdentityEFConfiguration.cs
│ │ │ │ └── OrderEFConfiguration.cs
│ │ │ ├── ATADbContext.cs
│ │ │ └── Repository
│ │ │ │ └── ATARepositoryReadOnly.cs
│ │ └── DbObjects.cs
│ ├── InfrastructureAssemblyEntryPoint.cs
│ ├── Common
│ │ └── Contracts
│ │ │ └── IBitInstaller.cs
│ ├── ConfigureServices
│ │ ├── IdentityInstaller.cs
│ │ ├── ATAInstaller.cs
│ │ ├── LoggerInstaller.cs
│ │ ├── ClientsInstaller.cs
│ │ ├── NamePatternRegisterInstaller.cs
│ │ └── DataAccessInstaller.cs
│ ├── Identity
│ │ └── IdentityClientsProvider.cs
│ └── LogStore
│ │ └── SeqLogStore.cs
└── Template.Domain
│ ├── Options
│ ├── URLOptions.cs
│ ├── ClientAppSettings.cs
│ ├── ConnectionStringOptions.cs
│ ├── AppSettings.cs
│ ├── AuthOptions.cs
│ └── ServerAppSettings.cs
│ ├── Enums
│ └── Order
│ │ ├── ReferenceCity.cs
│ │ ├── OrderOperation.cs
│ │ └── OrderStatus.cs
│ ├── Entities
│ ├── ATAEntity.cs
│ ├── Identity
│ │ └── IdentityTokenEntity.cs
│ └── Order
│ │ └── OrderEntity.cs
│ ├── GlobalUsings.cs
│ ├── Shared
│ ├── AppMetadata.cs
│ ├── AppMessages.cs
│ └── Claims.cs
│ └── Template.Domain.csproj
├── .editorconfig
├── Tests
├── Domain.UnitTests
│ ├── UnitTest1.cs
│ └── Domain.UnitTests.csproj
├── Template.Domain.UnitTests
│ ├── UnitTest1.cs
│ └── Template.Domain.UnitTests.csproj
├── Template.Application.UnitTests
│ ├── UnitTest1.cs
│ └── Template.Application.UnitTests.csproj
└── Template.Application.IntegrationTests
│ ├── UnitTest1.cs
│ └── Template.Application.IntegrationTests.csproj
├── BitConfig.json
├── Clean.bat
├── Directory.build.props
├── Architecture.txt
├── README.md
└── azure-pipelines.yml
/Src/Template.WebUI.Client/Shared/AccessDenied.razor:
--------------------------------------------------------------------------------
1 |
AccessDenied
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/APIAssemblyEntryPoint.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.API;
2 |
3 | public class APIAssemblyEntryPoint
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "ClientAppSettings": {
3 | "URLOptions": {
4 |
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # AsyncFixer03: Fire-and-forget async-void methods or delegates
4 | dotnet_diagnostic.AsyncFixer03.severity = suggestion
5 |
--------------------------------------------------------------------------------
/Src/Template.Application/ApplicationAssemblyEntryPoint.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Application;
2 |
3 | public class ApplicationAssemblyEntryPoint
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/EF/DataSeeder.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Infrastructure.Persistence.EF;
2 |
3 | public static class DataSeeder
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/compilerconfig.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "outputFile": "wwwroot/css/site.css",
4 | "inputFile": "wwwroot/css/site.scss"
5 | }
6 | ]
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/URLOptions.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class URLOptions
4 | {
5 | public string? AppURL { get; set; }
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Shared/EmptyLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 |
3 |
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Mappings/MappingExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Application.Common.Mappings;
2 |
3 | public static class MappingExtensions
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/InfrastructureAssemblyEntryPoint.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Infrastructure;
2 |
3 | public class InfrastructureAssemblyEntryPoint
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/icon-512.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.eot
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.ttf
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.woff
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/ClientAppSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class ClientAppSettings
4 | {
5 | public URLOptions? URLOptions { get; set; }
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/IdentityServerCertificate.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.API/IdentityServerCertificate.pfx
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ClientAppSettings": {
3 | "URLOptions": {
4 | "AppURL": "" //Set automatically in program.cs
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/BHoma.woff2
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Bold.otf
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.eot
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.ttf
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.woff
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/404.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Light.otf
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Medium.otf
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Iran-Yekan.woff2
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/user.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/fonts/Aeonik-Regular.otf
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/ConnectionStringOptions.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class ConnectionStringOptions
4 | {
5 | public string? AppDbConnectionString { get; set; }
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Contracts/IAppDataService.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.Client.Contracts;
2 |
3 | public interface IAppDataService
4 | {
5 | //Task> GetAllLocations();
6 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/user-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/user-blue.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/ata-header-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/ata-header-bg.jpg
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/ata_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/ata_loading.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/pages/login/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/pages/login/avatar.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/pages/main/ATA-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/pages/main/ATA-logo.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/utils/_base.scss:
--------------------------------------------------------------------------------
1 | @import '../abstracts/_variables.scss';
2 | @import '../abstracts/_functions.scss';
3 | @import '../abstracts/_responsive.scss';
4 | @import '../abstracts/_mixins.scss';
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/dark_right_arrow.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/pale_right_arrow.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/ataairlines_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/ataairlines_main.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/ataairlines_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/ataairlines_white.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/logo-header-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/logo-header-main.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/logo-header-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/layout/logo-header-white.png
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/PageNotFound.razor:
--------------------------------------------------------------------------------
1 |
2 |

3 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/AppSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class AppSettings
4 | {
5 | public ServerAppSettings? Server { get; set; }
6 |
7 | public ClientAppSettings? Client { get; set; }
8 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/pages/settings/_roles-page.scss:
--------------------------------------------------------------------------------
1 | @import '../../utils/_base.scss';
2 |
3 | .roles-page {
4 |
5 | .form-custom-wrapper {
6 | margin-bottom: rem(20px);
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Tests/Domain.UnitTests/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Domain.UnitTests
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 |
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/pages/workflow/receive-reterive-workflow.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farshaddavoudi/BitWithCleanArchitectureTemplate/HEAD/Src/Template.WebUI.Client/wwwroot/images/pages/workflow/receive-reterive-workflow.jpeg
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/arrow_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Tests/Template.Domain.UnitTests/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Template.Domain.UnitTests
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 |
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Contracts/IStringProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Application.Common.Contracts;
2 |
3 | public interface IStringProvider
4 | {
5 | string? Message(string messageStringsKey);
6 |
7 | string Exception(string exceptionStringsKey);
8 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Localization/Resources/StringResourceType.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Application.Common.Localization.Resources
2 | {
3 | public enum StringResourceType
4 | {
5 | MessageStrings,
6 |
7 | ExceptionStrings
8 | }
9 | }
--------------------------------------------------------------------------------
/Tests/Template.Application.UnitTests/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Template.Application.UnitTests
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 |
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Contracts/IInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Domain.Options;
2 |
3 | namespace Template.Application.Common.Contracts;
4 |
5 | public interface IInstaller
6 | {
7 | void InstallServices(IServiceCollection services, AppSettings appSettings);
8 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Order/Queries/GetOrders/GetOrdersQuery.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using Template.Application.Order.DTOs;
3 |
4 | namespace Template.Application.Order.Queries.GetOrders;
5 |
6 | public class GetOrdersQuery : IRequest>
7 | {
8 |
9 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Order/Queries/GetUserLastOrder/GetUserLastOrderQuery.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using Template.Application.Order.DTOs;
3 |
4 | namespace Template.Application.Order.Queries.GetUserLastOrder;
5 |
6 | public record GetUserLastOrderQuery(int UserId) : IRequest;
--------------------------------------------------------------------------------
/Tests/Template.Application.IntegrationTests/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Template.Application.IntegrationTests
4 | {
5 | public class UnitTest1
6 | {
7 | [Fact]
8 | public void Test1()
9 | {
10 |
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/AuthOptions.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class AuthOptions
4 | {
5 | public string? MasterPassword { get; set; }
6 |
7 | public bool? EnableDirectLogin { get; set; }
8 |
9 | public bool? IsAppPublic { get; set; }
10 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Enums/NotificationType.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.Client.Enums
2 | {
3 | public enum NotificationType
4 | {
5 | Success,
6 |
7 | Error,
8 |
9 | Message,
10 |
11 | Notify,
12 |
13 | Warning
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Enums/Order/ReferenceCity.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Template.Domain.Enums.Order;
4 |
5 | public enum ReferenceCity
6 | {
7 | [Display(Name = "تهران")]
8 | Tehran = 1,
9 |
10 | [Display(Name = "تبریز")]
11 | Tabriz = 2
12 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/pages/food/_tbz-food-menu-page.scss:
--------------------------------------------------------------------------------
1 | @import '../../utils/_base.scss';
2 |
3 | .change-mode-wrapper {
4 | display: flex;
5 | margin-left: rem(19px);
6 | flex-direction: row-reverse;
7 |
8 | > button {
9 | width: rem(140px);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/HeaderAddOrEdit.razor.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Components;
2 |
3 | namespace Template.WebUI.Client.Components
4 | {
5 | public partial class HeaderAddOrEdit
6 | {
7 | [Parameter]
8 | public RenderFragment ChildContent { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/components/_Confirm.scss:
--------------------------------------------------------------------------------
1 | @import '../utils/_base.scss';
2 |
3 | .confirm-component {
4 |
5 | .buttons-wrapper {
6 | text-align: left;
7 | margin-top: 2rem;
8 | }
9 |
10 | .confirm-button {
11 | margin-left: 0.6rem;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Options/ServerAppSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Options;
2 |
3 | public class ServerAppSettings
4 | {
5 | public ConnectionStringOptions? ConnectionStringOptions { get; set; }
6 |
7 | public URLOptions? URLOptions { get; set; }
8 |
9 | public AuthOptions? AuthOptions { get; set; }
10 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/Entities/ATAEntity.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.Entities.Contracts;
2 | using Bit.Model.Contracts;
3 |
4 | namespace Template.Domain.Entities;
5 |
6 | public abstract class ATAEntity : IATAMiniEntity, IArchivableEntity
7 | {
8 | public int Id { get; set; }
9 |
10 | public bool IsArchived { get; set; }
11 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | //global using CleanArchitecture.Domain.Common;
2 | //global using CleanArchitecture.Domain.Entities;
3 | //global using CleanArchitecture.Domain.Enums;
4 | //global using CleanArchitecture.Domain.Events;
5 | //global using CleanArchitecture.Domain.Exceptions;
6 | //global using CleanArchitecture.Domain.ValueObjects;
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/home.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/notifications-white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Src/Template.Application/User/Queries/GetIdentityTokenById/GetIdentityTokenByIdQuery.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using System.ComponentModel.DataAnnotations.Schema;
3 | using Template.Domain.Entities.Identity;
4 |
5 | namespace Template.Application.DTOs;
6 |
7 | [ComplexType]
8 | public record GetIdentityTokenByIdQuery(int Id) : IRequest;
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/AppStartup.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Bit.OData.Contracts;
3 | using Bit.Owin;
4 | using Template.WebUI.API;
5 |
6 | [assembly: ODataModule("TemplateRoute")]
7 | [assembly: AppModule(typeof(AppModules))]
8 |
9 | namespace Template.WebUI.API;
10 |
11 | public class AppStartup : AspNetCoreAppStartup
12 | {
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/images/layout/home-border.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Models/HostClient.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http;
2 |
3 | namespace Template.WebUI.Client.Models
4 | {
5 | public class HostClient
6 | {
7 | public HttpClient Client { get; }
8 |
9 | public HostClient(HttpClient client)
10 | {
11 | Client = client;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Enums/Order/OrderOperation.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Template.Domain.Enums.Order;
4 |
5 | public enum OrderOperation
6 | {
7 | [Display(Name = "ثبت")]
8 | Add = 0,
9 |
10 | [Display(Name = "ویرایش")]
11 | Update = 1,
12 |
13 | [Display(Name = "حذف")]
14 | Delete = 2
15 | }
16 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/close.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Common/Contracts/IBitInstaller.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Template.Domain.Options;
3 |
4 | namespace Template.Infrastructure.Common.Contracts;
5 |
6 | public interface IBitInstaller
7 | {
8 | void InstallServices(IServiceCollection services,
9 | IDependencyManager dependencyManager,
10 | AppSettings appSettings);
11 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Confirm.razor:
--------------------------------------------------------------------------------
1 |
2 | @ConfirmationMessage
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Shared/TopBar.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
@PageName
4 |
@PageDescription
5 |
6 |
7 | @code
8 | {
9 | [Parameter]
10 | public string PageName { get; set; }
11 |
12 | [Parameter]
13 | public string PageDescription { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/toast/success-notif-icon.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "سامانهی انتخاب غذای آتا",
3 | "short_name": "انتخاب غذای آتا",
4 | "start_url": "./",
5 | "display": "standalone",
6 | "background_color": "#ffffff",
7 | "theme_color": "#03173d",
8 | "icons": [
9 | {
10 | "src": "icon-512.png",
11 | "type": "image/png",
12 | "sizes": "512x512"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Enums/OperationType.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Template.WebUI.Client.Enums;
4 |
5 | public enum OperationType
6 | {
7 | Nothing,
8 |
9 | [Display(Name = "افزودن")]
10 | Add,
11 |
12 | [Display(Name = "فیلتر")]
13 | Edit,
14 |
15 | [Display(Name = "فیلتر")]
16 | Filter,
17 |
18 | Custom1,
19 |
20 | Custom2
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/pages/dashboard/_dashboard-page.scss:
--------------------------------------------------------------------------------
1 | @import '../../utils/_base.scss';
2 |
3 | .dashboard-page {
4 |
5 | .dashboard-grid-operation-wrapper {
6 | text-align: end;
7 | padding: rem(10px);
8 | background-color: $white-four;
9 |
10 | }
11 |
12 | .k-tabstrip-content, .k-tabstrip > .k-content {
13 | border : none;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/service-worker.published.min.js:
--------------------------------------------------------------------------------
1 | "use strict";self.assetsInclude=[/\.svg$/,/FabExMDL*/];self.assetsExclude=[/\.scp\.css$/,/bit\.blazorui\.cupertino\.min\.css$/,/bit\.blazorui\.cupertino\.css$/,/bit\.blazorui\.fluent\.min\.css$/,/bit\.blazorui\.fluent\.css$/,/bit\.blazorui\.material\.min\.css$/,/bit\.blazorui\.material\.css$/];self.defaultUrl="/";self.importScripts("_content/Bit.Tooling.Bswup/bit-bswup.sw.js");
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/BrokersInstaller.cs:
--------------------------------------------------------------------------------
1 | using ATA.Broker.SSOSecurity;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 |
5 | namespace Template.WebUI.Client.ConfigureServices;
6 |
7 | public class BrokersInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | services.AddATASSOClient();
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/TelerikInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 |
4 | namespace Template.WebUI.Client.ConfigureServices
5 | {
6 | public class TelerikInstaller : IInstaller
7 | {
8 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
9 | {
10 | services.AddTelerikBlazor();
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/compilerconfig.json.defaults:
--------------------------------------------------------------------------------
1 | {
2 | "compilers": {
3 | "sass": {
4 | "autoPrefix": "",
5 | "loadPaths": [],
6 | "style": 0,
7 | "precision": 10,
8 | "quiet": true,
9 | "quietDeps": true,
10 | "sourceMap": false
11 | }
12 | },
13 | "minifiers": {
14 | "css": {
15 | "enabled": true,
16 | "termSemicolons": true,
17 | "gzip": false
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/ExcelWizardInstaller.cs:
--------------------------------------------------------------------------------
1 | using ExcelWizard;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 |
5 | namespace Template.WebUI.Client.ConfigureServices;
6 |
7 | public class ExcelWizardInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | services.AddExcelWizardServices(true);
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/appsettings.Production.json:
--------------------------------------------------------------------------------
1 | {
2 | // (Server)AppSettings
3 | "ServerAppSettings": {
4 | "ConnectionStringOptions": {
5 |
6 | },
7 |
8 | "URLOptions": {
9 | "AppURL": "https://food.app.ataair.ir"
10 | },
11 |
12 | "AuthOptions": {
13 | "MasterPassword": "fsrnfata!",
14 | "EnableDirectLogin": true,
15 | "IsAppPublic": true //Meaning it is available to all users
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/abstracts/_variables.scss:
--------------------------------------------------------------------------------
1 | /// Global Variables
2 | @import '_colors.scss';
3 |
4 | // Colors
5 | $themeMainColor: $ATARed; // e.g. #403d7d
6 | $themeLightColor: $ATARed; // e.g. #6a679a
7 | $themeDarkColor: $ATADarkRed; // e.g. #2B2867
8 | $themeGridColor: $pale-chestnut;
9 |
10 | // Fonts
11 | $fontPrimary: aeonik-regular, iranyekan;
12 | $fontPrimaryLight: aeonik-light, iranyekan;
13 | $fontBHoma: bhoma, iranyekan;
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Data": {
3 | "DbIsolationLevel": "ReadCommitted"
4 | },
5 | "Logging": {
6 | "LogLevel": {
7 | "Default": "Information",
8 | "Microsoft": "Warning",
9 | "Microsoft.Hosting.Lifetime": "Information"
10 | }
11 | },
12 | "AllowedHosts": "*",
13 | "IdentityCertificatePassword": "P@ssw0rd",
14 |
15 | // (Server)AppSettings
16 | "ServerAppSettings": {
17 |
18 |
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/toast/error-notif-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/Installers/AutoMapperInstaller.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 |
5 | namespace Template.Application.ConfigureServices.Installers;
6 |
7 | public class AutoMapperInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | services.AddAutoMapper(Assembly.GetExecutingAssembly());
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/toast/info-notif-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/utils/_alertify-custom.scss:
--------------------------------------------------------------------------------
1 | @import '_base.scss';
2 |
3 | .alertify-notifier {
4 | border: 0;
5 | font-family: $fontPrimary;
6 |
7 | &.ajs-center {
8 | left: 62.5%;
9 | }
10 |
11 | .ajs-message {
12 | background-color: $themeMainColor;
13 | color: $white;
14 | text-shadow: -0.5px -0.5px 0 #232e3c;
15 | }
16 | }
17 |
18 | .validation-message {
19 | margin-top: rem(5px);
20 | color: $error-red;
21 | }
22 |
--------------------------------------------------------------------------------
/BitConfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "BitCodeGeneratorConfigs": {
3 | "BitCodeGeneratorMappings": [
4 | {
5 | "GenerationType": "CSharpHttpClient",
6 | "Route": "Food",
7 | "DestinationFileName": "Bit\\ATA.Food.Model.Context",
8 | "SourceProjects": [
9 | {
10 | "Name": "ATA.Food.Server.Api"
11 | }
12 | ],
13 | "DestinationProject": {
14 | "Name": "ATA.Food.Client.Web"
15 | }
16 | }
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/LoadingBarInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 | using Toolbelt.Blazor.Extensions.DependencyInjection;
4 |
5 | namespace Template.WebUI.Client.ConfigureServices
6 | {
7 | public class LoadingBarInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | services.AddLoadingBar();
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Mappings/OrderMapperProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using Template.Application.Order.DTOs;
3 | using Template.Domain.Entities.Order;
4 |
5 | namespace Template.Application.Common.Mappings;
6 |
7 | public class OrderMapperProfile : Profile
8 | {
9 | public OrderMapperProfile()
10 | {
11 | CreateMap()
12 | .ForMember(dto => dto.OrderStatus, config =>
13 | config.MapFrom(entity => (int)entity.OrderStatus));
14 | }
15 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/ClientAppSettingsInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 |
4 | namespace Template.WebUI.Client.ConfigureServices;
5 |
6 | public class ClientAppSettingsInstaller : IInstaller
7 | {
8 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
9 | {
10 | // Directly with injecting ClientAppSettings class
11 | services.AddSingleton(serviceProvider => appSettings);
12 | }
13 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/ModalInstaller.cs:
--------------------------------------------------------------------------------
1 | using Blazored.Modal;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 |
5 | namespace Template.WebUI.Client.ConfigureServices
6 | {
7 | public class ModalInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | // https://github.com/Blazored/Modal
12 | services.AddBlazoredModal();
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | // (Server)AppSettings
3 | "ServerAppSettings": {
4 | "ConnectionStringOptions": {
5 | //"AppDbConnectionString": "Data Source=.;Initial Catalog=ATACatering;Integrated Security=True;"
6 | },
7 |
8 | "URLOptions": {
9 | "AppURL": "localhost:5001"
10 | },
11 |
12 | "AuthOptions": {
13 | "MasterPassword": "ata!",
14 | "EnableDirectLogin": true,
15 | "IsAppPublic": true //Meaning it is available to all users
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/Installers/FluentValidationInstaller.cs:
--------------------------------------------------------------------------------
1 | using FluentValidation;
2 | using System.Reflection;
3 | using Template.Application.Common.Contracts;
4 | using Template.Domain.Options;
5 |
6 | namespace Template.Application.ConfigureServices.Installers;
7 |
8 | public class FluentValidationInstaller : IInstaller
9 | {
10 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
11 | {
12 | services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
13 | }
14 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/service-worker.js:
--------------------------------------------------------------------------------
1 | self.assetsInclude = [
2 | /\.svg$/,
3 | /FabExMDL*/
4 | ];
5 |
6 | self.assetsExclude = [
7 | /\.scp\.css$/,
8 | /bit\.blazorui\.cupertino\.min\.css$/,
9 | /bit\.blazorui\.cupertino\.css$/,
10 | /bit\.blazorui\.fluent\.min\.css$/,
11 | /bit\.blazorui\.fluent\.css$/,
12 | /bit\.blazorui\.material\.min\.css$/,
13 | /bit\.blazorui\.material\.css$/
14 | ];
15 |
16 | self.defaultUrl = "/";
17 |
18 | self.importScripts('_content/Bit.Tooling.Bswup/bit-bswup.sw.js');
19 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/LocalStorageInstaller.cs:
--------------------------------------------------------------------------------
1 | using Blazored.LocalStorage;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 |
5 |
6 | namespace Template.WebUI.Client.ConfigureServices
7 | {
8 | public class LocalStorageInstaller : IInstaller
9 | {
10 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
11 | {
12 | // https://github.com/Blazored/LocalStorage
13 | services.AddBlazoredLocalStorage();
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/Shared/AppMetadata.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | namespace Template.Domain.Shared;
4 |
5 | public static class AppMetadata
6 | {
7 | public static readonly string AppVersion = Assembly.GetExecutingAssembly().GetName().Version!.ToString(3);
8 |
9 | public static readonly string SSOAppName = "food";
10 |
11 | public static readonly string PersianFullName = "سامانهی انتخاب غذای آتا";
12 |
13 | public static readonly string EnglishFullName = "ATA Food";
14 |
15 | public static readonly string SolutionName = "ATA.Food";
16 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/back.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Enums/AlertifyPosition.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Template.WebUI.Client.Enums;
4 |
5 | public enum AlertifyPosition
6 | {
7 | [Display(Name = "top-right")]
8 | TopRight,
9 |
10 | [Display(Name = "top-center")]
11 | TopCenter,
12 |
13 | [Display(Name = "top-left")]
14 | TopLeft,
15 |
16 | [Display(Name = "bottom-right")]
17 | BottomRight,
18 |
19 | [Display(Name = "bottom-center")]
20 | BottomCenter,
21 |
22 | [Display(Name = "bottom-left")]
23 | BottomLeft
24 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/ConfigureServices/AppSettingsJsonInstaller.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Template.Domain.Options;
3 | using Template.Infrastructure.Common.Contracts;
4 |
5 | namespace Template.WebUI.API.ConfigureServices;
6 |
7 | public class AppSettingsJsonInstaller : IBitInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
10 | {
11 | // Register (Server)AppSettings as Singleton to easy use
12 | dependencyManager.RegisterInstance(appSettings);
13 | }
14 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/close-white.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/IdentityInstaller.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.User.Contract;
2 | using Bit.Core.Contracts;
3 | using Template.Domain.Options;
4 | using Template.Infrastructure.Common.Contracts;
5 | using Template.Infrastructure.Identity;
6 |
7 | namespace Template.Infrastructure.ConfigureServices;
8 |
9 | public class IdentityInstaller : IBitInstaller
10 | {
11 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
12 | {
13 | dependencyManager.Register();
14 | }
15 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/Extensions/AppModuleExtensions.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Template.WebUI.API.ActionFilters;
3 |
4 | namespace Template.WebUI.API.Extensions
5 | {
6 | public static class AppModuleExtensions
7 | {
8 | public static IDependencyManager RegisterModelStateValidator(this IDependencyManager dependencyManager)
9 | {
10 | dependencyManager.RegisterGlobalWebApiActionFiltersUsing(webApiConfig =>
11 | webApiConfig.Filters.Add(new ModelStateValidatorAttribute()));
12 |
13 | return dependencyManager;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/BitInstaller.cs:
--------------------------------------------------------------------------------
1 | using Bit.Http.Contracts;
2 | using Bit.Http.Implementations;
3 | using Template.Application.Common.Contracts;
4 | using Template.Domain.Options;
5 |
6 | namespace Template.WebUI.Client.ConfigureServices
7 | {
8 | public class BitInstaller : IInstaller
9 | {
10 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
11 | {
12 | services.AddScoped();
13 | services.AddTransient();
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/HeaderAddOrEdit.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
10 |
11 |
12 |
13 |

14 |
15 |
@ChildContent
16 |
17 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Loading.razor:
--------------------------------------------------------------------------------
1 |
2 | @**@
3 |
4 |
5 |
6 |
7 |
8 |

9 |
10 |
11 | @*
Authorizing ...
*@
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/abstracts/_functions.scss:
--------------------------------------------------------------------------------
1 | $html-font-size: 16px;
2 |
3 | /// stripUnit(10px) -> 10
4 | /// stripUnit(2em) -> 2
5 | /// stripUnit(3) -> 3
6 | @function stripUnit($value) {
7 | @if type-of($value) == 'number' and not unitless($value) {
8 | @return $value / ($value * 0 + 1);
9 | }
10 | @return $value;
11 | }
12 |
13 | /// Convert px to rem.
14 | @function rem($pxValue) {
15 | @return #{stripUnit($pxValue) / stripUnit($html-font-size)}rem;
16 | }
17 |
18 | /// Convert px to em.
19 | @function em($size, $base-font-size: 16px) {
20 | @return stripUnit($size) / stripUnit($base-font-size) * 1em;
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/NotificationInstaller.cs:
--------------------------------------------------------------------------------
1 | using Blazored.Toast;
2 | using Template.Application.Common.Contracts;
3 | using Template.Domain.Options;
4 | using Template.WebUI.Client.Contracts;
5 | using Template.WebUI.Client.Implementations;
6 |
7 | namespace Template.WebUI.Client.ConfigureServices;
8 |
9 | public class NotificationInstaller : IInstaller
10 | {
11 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
12 | {
13 | //https://github.com/Blazored/Toast
14 | services.AddBlazoredToast();
15 |
16 | services.AddTransient();
17 | }
18 | }
--------------------------------------------------------------------------------
/Clean.bat:
--------------------------------------------------------------------------------
1 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S bin') DO RMDIR /S /Q "%%G"
2 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO RMDIR /S /Q "%%G"
3 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S node_modules') DO RMDIR /S /Q "%%G"
4 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S Packages') DO RMDIR /S /Q "%%G"
5 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S .vs') DO RMDIR /S /Q "%%G"
6 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S TestResults') DO RMDIR /S /Q "%%G"
7 | FOR /F "tokens=*" %%G IN ('DIR /B /AD /S AppPackages') DO RMDIR /S /Q "%%G"
8 | DEL /Q /F /S "Resource.designer.cs"
9 | DEL /Q /F /S "*.csproj.user"
10 | DEL /Q /F /S "*.Model.Context.d.ts"
11 | DEL /Q /F /S "*.Model.Context.js"
--------------------------------------------------------------------------------
/Src/Template.Application/Order/DTOs/GetOrdersQuery.cs:
--------------------------------------------------------------------------------
1 | using DNTPersianUtils.Core;
2 | using System.ComponentModel.DataAnnotations.Schema;
3 |
4 | namespace Template.Application.Order.DTOs;
5 |
6 | [ComplexType]
7 | public class GetOrdersQuery
8 | {
9 | public int? CityId { get; set; } //Null means user my-foods report
10 |
11 | public bool IsUserMyFoodsReport => CityId is null;
12 |
13 | public string? SearchTerm { get; set; }
14 |
15 | [ValidPersianDateTime(ErrorMessage = "فرمت تاریخ شمسی معتبر نیست")]
16 | public string? JalaliDate { get; set; }
17 |
18 | public IEnumerable? Locations { get; set; }
19 |
20 | public string? Unit { get; set; }
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Models/AppData.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.Client.Models
2 | {
3 | public class AppData
4 | {
5 | //private List? _locations = new();
6 | //public List Locations
7 | //{
8 | // get => _locations ?? new List();
9 | // set
10 | // {
11 | // _locations = value;
12 | // NotifyDataChanged();
13 | // }
14 | //}
15 |
16 | public string? UserProfileImageUrl { get; set; }
17 |
18 |
19 | public event Action? OnChange;
20 | private void NotifyDataChanged() => OnChange?.Invoke();
21 | }
22 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/CacheInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 | using Template.WebUI.Client.Models;
4 |
5 | namespace Template.WebUI.Client.ConfigureServices
6 | {
7 | public class CacheInstaller : IInstaller
8 | {
9 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
10 | {
11 | // Singleton cash using by directly injecting AppData into a class
12 | var appCache = new AppData();
13 |
14 | services.AddSingleton(sp => appCache);
15 |
16 | //services.AddTransient();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/EF/Configuration/IdentityEFConfiguration.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using Template.Domain.Entities.Identity;
4 |
5 | namespace Template.Infrastructure.Persistence.EF.Configuration;
6 |
7 | public class IdentityEFConfiguration : IEntityTypeConfiguration
8 | {
9 | public void Configure(EntityTypeBuilder builder)
10 | {
11 | // Table
12 | builder.ToTable("IdentityTokens");
13 |
14 | builder.HasKey(t => t.Id);
15 |
16 | // Props
17 | builder.Property(b => b.ClientName).IsRequired().HasMaxLength(100);
18 | }
19 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/close-menu.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Entities/Identity/IdentityTokenEntity.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Entities.Identity;
2 |
3 | public class IdentityTokenEntity : ATAEntity
4 | {
5 | public new int Id { get; set; }
6 |
7 | public string? ClientName { get; set; }
8 |
9 | public DateTimeOffset ExpiresAt { get; set; }
10 |
11 | public DateTimeOffset CreatedAt { get; set; }
12 |
13 | public DateTimeOffset ModifiedAt { get; set; }
14 |
15 | public int UserId { get; set; }
16 |
17 | public string? IPAddress { get; set; }
18 |
19 | public string? DeviceName { get; set; }
20 |
21 | public override string ToString()
22 | {
23 | return $"{nameof(ClientName)}: {ClientName}, UserId: {UserId}";
24 | }
25 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/ATAInstaller.cs:
--------------------------------------------------------------------------------
1 | using ATA.Broker.CDN;
2 | using ATA.Broker.SSOSecurity;
3 | using ATA.Broker.Workflow;
4 | using ATABit.Data;
5 | using Bit.Core.Contracts;
6 | using Template.Domain.Options;
7 | using Template.Infrastructure.Common.Contracts;
8 |
9 | namespace Template.Infrastructure.ConfigureServices;
10 |
11 | public class ATAInstaller : IBitInstaller
12 | {
13 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
14 | {
15 | services.AddATABitDataAccess();
16 |
17 | services.AddATACDN();
18 |
19 | services.AddATASSOClient();
20 |
21 | services.AddATAWorkflowClient();
22 | }
23 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Extensions/NavigationManagerExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Specialized;
2 | using System.Web;
3 | using Microsoft.AspNetCore.Components;
4 |
5 | namespace Template.WebUI.Client.Extensions;
6 |
7 | public static class NavigationManagerExtensions
8 | {
9 | public static NameValueCollection GetQueryStrings(this NavigationManager navigationManager)
10 | {
11 | return HttpUtility.ParseQueryString(new Uri(navigationManager.Uri).Query);
12 | }
13 |
14 | // get single querystring value with specified key
15 | public static string GetQueryString(this NavigationManager navigationManager, string key)
16 | {
17 | return navigationManager.GetQueryStrings()[key];
18 | }
19 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/service-worker.published.js:
--------------------------------------------------------------------------------
1 | self.assetsInclude = [];
2 | self.assetsExclude = [/\.scp\.css$/];
3 | self.defaultUrl = '/';
4 | self.prohibitedUrls = [];
5 | self.assetsUrl = '/service-worker-assets.js';
6 |
7 | // more about SRI (Subresource Integrity) here: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
8 | // online tool to generate integrity hash: https://www.srihash.org/ or https://laysent.github.io/sri-hash-generator/
9 | // using only js to generate hash: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
10 | self.externalAssets = [
11 | {
12 | "url": "/"
13 | },
14 | ];
15 |
16 | self.importScripts('_content/Bit.Tooling.Bswup/bit-bswup.sw.js');
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/report.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/HttpClientFactoryInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 | using Template.WebUI.Client.Implementations;
4 | using Template.WebUI.Client.Models;
5 |
6 | namespace Template.WebUI.Client.ConfigureServices
7 | {
8 | public class HttpClientFactoryInstaller : IInstaller
9 | {
10 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
11 | {
12 | #region Host client
13 |
14 | services.AddScoped(serviceProvider => serviceProvider.GetService()!.Client);
15 |
16 | services.AddScoped();
17 |
18 | #endregion
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Confirm.razor.cs:
--------------------------------------------------------------------------------
1 | using Blazored.Modal;
2 | using Blazored.Modal.Services;
3 | using Microsoft.AspNetCore.Components;
4 |
5 | namespace Template.WebUI.Client.Components
6 | {
7 | public partial class Confirm
8 | {
9 | [Parameter]
10 | public string ConfirmationMessage { get; set; } = "آیا مطمئن هستید؟";
11 |
12 | [CascadingParameter]
13 | private BlazoredModalInstance ConfirmModal { get; set; }
14 |
15 | private async Task OnConfirm()
16 | {
17 | await ConfirmModal.CloseAsync(ModalResult.Ok(true));
18 | }
19 |
20 | private async Task OnCancel()
21 | {
22 | await ConfirmModal.CancelAsync();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/Installers/MediatRInstaller.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using System.Reflection;
3 | using Template.Application.Common.Contracts;
4 | using Template.Application.Common.PipelineBehaviours;
5 | using Template.Domain.Options;
6 |
7 | namespace Template.Application.ConfigureServices.Installers;
8 |
9 | public class MediatRInstaller : IInstaller
10 | {
11 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
12 | {
13 | services.AddMediatR(Assembly.GetExecutingAssembly());
14 |
15 | // MediatR Pipelines (Behaviours)
16 | // Pipelines order matter! Execute from top to bottom
17 | services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
18 | }
19 | }
--------------------------------------------------------------------------------
/Src/Template.Application/CurrentApp/DTOs/AppVersioningDto.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Helper.Extensions;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.ComponentModel.DataAnnotations.Schema;
4 |
5 | namespace Template.Application.DTOs;
6 |
7 | [ComplexType]
8 | public class AppVersioningDto
9 | {
10 | public string? Version { get; set; }
11 | public int VersionNo => Version!.Replace(".", "").ToInt();
12 |
13 | public string? Date { get; set; }
14 |
15 | public List Changes { get; set; } = new();
16 | }
17 |
18 | [ComplexType]
19 | public class VersionChange
20 | {
21 | [Required(ErrorMessage = "Version Change Title Is Required")]
22 | public string? Title { get; set; }
23 |
24 | public List Description { get; set; } = new();
25 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/LoggerInstaller.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Bit.Owin.Implementations;
3 | using System.Reflection;
4 | using Template.Domain.Options;
5 | using Template.Infrastructure.Common.Contracts;
6 | using Template.Infrastructure.LogStore;
7 |
8 | namespace Template.Infrastructure.ConfigureServices;
9 |
10 | public class LoggerInstaller : IBitInstaller
11 | {
12 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
13 | {
14 | dependencyManager.RegisterDefaultLogger(typeof(SeqLogStore).GetTypeInfo()
15 | #if DEBUG
16 | , typeof(DebugLogStore).GetTypeInfo()
17 | , typeof(ConsoleLogStore).GetTypeInfo()
18 | #endif
19 | );
20 | }
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/borrows_active.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/borrows_inactive.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Shared/AppMessages.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Domain.Shared
2 | {
3 | public class AppMessages
4 | {
5 | public class Errors
6 | {
7 | public static string FoodIsDuplicate = "این غذا قبلا در سیستم ثبت شده است";
8 | public static string FoodDeletionFailed = "مشکلی در حذف غذا وجود دارد";
9 | public static string FoodUsedBefore = "از این غذا قبلا استفاده شده و امکان حذف آن وجود ندارد";
10 | public static string FoodIdNotFound = "غذایی با این شناسه پیدا نشد";
11 | }
12 |
13 | public class Success
14 | {
15 | public static string FoodAddedSuccessfully = "غذا با موفقیت ثبت شد";
16 | public static string FoodDeletedSuccessfully = "غذا با موفقیت حذف شد";
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/Controllers/Order/OrderController.cs:
--------------------------------------------------------------------------------
1 | using Bit.OData.ODataControllers;
2 | using MediatR;
3 | using System.Web.Http;
4 | using Template.Application.Order.DTOs;
5 | using Template.Application.Order.Queries.GetUserLastOrder;
6 |
7 | namespace Template.WebUI.API.Controllers.Order;
8 |
9 | [AllowAnonymous]
10 | public class OrderController : DtoController
11 | {
12 | private readonly IMediator _mediator;
13 |
14 | public OrderController(IMediator mediator)
15 | {
16 | _mediator = mediator;
17 | }
18 |
19 | [Function]
20 | public async Task GetFirstOrder(int userId, CancellationToken cancellationToken)
21 | {
22 | var a = await _mediator.Send(new GetUserLastOrderQuery(userId), cancellationToken);
23 |
24 | return a;
25 | }
26 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Modal.razor.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Components;
2 |
3 | namespace Template.WebUI.Client.Components
4 | {
5 | public partial class Modal
6 | {
7 | [Parameter]
8 | public string Title { get; set; }
9 |
10 | [Parameter]
11 | public string Text { get; set; }
12 |
13 | [Parameter]
14 | public RenderFragment ChildContent { get; set; }
15 |
16 | public bool Visibility { get; set; }
17 |
18 | public void ToggleVisibility()
19 | {
20 | Visibility = !Visibility;
21 | }
22 |
23 | public void Show()
24 | {
25 | Visibility = true;
26 | }
27 |
28 | public void Hide()
29 | {
30 | Visibility = false;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/DbObjects.cs:
--------------------------------------------------------------------------------
1 | namespace Template.Infrastructure.Persistence;
2 |
3 | public static class DbSchemas
4 | {
5 | public static readonly string ATA = nameof(ATA);
6 | public static readonly string ATAWorkflowDboSchema = "ATAWorkflow.dbo";
7 | public static readonly string PardisWebDbDboSchema = "PardisWebDB.dbo";
8 | }
9 |
10 | public static class DbViews
11 | {
12 | public static readonly string UsersView = nameof(UsersView);
13 | public static readonly string FoodMenu = nameof(FoodMenu);
14 | public static readonly string UserRolePairsView = nameof(UserRolePairsView);
15 | public static readonly string LocationView = nameof(LocationView);
16 | }
17 |
18 | public static class DbStoredProcedures
19 | {
20 | // public static readonly string SpName = nameof(SpName);
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/toast/warning-notif-icon.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/ActionFilters/ATAExceptionHandlerFilterAttribute.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Web.Http.Filters;
3 | using Bit.Owin.Contracts;
4 | using Bit.WebApi.ActionFilters;
5 |
6 | namespace Template.WebUI.API.ActionFilters;
7 |
8 | public class ATAExceptionHandlerFilterAttribute : ExceptionHandlerFilterAttribute
9 | {
10 | protected override HttpResponseMessage CreateErrorResponseMessage(HttpActionExecutedContext actionExecutedContext, IExceptionToHttpErrorMapper exceptionToHttpErrorMapper, Exception exception)
11 | {
12 | return new HttpResponseMessage
13 | {
14 | Content = new StringContent(exceptionToHttpErrorMapper.GetMessage(actionExecutedContext.Exception), Encoding.UTF8, "application/json"),
15 | StatusCode = exceptionToHttpErrorMapper.GetStatusCode(exception)
16 | };
17 | }
18 | }
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/ConfigureServicesExtension.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable CheckNamespace
2 |
3 | using System.Reflection;
4 | using Template.Application.Common.Contracts;
5 | using Template.Domain.Options;
6 |
7 | namespace Microsoft.Extensions.DependencyInjection;
8 |
9 | public static class ConfigureServicesExtension
10 | {
11 | public static IServiceCollection AddApplicationServices(this IServiceCollection services, AppSettings appSettings)
12 | {
13 | var installers = Assembly.GetExecutingAssembly().GetExportedTypes()
14 | .Where(c => c.IsClass && !c.IsAbstract && c.IsPublic && typeof(IInstaller).IsAssignableFrom(c))
15 | .Select(Activator.CreateInstance).Cast().ToList();
16 |
17 | installers.ForEach(i => i.InstallServices(services, appSettings));
18 |
19 | return services;
20 | }
21 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/!app_offline.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
19 |
20 |
21 |
22 |
23 |
این سامانه در حال بروزرسانی است
24 |
لطفا چند دقیقهی بعد مراجعه نمایید.
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Src/Template.Application/User/Queries/GetIdentityTokenById/GetIdentityTokenByIdQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.Data.Contracts;
2 | using MediatR;
3 | using Template.Domain.Entities.Identity;
4 |
5 | namespace Template.Application.DTOs;
6 |
7 | public class GetIdentityTokenByIdQueryHandler : IRequestHandler
8 | {
9 | private readonly IATARepository _identityTokenRepository;
10 |
11 | public GetIdentityTokenByIdQueryHandler(IATARepository identityTokenRepository)
12 | {
13 | _identityTokenRepository = identityTokenRepository;
14 | }
15 |
16 | public Task Handle(GetIdentityTokenByIdQuery request, CancellationToken cancellationToken)
17 | {
18 | return _identityTokenRepository.GetByIdAsync(request.Id, cancellationToken);
19 | }
20 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/Enums/Order/OrderStatus.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace Template.Domain.Enums.Order;
4 |
5 | public enum OrderStatus
6 | {
7 | [Display(Name = "ثبت شده")]
8 | Confirmed = 0,
9 |
10 | [Display(Name = "حذف مستقیم توسط کاربر")]
11 | DeletedDirectlyByUser = 1,
12 |
13 | [Display(Name = "حذف بدلیل ویرایش غذا توسط کاربر")]
14 | DeletedBecauseOfFoodUpdateByUser = 2,
15 |
16 | [Display(Name = "حذف بدلیل تغییر برنامه غذایی")]
17 | DeletedBecauseOfGroupDeleteByCatering = 3,
18 |
19 | [Display(Name = "حذف بدلیل تغییر برنامه غذایی")]
20 | DeletedBecauseOfCalendarFoodChangeByCatering = 4
21 | }
22 |
23 | public static class OrderStatusExtensions
24 | {
25 | public static bool IsDelete(this OrderStatus orderStatus)
26 | {
27 | return orderStatus != OrderStatus.Confirmed;
28 | }
29 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Localization/Attributes/LocalizedRequiredAttribute.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using ATA.Food.Shared.Localization.Resources.DataAnnotations;
3 |
4 | namespace Template.Application.Common.Localization.Attributes
5 | {
6 | public class LocalizedRequiredAttribute : RequiredAttribute
7 | {
8 | public LocalizedRequiredAttribute()
9 | {
10 | ErrorMessageResourceType = typeof(DataAnnotationStrings);
11 | ErrorMessageResourceName = nameof(DataAnnotationStrings.RequiredAttribute_ValidationError);
12 | }
13 |
14 | public LocalizedRequiredAttribute(string dataAnnotationStringsResourceKey)
15 | {
16 | ErrorMessageResourceType = typeof(DataAnnotationStrings);
17 | ErrorMessageResourceName = dataAnnotationStringsResourceKey;
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/Program.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core;
2 | using Bit.Owin;
3 | using Bit.Owin.Implementations;
4 |
5 | namespace Template.WebUI.API;
6 |
7 | public class Program
8 | {
9 | public static Task Main(string[] args)
10 | {
11 | AssemblyContainer.Current.Init();
12 |
13 | AssemblyContainer.Current.AddAppAssemblies(typeof(Program).Assembly);
14 |
15 | AspNetCoreAppEnvironmentsProvider.Current.Use();
16 |
17 | return CreateHostBuilder(args)
18 | .Build()
19 | .RunAsync();
20 | }
21 |
22 | public static IHostBuilder CreateHostBuilder(string[] args) =>
23 | BitWebHost.CreateWebHost(args)
24 | .ConfigureWebHostDefaults(webHostBuilder =>
25 | {
26 | #if Development
27 | webHostBuilder.UseUrls("http://*:5000/", "https://*:5001/");
28 | #endif
29 | });
30 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Implementations/AppDataService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http;
2 | using Template.WebUI.Client.Contracts;
3 | using Template.WebUI.Client.Models;
4 |
5 | namespace Template.WebUI.Client.Implementations;
6 |
7 | public class AppDataService : IAppDataService
8 | {
9 | private AppData _appData;
10 | private HttpClient _httpClient;
11 |
12 | public AppDataService(AppData appData, HttpClient httpClient)
13 | {
14 | _appData = appData;
15 | _httpClient = httpClient;
16 | }
17 |
18 | //public async Task> GetAllLocations()
19 | //{
20 | // List locations = new();
21 |
22 | // if (_appData.Locations.Any() is false)
23 | // locations = await _httpClient.Location().GetAllLocations();
24 | // else
25 | // locations = _appData.Locations;
26 |
27 | // return locations;
28 | //}
29 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Identity/IdentityClientsProvider.cs:
--------------------------------------------------------------------------------
1 | using Bit.IdentityServer.Contracts;
2 | using Bit.IdentityServer.Implementations;
3 | using Template.Domain.Shared;
4 |
5 | namespace Template.Infrastructure.Identity
6 | {
7 | public class IdentityClientsProvider : OAuthClientsProvider
8 | {
9 | public override IEnumerable GetClients()
10 | {
11 | return new[]
12 | {
13 | GetResourceOwnerFlowClient(new BitResourceOwnerFlowClient
14 | {
15 | ClientName = AppConstants.WebApp.ClientName,
16 | ClientId = AppConstants.WebApp.ClientId,
17 | Secret = AppConstants.WebApp.Secret,
18 | TokensLifetime = AppConstants.AuthToken.Lifetime,
19 | Enabled = true
20 | })
21 | };
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Modal.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Tests/Domain.UnitTests/Domain.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 |
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 | all
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 | all
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Template.Domain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | all
32 | runtime; build; native; contentfiles; analyzers
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/comment.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/EF/Configuration/OrderEFConfiguration.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.EntityFrameworkCore.Metadata.Builders;
3 | using Template.Domain.Entities.Order;
4 | using Template.Domain.Enums.Order;
5 |
6 | namespace Template.Infrastructure.Persistence.EF.Configuration;
7 |
8 | public class OrderEFConfiguration : IEntityTypeConfiguration
9 | {
10 | public void Configure(EntityTypeBuilder builder)
11 | {
12 | // Table
13 | builder.ToTable("FoodOrder", DbSchemas.ATA);
14 |
15 | builder.HasKey(b => b.Id);
16 |
17 | // Props
18 | builder.Property(b => b.Id).HasColumnType("bigint");
19 |
20 | builder.Property(b => b.OrderStatus).HasDefaultValue(OrderStatus.Confirmed);
21 |
22 | builder.Property(b => b.GroupCalendarId).HasColumnType("bigint");
23 |
24 | builder.Property(b => b.UserPersonnelCode).HasColumnName("EmployeeCode").HasColumnType("bigint");
25 |
26 | builder.Property(b => b.UserFullName).HasMaxLength(20);
27 | }
28 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:65189",
7 | "sslPort": 44398
8 | }
9 | },
10 | "profiles": {
11 | "Template.WebUI.Client": {
12 | "commandName": "Project",
13 | "dotnetRunMessages": true,
14 | "launchBrowser": true,
15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
16 | "applicationUrl": "https://localhost:7298;http://localhost:5298",
17 | "environmentVariables": {
18 | "ASPNETCORE_ENVIRONMENT": "Development"
19 | }
20 | },
21 | "IIS Express": {
22 | "commandName": "IISExpress",
23 | "launchBrowser": true,
24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/Toast.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 | @Message
8 |
9 |
10 |
11 | @code {
12 | [CascadingParameter] private BlazoredToast ToastInstance { get; set; }
13 |
14 | [Parameter] public NotificationType NotifType { get; set; }
15 |
16 | [Parameter] public string Message { get; set; }
17 |
18 | string _iconUrl;
19 |
20 | protected override void OnInitialized()
21 | {
22 | _iconUrl = NotifType switch
23 | {
24 | NotificationType.Success => IconUrls.SuccessToast,
25 | NotificationType.Error => IconUrls.ErrorToast,
26 | NotificationType.Warning => IconUrls.WarningToast,
27 | NotificationType.Notify => IconUrls.InfoToast,
28 | NotificationType.Message => IconUrls.InfoToast,
29 | _ => _iconUrl
30 | };
31 |
32 | base.OnInitialized();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/ImageUrls.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.Client.wwwroot;
2 |
3 | public static class ImageUrls
4 | {
5 | public static class Layout
6 | {
7 | public const string LogoHeaderWhite = "/images/layout/logo-header-white.png";
8 | public const string LogoHeaderMain = "/images/layout/logo-header-main.png";
9 | public const string AtaAirlinesLogoMain = "/images/layout/ataairlines_main.png";
10 | public const string AtaAirlinesLogoWhite = "/images/layout/ataairlines_white.png";
11 | public const string NotificationsWhite = "/images/layout/notifications-white.svg";
12 | public const string ATALoading = "/images/layout/ata_loading.png";
13 | public const string PageNotFound404 = "/images/layout/404.png";
14 | }
15 |
16 | public static class Pages
17 | {
18 | public const string SelectFoodBanner = "/images/pages/food/desktop-banner.png";
19 | public const string SelectFoodBannerMobile = "/images/pages/food/mobile-banner.png";
20 | public const string SelectFoodSpoonAndFork = "/images/pages/food/spoon-fork.png";
21 | }
22 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/pen_gray.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/pen_white.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/utils/_bit-custom.scss:
--------------------------------------------------------------------------------
1 | @import '_base.scss';
2 |
3 | /*#region BitDropDown */
4 |
5 | .bit-drp-fluent {
6 | font-family: $fontPrimary;
7 |
8 | .bit-drp-wrapper {
9 | .bit-drp-wrapper-txt {
10 | border: 1px solid $pinkish-grey;
11 | height: rem(40px);
12 | display: flex;
13 | align-items: center;
14 | }
15 |
16 | .bit-drp-wrapper-ic {
17 | top: rem(5px);
18 | }
19 | }
20 |
21 | .bit-drp-items-wrapper {
22 | .rtl & {
23 | left: unset !important;
24 | width: rem(460px);
25 | }
26 |
27 | .bit-chb-fluent {
28 | .bit-chb-txt {
29 | .rtl & {
30 | font-family: $fontPrimary;
31 | color: $dark;
32 | margin-right: 0.25rem;
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
39 | /*#endregion BitDropDown*/
40 |
41 | /*#region BitSpinner */
42 |
43 | .bit-spn-fluent > div:first-child {
44 | border-top-color: $boulder;
45 | }
46 | /*#endregion BitSpinner*/
47 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/abstracts/_mixins.scss:
--------------------------------------------------------------------------------
1 | @import '_variables.scss';
2 | @import '_functions.scss';
3 | @import '_responsive.scss';
4 |
5 | // Global Mixins
6 |
7 | @mixin removeButtonDefaultStyle {
8 | border: none;
9 | outline: none;
10 | white-space: nowrap;
11 | text-decoration: none;
12 | font-family: 'aeonik-regular';
13 | cursor: pointer;
14 |
15 | &:hover {
16 | text-decoration: none;
17 | }
18 |
19 | &:focus {
20 | outline: none;
21 | }
22 | }
23 |
24 | @mixin removeLinkDefaultStyle {
25 | cursor: pointer;
26 |
27 | &:hover {
28 | text-decoration: none;
29 | }
30 | }
31 |
32 | @mixin border($bcolor: $pinkish-grey) {
33 | border: rem(0.5px) solid $bcolor;
34 | border-radius: rem(2px);
35 | box-sizing: border-box;
36 | }
37 |
38 | @mixin defaultButtonStyle {
39 | @include removeButtonDefaultStyle;
40 | border-radius: 2px;
41 | font-size: rem(14px);
42 | font-family: $fontPrimary;
43 | height: rem(40px);
44 | line-height: 40px;
45 | display: flex;
46 | align-items: center;
47 | width: rem(140px);
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/Extensions/ATAExceptionToHttpErrorMapper.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Server.Extensions;
2 | using ATABit.Shared.Exceptions;
3 | using Bit.Owin.Implementations;
4 | using Bit.Owin.Metadata;
5 | using System.Net;
6 |
7 | namespace Template.WebUI.API.Extensions
8 | {
9 | public class ATAExceptionToHttpErrorMapper : DefaultExceptionToHttpErrorMapper
10 | {
11 | public override HttpStatusCode GetStatusCode(Exception exp)
12 | {
13 | if (exp is ValidationException)
14 | return HttpStatusCode.BadRequest;
15 |
16 | //if (exp is InvalidTokenException)
17 | // return HttpStatusCode.BadRequest;
18 |
19 | return base.GetStatusCode(exp);
20 | }
21 |
22 | public override string GetMessage(Exception exp)
23 | {
24 | exp = UnWrapException(exp);
25 |
26 | string? messageToShow = BitMetadataBuilder.UnknownError;
27 |
28 | if (IsKnownError(exp))
29 | {
30 | messageToShow = exp.GetModelErrorWrapper();
31 | }
32 |
33 | return messageToShow ?? "";
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Src/Template.Application/Order/Queries/GetUserLastOrder/GetUserLastOrderQueryHandler.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.Data.Contracts;
2 | using AutoMapper;
3 | using AutoMapper.QueryableExtensions;
4 | using MediatR;
5 | using Microsoft.EntityFrameworkCore;
6 | using Template.Application.Order.DTOs;
7 | using Template.Domain.Entities.Order;
8 |
9 | namespace Template.Application.Order.Queries.GetUserLastOrder;
10 |
11 | public class GetUserLastOrderQueryHandler : IRequestHandler
12 | {
13 | private readonly IATARepository _orderRepository;
14 | private readonly IMapper _mapper;
15 |
16 | public GetUserLastOrderQueryHandler(IATARepository orderRepository, IMapper mapper)
17 | {
18 | _orderRepository = orderRepository;
19 | _mapper = mapper;
20 | }
21 |
22 | public Task Handle(GetUserLastOrderQuery request, CancellationToken cancellationToken)
23 | {
24 | return _orderRepository.GetAll()
25 | .Where(o => o.UserId == request.UserId)
26 | .ProjectTo(_mapper.ConfigurationProvider)
27 | .FirstOrDefaultAsync(cancellationToken);
28 | }
29 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/TelerikComponents/CustomDropDownListPopupSettings.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using Microsoft.AspNetCore.Components;
3 | using Telerik.Blazor.Components;
4 |
5 | namespace ATA.Food.Client.Web.Components.TelerikComponents;
6 |
7 | public class CustomDropDownListPopupSettings : DropDownListPopupSettings
8 | {
9 | [Parameter] [Required] public bool HasDefaultText { get; set; }
10 | [Parameter] [Required] public int ItemsCount { get; set; }
11 |
12 | protected override Task OnParametersSetAsync()
13 | {
14 | Height = CalculatePopUpHeight();
15 | Class = "form-dropdown-popup";
16 | return base.OnParametersSetAsync();
17 | }
18 |
19 | private string CalculatePopUpHeight()
20 | {
21 | int paddingHeight = HasDefaultText ? 47 : 20;
22 | int itemHeight = 40;
23 | int maxHeight = 210;
24 |
25 | int itemsHeight = (ItemsCount == 0 ? 1 : ItemsCount) * itemHeight;
26 | int popUpHeight = itemsHeight + paddingHeight;
27 |
28 | int height = popUpHeight > maxHeight ? maxHeight : popUpHeight;
29 |
30 | return $"{height}px";
31 | }
32 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/folder-close.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/home_active.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/home_inactive.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/App.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | @code
33 | {
34 | protected override async Task OnInitializedAsync()
35 | {
36 | //await JsRuntime.InvokeVoidAsync("addSignature");
37 | }
38 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/AutoRegisterDiInstaller.cs:
--------------------------------------------------------------------------------
1 | using NetCore.AutoRegisterDi;
2 | using System.Reflection;
3 | using Template.Application.Common.Contracts;
4 | using Template.Domain.Options;
5 |
6 | namespace Template.WebUI.Client.ConfigureServices
7 | {
8 | public class AutoRegisterDiInstaller : IInstaller
9 | {
10 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
11 | {
12 | var webAssembly = Assembly.GetExecutingAssembly();
13 | var clientWebServiceAssembly = typeof(ClientAppSettings).Assembly;
14 |
15 | var assembliesToScan = new[] { webAssembly, clientWebServiceAssembly };
16 |
17 | #region Generic Type Dependencies
18 | //services.AddScoped(typeof(IRepository<>), typeof(EfCoreRepositoryBase<,>));
19 | #endregion
20 |
21 |
22 | #region Register DIs By Name
23 | services.RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
24 | .Where(c => c.Name.EndsWith("Service"))
25 | .AsPublicImplementedInterfaces(ServiceLifetime.Scoped);
26 | #endregion
27 |
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/Src/Template.Application/User/Queries/GetIdentityTokenById/GetIdentityTokenByIdQueryValidator.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.Data.Contracts;
2 | using FluentValidation;
3 | using Template.Domain.Entities.Identity;
4 |
5 | namespace Template.Application.DTOs;
6 |
7 | public class GetIdentityTokenByIdQueryValidator : AbstractValidator
8 | {
9 | private readonly IATARepository _identityTokenRepository;
10 |
11 | public GetIdentityTokenByIdQueryValidator(IATARepository identityTokenRepository)
12 | {
13 | _identityTokenRepository = identityTokenRepository;
14 |
15 | //RuleFor(v => v.Title)
16 | // .NotEmpty().WithMessage("Title is required.")
17 | // .MaximumLength(200).WithMessage("Title must not exceed 200 characters.")
18 | // .MustAsync(BeUniqueTitle).WithMessage("The specified title already exists.");
19 | }
20 |
21 | public async Task BeUniqueTitle(string title, CancellationToken cancellationToken)
22 | {
23 | return await Task.FromResult(true);
24 | //return await _context.TodoLists
25 | // .AllAsync(l => l.Title != title, cancellationToken);
26 | }
27 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/request_active.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/request_inactive.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using System.Net.Http
2 | @using System.Net.Http.Json
3 | @using Microsoft.AspNetCore.Components.Forms
4 | @using Microsoft.AspNetCore.Components.Routing
5 | @using Microsoft.AspNetCore.Components.Web
6 | @using Microsoft.AspNetCore.Components.Web.Virtualization
7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http
8 | @using Microsoft.JSInterop
9 | @using Template.WebUI.Client
10 | @using Template.WebUI.Client.Shared
11 |
12 | @* Libs Usings *@
13 | @using Bit_.View
14 | @using Blazored.Toast
15 | @using Blazored.Toast.Services
16 | @using Blazored.Modal
17 | @using Blazored.Modal.Services
18 | @using Telerik.Blazor
19 | @using Telerik.Blazor.Components
20 | @using Radzen
21 | @using Radzen.Blazor
22 | @using Blazor.PersianDatePicker
23 | @using Blazor.PersianDatePicker.Extensions
24 | @using ATABit.Helper;
25 | @using Bit.Client.Web.BlazorUI
26 | @using Microsoft.AspNetCore.Components.Authorization
27 | @using Blazored.Toast.Configuration
28 |
29 | @* Project Usings *@
30 | @using Template.WebUI.Client.Components
31 | @using Template.Domain.Shared
32 | @using Template.WebUI.Client.wwwroot
33 | @using Template.WebUI.Client.Pages
34 | @using Template.WebUI.Client.Extensions
35 | @using Template.WebUI.Client.Enums
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/ClientsInstaller.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Template.Domain.Options;
3 | using Template.Infrastructure.Common.Contracts;
4 |
5 | // ReSharper disable once ObjectCreationAsStatement
6 |
7 | namespace Template.Infrastructure.ConfigureServices;
8 |
9 | public class ClientsInstaller : IBitInstaller
10 | {
11 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
12 | {
13 | //// SSO Client
14 | //services.AddHttpClient(client =>
15 | //{
16 | // client.BaseAddress = new Uri(serverAppSettings.URLOptions!.SSOClient!);
17 | //});
18 |
19 | //// HR Client
20 | //services.AddHttpClient(client =>
21 | //{
22 | // string hrClientBaseUrl = AspNetCoreAppEnvironmentsProvider.Current.HostingEnvironment.IsDevelopment()
23 | // ? "https://dummy.com/" //Doesn't matter
24 | // : serverAppSettings.URLOptions!.HRClient!;
25 |
26 | // client.BaseAddress = new Uri(hrClientBaseUrl);
27 | // client.DefaultRequestHeaders.Add("api_key", serverAppSettings.HRClientOptions?.APIKey);
28 | //});
29 | }
30 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/site.scss:
--------------------------------------------------------------------------------
1 | // Abstracts
2 | @import 'abstracts/_variables.scss';
3 | @import 'abstracts/_responsive.scss';
4 | @import 'abstracts/_fonts.scss';
5 |
6 | // Vendors
7 | @import 'vendors/bootstrap/bootstrap-grid.min.css';
8 | @import 'vendors/alertify/alertify.min.css';
9 |
10 | // Utils
11 | @import 'utils/_helpers.scss';
12 | @import 'utils/_radzen-custom.scss';
13 | @import 'utils/_telerik-custom.scss';
14 | @import 'utils/_bit-custom.scss';
15 | @import 'utils/_alertify-custom.scss';
16 | @import 'utils/_shared.scss';
17 |
18 | // Layouts
19 | @import "layout/_header.scss";
20 | @import "layout/_sidebar.scss";
21 | @import "layout/_content.scss";
22 |
23 | // Components
24 | @import 'components/_Confirm.scss';
25 | @import 'components/_Loading.scss';
26 | @import 'components/_Toast.scss';
27 |
28 | // Pages
29 | @import 'pages/dashboard/_dashboard-page.scss';
30 | @import 'pages/dashboard/_flowForm-page.scss';
31 | @import 'pages/settings/_roles-page.scss';
32 | @import 'pages/report/_report-statistical-page.scss';
33 | @import 'pages/report/_personnel-report-page.scss';
34 | @import 'pages/food/_tbz-food-menu-page.scss';
35 | @import 'pages/food/_select-food-page.scss';
36 | @import 'pages/calendar/_food-calendar-page.scss';
37 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/NamePatternRegisterInstaller.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Bit.Core.Contracts;
3 | using System.Reflection;
4 | using Template.Domain.Options;
5 | using Template.Infrastructure.Common.Contracts;
6 |
7 | namespace Template.Infrastructure.ConfigureServices;
8 |
9 | ///
10 | /// Register Assembly Public NonAbstract Classes with PropertyInjection enabled
11 | ///
12 | public class NamePatternRegisterInstaller : IBitInstaller
13 | {
14 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
15 | {
16 | dependencyManager
17 | .GetContainerBuilder()
18 | .RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
19 | .PublicOnly()
20 | .Where(type =>
21 | type.IsClass &&
22 | !type.IsAbstract &&
23 | (type.Name.EndsWith("Service") || type.Name.EndsWith("Repository")) &&
24 | type.Name != "EntityService")
25 | .AsSelf()
26 | .As(t => t.BaseType!)
27 | .AsImplementedInterfaces()
28 | .PropertiesAutowired(PropertyWiringOptions.PreserveSetValues)
29 | .PreserveExistingDefaults();
30 | }
31 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Pages/PageUrls.cs:
--------------------------------------------------------------------------------
1 | namespace Template.WebUI.Client.Pages;
2 |
3 | public static class PageUrls
4 | {
5 | public const string SelectFoodPage = "/";
6 |
7 | public static string FlowFormsPage(int paramRequestId) => $"/flow-forms/{paramRequestId}";
8 | public const string LogsPage = "/logs";
9 |
10 | public const string ReportsRootPath = "/reports";
11 | public const string MyFoodsReport = $"{ReportsRootPath}/personnel";
12 | public static string PersonnelReportPage(string city) => $"{ReportsRootPath}/personnel/{city}";
13 | public static string StatisticalReportPage(string city) => $"{ReportsRootPath}/statistical/{city}";
14 | public static string GuestsReportPage(string city) => $"{ReportsRootPath}/guests/{city}";
15 |
16 | public const string FoodManagementRootPath = "/foods";
17 | public const string FoodMenuPage = $"{FoodManagementRootPath}/food-menu";
18 | public static string FoodCalendarPage(string city) => $"{FoodManagementRootPath}/food-calendar/{city}";
19 |
20 | public const string SettingsRootPath = "/settings";
21 | public const string UsersPage = $"{SettingsRootPath}/users";
22 | public const string RolesPage = $"{SettingsRootPath}/roles";
23 | public const string WorkflowPage = $"{SettingsRootPath}/workflow";
24 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/ConfigureServices/NamePatternRegisterInstaller.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Bit.Core.Contracts;
3 | using Template.Domain.Options;
4 | using Template.Infrastructure.Common.Contracts;
5 |
6 | namespace Template.WebUI.API.ConfigureServices
7 | {
8 | ///
9 | /// Register Assembly Public NonAbstract Classes with PropertyInjection enabled
10 | ///
11 | public class NamePatternRegisterInstaller : IBitInstaller
12 | {
13 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
14 | {
15 | dependencyManager
16 | .GetContainerBuilder()
17 | .RegisterAssemblyTypes(typeof(APIAssemblyEntryPoint).Assembly)
18 | .PublicOnly()
19 | .Where(type =>
20 | type.IsClass &&
21 | !type.IsAbstract &&
22 | type.Name.EndsWith("Service") &&
23 | type.Name != "EntityService")
24 | .AsSelf()
25 | .As(t => t.BaseType!)
26 | .AsImplementedInterfaces()
27 | .PropertiesAutowired(PropertyWiringOptions.PreserveSetValues)
28 | .PreserveExistingDefaults();
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/ActionFilters/ModelStateValidatorAttribute.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Server.Extensions;
2 | using ATABit.Shared;
3 | using ATABit.Shared.Exceptions;
4 | using Bit.Core.Contracts;
5 | using Microsoft.Owin;
6 | using System.Web.Http.Controllers;
7 | using System.Web.Http.Filters;
8 | using ILogger = Bit.Core.Contracts.ILogger;
9 |
10 | namespace Template.WebUI.API.ActionFilters
11 | {
12 | public class ModelStateValidatorAttribute : ActionFilterAttribute
13 | {
14 | public override void OnActionExecuting(HttpActionContext actionContext)
15 | {
16 | if (actionContext.ModelState is null)
17 | throw new ArgumentNullException(nameof(actionContext.ModelState));
18 |
19 | if (actionContext.ModelState.IsValid | actionContext.Request.Method == HttpMethod.Get /*workaround*/)
20 | return;
21 |
22 | IDependencyResolver dependencyResolver = actionContext.Request.GetOwinContext().GetDependencyResolver();
23 | var logger = dependencyResolver.Resolve();
24 |
25 | ModelErrorWrapper modelErrorWrapper = actionContext.ModelState.GetModelErrors();
26 | logger.AddLogData("ModelError", modelErrorWrapper);
27 |
28 | throw new ValidationException(modelErrorWrapper);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Directory.build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | Client
4 |
5 | $(DefineConstants);BlazorClient
6 |
7 |
8 |
9 | 1.0.0
10 | net6.0
11 | latest
12 | $(NoWarn);NU1701;1702;1591;NU1602;CS8609;CS8610;CS8619;CS8632
13 | enable
14 |
15 |
16 |
17 | portable
18 | true
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | all
33 | runtime; build; native; contentfiles; analyzers
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Src/Template.Application/Common/PipelineBehaviours/ValidationBehaviour.cs:
--------------------------------------------------------------------------------
1 | using FluentValidation;
2 | using MediatR;
3 |
4 | namespace Template.Application.Common.PipelineBehaviours;
5 |
6 | public class ValidationBehaviour : IPipelineBehavior
7 | where TRequest : IRequest
8 | {
9 | private readonly IEnumerable> _validators;
10 |
11 | public ValidationBehaviour(IEnumerable> validators)
12 | {
13 | _validators = validators;
14 | }
15 |
16 | public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next)
17 | {
18 | if (_validators.Any())
19 | {
20 | var context = new ValidationContext(request);
21 |
22 | var validationResults = await Task.WhenAll(
23 | _validators.Select(v =>
24 | v.ValidateAsync(context, cancellationToken)));
25 |
26 | var failures = validationResults
27 | .Where(r => r.Errors.Any())
28 | .SelectMany(r => r.Errors)
29 | .ToList();
30 |
31 | if (failures.Any())
32 | throw new ValidationException(failures);
33 | }
34 |
35 | return await next();
36 | }
37 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/dashboard_active.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/dashboard_inactive.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/samples_active.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/samples_inactive.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/ConfigureServices/AuthInstaller.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Components.Authorization;
3 | using Template.Application.Common.Contracts;
4 | using Template.Domain.Options;
5 | using Template.Domain.Shared;
6 | using Template.WebUI.Client.Implementations;
7 |
8 | namespace Template.WebUI.Client.ConfigureServices;
9 |
10 | public class AuthInstaller : IInstaller
11 | {
12 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
13 | {
14 | services.AddOptions();
15 |
16 | services.AddAuthorizationCore(config =>
17 | {
18 | var claims = Claims.GetAllAppClaims().ToList();
19 |
20 | foreach (var claim in claims)
21 | {
22 | config.AddPolicy(claim,
23 | new AuthorizationPolicyBuilder()
24 | .RequireAuthenticatedUser()
25 | .RequireClaim(claim)
26 | .Build());
27 | }
28 | }
29 | );
30 |
31 | services.AddScoped();
32 |
33 | services.AddTransient(serviceProvider => (AppAuthenticationStateProvider)serviceProvider.GetRequiredService());
34 | }
35 | }
--------------------------------------------------------------------------------
/Tests/Template.Domain.UnitTests/Template.Domain.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 |
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 | all
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 | all
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | all
30 | runtime; build; native; contentfiles; analyzers
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Tests/Template.Application.IntegrationTests/Template.Application.IntegrationTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 |
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 | all
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 | all
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | all
30 | runtime; build; native; contentfiles; analyzers
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/Installers/AutoRegisterInstaller.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using NetCore.AutoRegisterDi;
3 | using Template.Application.Common.Contracts;
4 | using Template.Domain.Options;
5 |
6 | namespace Template.Application.ConfigureServices.Installers;
7 |
8 | ///
9 | /// Register Assembly Public NonAbstract Classes
10 | ///
11 | public class AutoRegisterInstaller : IInstaller
12 | {
13 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
14 | {
15 | services.RegisterAssemblyPublicNonGenericClasses()
16 | .Where(c => c.Name.EndsWith("Service")) //optional
17 | // .IgnoreThisInterface() //optional
18 | .AsPublicImplementedInterfaces();
19 |
20 | #region Scanning Multiple assemblies example
21 |
22 | //var assembliesToScan = new[]
23 | //{
24 | // Assembly.GetExecutingAssembly(),
25 | // Assembly.GetAssembly(typeof(MyServiceInAssembly1)),
26 | // Assembly.GetAssembly(typeof(MyServiceInAssembly2))
27 | //};
28 |
29 | //services.RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
30 | // .Where(c => c.Name.EndsWith("Service")) //optional
31 | // .IgnoreThisInterface() //optional
32 | // .AsPublicImplementedInterfaces();
33 |
34 | #endregion
35 | }
36 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.API/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:21653",
8 | "sslPort": 44331
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development"
17 | }
18 | },
19 | "Run (Dev)": {
20 | "commandName": "Project",
21 | "launchBrowser": true,
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | },
25 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
26 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
27 | "dotnetRunMessages": "true"
28 | },
29 | "Run (Prod)": {
30 | "commandName": "Project",
31 | "launchBrowser": true,
32 | "environmentVariables": {
33 | "ASPNETCORE_ENVIRONMENT": "Production"
34 | },
35 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
36 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
37 | "dotnetRunMessages": "true"
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Tests/Template.Application.UnitTests/Template.Application.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 |
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 | all
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 | all
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | all
31 | runtime; build; native; contentfiles; analyzers
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Src/Template.Application/ConfigureServices/Installers/LocalizationInstaller.cs:
--------------------------------------------------------------------------------
1 | using Template.Application.Common.Contracts;
2 | using Template.Domain.Options;
3 |
4 | namespace Template.Application.ConfigureServices.Installers;
5 |
6 | public class LocalizationInstaller : IInstaller
7 | {
8 | public void InstallServices(IServiceCollection services, AppSettings appSettings)
9 | {
10 | //services.AddLocalization();
11 |
12 | //services.AddRequestLocalization(options =>
13 | //{
14 | // var supportedCultures = new[]
15 | // {
16 | // new CultureInfo("fa"),
17 | // new CultureInfo("en"),
18 | // };
19 |
20 | // options.SupportedCultures = supportedCultures;
21 | // options.DefaultRequestCulture = new RequestCulture("fa");
22 | // options.ApplyCurrentCultureToResponseHeaders = true;
23 | // options.SupportedUICultures = supportedCultures;
24 | // options.RequestCultureProviders = new List
25 | // {
26 | // new QueryStringRequestCultureProvider(),
27 | // new AcceptLanguageHeaderRequestCultureProvider()
28 | // // new CookieRequestCultureProvider()
29 | // };
30 | //});
31 |
32 | //dependencyManager.Register();
33 |
34 | //services.AddSingleton, MvcConfigurationToProvideModelBindingMessage>();
35 | }
36 | }
--------------------------------------------------------------------------------
/Architecture.txt:
--------------------------------------------------------------------------------
1 | It is Clean Architechture, the one more aligned withJson Tylor and Nick Chapsas.
2 |
3 | Domain:
4 | - Things related to the domain (a little like DDD). No logic comes here.
5 | - This will contain all entities, enums, exceptions, interfaces, types and logic specific to the domain layer.
6 | - All Entities Properties has private set! Because only with class APIs they can change.
7 |
8 | Application:
9 | - Orchestrate the application. This layer contains all application logic. It is dependent on the domain layer, but has no dependencies on any other layer or project. This layer defines interfaces that are implemented by outside layers and DTOs. For example, if the application need to access a notification service, a new interface would be added to application and an implementation would be created within infrastructure.
10 |
11 | Infrastructure:
12 | - This layer contains classes for accessing external resources such as file systems, web services, smtp, and so on. These classes should be based on interfaces defined within the application layer.
13 | - All classes be internal because it do not have any effect on other projects, only in ConfigureServices have and it has its own method.
14 |
15 | WebUI:
16 | - This layer depends on both the Application and Infrastructure layers, however, the dependency on Infrastructure is only to support dependency injection. Therefore only Startup.cs should reference Infrastructure.
17 | - They depend to Infrastrucutre project only for Service registration and nothing else!
18 |
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Localization/Extensions/ValidationContextExtension.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using Bit.Core.Exceptions;
3 | using Template.Application.Common.Contracts;
4 |
5 | namespace Template.Application.Common.Localization.Extensions
6 | {
7 | public static class ValidationContextExtension
8 | {
9 | public static IStringProvider GetStringProvider(this ValidationContext validationContext)
10 | {
11 | // Request originated from AspNetCore Controllers
12 | var stringsProvider = validationContext.GetService(typeof(IStringProvider));
13 |
14 | if (stringsProvider is not null)
15 | return (IStringProvider)stringsProvider;
16 |
17 | // Below block should be uncomment in backend only projects. Blazor will use AspNetCore context and
18 | // will validate the dto in client-side, so no need to backend error message.
19 |
20 | #region Request originated from Bit Controllers
21 |
22 | //var context = DefaultDependencyManager.Current.Resolve().HttpContext;
23 |
24 | //validationContext.InitializeServiceProvider(type => context!.RequestServices.GetRequiredService(type));
25 |
26 | //return validationContext.GetRequiredService();
27 |
28 | #endregion
29 |
30 | throw new DomainLogicException("In Blazor applications, this error should not happen! See the above comments");
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/curved_right_arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
47 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/components/_Loading.scss:
--------------------------------------------------------------------------------
1 | @import '../utils/_base.scss';
2 |
3 | .ata-loading-component {
4 |
5 | #loader-wrappers {
6 | width: 100%;
7 | height: 100%;
8 | position: fixed;
9 | left: 0;
10 | top: 0;
11 | right: 0;
12 | bottom: 0;
13 | z-index: 9999;
14 | display: flex;
15 | align-items: center;
16 | flex-direction: column;
17 | justify-content: center;
18 | direction: ltr;
19 | }
20 |
21 | #loaders-body {
22 | width: 94px;
23 | height: 94px;
24 | background-size: 80%;
25 | border-radius: 50%;
26 | margin: 0 auto;
27 | z-index: 1;
28 | position: relative;
29 | display: flex;
30 | justify-content: center;
31 | align-items: center;
32 |
33 | img {
34 | position: absolute;
35 | left: 14px;
36 | }
37 | }
38 |
39 | #loaders {
40 | left: 0;
41 | top: 0;
42 | z-index: 1;
43 | border: 3px solid #b2b3b0;
44 | border-radius: 50%;
45 | border-top: 3px solid #a71c20;
46 | width: 68px;
47 | height: 68px;
48 | margin: -9px;
49 | -webkit-animation: spin 1s linear infinite;
50 | animation: spins 1s linear infinite;
51 | }
52 |
53 | @keyframes spins {
54 | 0% {
55 | transform: rotate(0deg);
56 | }
57 |
58 | 100% {
59 | transform: rotate(360deg);
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Contracts/INotificationService.cs:
--------------------------------------------------------------------------------
1 | using Template.Domain.Shared;
2 | using Template.WebUI.Client.Enums;
3 |
4 | namespace Template.WebUI.Client.Contracts
5 | {
6 | public interface INotificationService
7 | {
8 | ///
9 | /// Show Alert Using AlertifyJS library
10 | ///
11 | /// Type of alert including success, error, warning, etc
12 | /// Message content
13 | /// Time (in seconds) to wait before the message is dismissed, a value of 0 means keep open till clicked.
14 | /// Sets a value indicating the position of the notifier instance.
15 | ///
16 | ValueTask AlertAsync(NotificationType notifType, string message, int waitSeconds = AppConstants.AlertDefaultTimeout, AlertifyPosition position = AlertifyPosition.TopCenter);
17 |
18 | ///
19 | /// Show Alert Using BlazoredToast library
20 | ///
21 | /// Type of alert including success, error, warning, etc
22 | /// Message content
23 | ///
24 | ///
25 | ///
26 | void Toast(NotificationType notifType, string message, int waitSeconds = 5, bool showProgressBar = true);
27 |
28 | ValueTask AlertGeneralError();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/EF/ATADbContext.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Data.Extensions;
2 | using Bit.Data.EntityFrameworkCore.Implementations;
3 | using Microsoft.EntityFrameworkCore;
4 | using Template.Domain.Entities;
5 |
6 | namespace Template.Infrastructure.Persistence.EF;
7 |
8 | public class ATADbContext : EfCoreDbContextBase
9 | {
10 | public ATADbContext(DbContextOptions options)
11 | : base(options)
12 | {
13 | }
14 |
15 | protected override void OnModelCreating(ModelBuilder modelBuilder)
16 | {
17 | // Auto Register all Entities
18 | modelBuilder.RegisterDbSets(typeof(ATAEntity).Assembly);
19 |
20 | modelBuilder.UseJsonDbFunctions();
21 |
22 | // Configure Views
23 | //modelBuilder.ConfigureDbView(DbViews.FoodMenu, DbSchemas.ATA, hasKey: true);
24 |
25 | base.OnModelCreating(modelBuilder);
26 |
27 | // Seed Base Data to Database
28 | //modelBuilder.SeedDefaultRoles();
29 |
30 | // Ef Global Query Filters
31 | modelBuilder.RegisterIsArchivedGlobalQueryFilter();
32 | //modelBuilder.Entity().HasQueryFilter(ur => ur.ApplicationName == AppMetadata.SSOAppName);
33 |
34 | modelBuilder.ConfigureDecimalPrecision();
35 |
36 | // Restrict Delete (in Hard delete scenarios)
37 | // Ef default is Cascade
38 | modelBuilder.SetRestrictAsDefaultDeleteBehavior();
39 |
40 | // Auto Register all Entity Configurations (Fluent-API)
41 | modelBuilder.ApplyConfigurations(typeof(ATADbContext).Assembly);
42 | }
43 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/role.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/Persistence/EF/Repository/ATARepositoryReadOnly.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Model.Data.Contracts;
2 | using Bit.Data.EntityFrameworkCore.Implementations;
3 | using Bit.Model.Contracts;
4 | using Microsoft.EntityFrameworkCore;
5 | using System.Linq.Expressions;
6 |
7 | namespace Template.Infrastructure.Persistence.EF.Repository;
8 |
9 | public class ATARepositoryReadOnly : EfCoreRepository, IReadOnlyATARepository
10 | where TEntity : class, IEntity
11 | {
12 | public IQueryable GetAllWithoutQueryFilter()
13 | {
14 | return Set.IgnoreQueryFilters();
15 | }
16 |
17 | public override IQueryable GetAll()
18 | {
19 | Expression>? getFilter = CreateGetFilter();
20 |
21 | IQueryable queryable = base.GetAll();
22 |
23 | if (getFilter != null)
24 | {
25 | queryable = queryable.Where(getFilter);
26 | }
27 |
28 | return queryable;
29 | }
30 |
31 | public override async Task> GetAllAsync(CancellationToken cancellationToken)
32 | {
33 | Expression>? getFilter = CreateGetFilter();
34 |
35 | IQueryable queryable = await base.GetAllAsync(cancellationToken);
36 |
37 | if (getFilter != null)
38 | {
39 | queryable = queryable.Where(getFilter);
40 | }
41 |
42 | return queryable;
43 | }
44 |
45 | protected virtual Expression>? CreateGetFilter()
46 | {
47 | Expression>? criteria = null;
48 |
49 | return criteria;
50 | }
51 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/folder-open.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.Application/Template.Application.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | all
35 | runtime; build; native; contentfiles; analyzers
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/trash_gray.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/trash_white.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Pages/PageTitles.cs:
--------------------------------------------------------------------------------
1 | using Template.Domain.Shared;
2 |
3 | namespace Template.WebUI.Client.Pages;
4 |
5 | public static class PageTitles
6 | {
7 | public static class HomePage
8 | {
9 | public static readonly string Title = AppMetadata.PersianFullName;
10 | }
11 |
12 | public static class LogsPage
13 | {
14 | public static readonly string Title = "Audit Logs";
15 | }
16 |
17 | public static class PersonnelReportPage
18 | {
19 | public static readonly string ManagerialReportTitle = "گزارش غذای پرسنل";
20 | public static readonly string PersonnelMyFoodTitle = "گزارش غذای من";
21 | }
22 |
23 | public static class GuestReportPage
24 | {
25 | public static readonly string Title = "گزارش غذای مهمان";
26 | }
27 |
28 | public static class StatisticalReportPage
29 | {
30 | public static readonly string Title = "گزارش آماری";
31 | }
32 |
33 | public static class UsersPage
34 | {
35 | public static readonly string Title = "کاربران";
36 | }
37 |
38 | public static class RolesPage
39 | {
40 | public static readonly string Title = "نقشها";
41 | }
42 |
43 | public static class SettingsPage
44 | {
45 | public static readonly string Title = "تنظیمات";
46 | }
47 |
48 | public static class FoodMenuPage
49 | {
50 | public static readonly string Title = "تعریف غذا";
51 | }
52 |
53 | public static class FoodCalendarPage
54 | {
55 | public static readonly string Title = "تعریف گروه و تقویم غذایی";
56 | }
57 |
58 | public static class SelectFoodPage
59 | {
60 | public static readonly string Title = "انتخاب غذا آتا";
61 | }
62 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/add-circle.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Components.Web;
2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using System.Reflection;
5 | using Template.Application.Common.Contracts;
6 | using Template.Domain.Options;
7 | using Template.WebUI.Client.Implementations;
8 | using Template.WebUI.Client.Models;
9 | using Toolbelt.Blazor.Extensions.DependencyInjection;
10 |
11 | namespace Template.WebUI.Client;
12 |
13 | public class Program
14 | {
15 | public static Task Main(string[] args)
16 | {
17 | var builder = WebAssemblyHostBuilder.CreateDefault(args);
18 | builder.RootComponents.Add("head::after");
19 |
20 | var clientAppSettings = builder.Configuration.GetSection(nameof(ClientAppSettings)).Get();
21 | clientAppSettings.URLOptions!.AppURL = builder.HostEnvironment.BaseAddress;
22 |
23 | // Host client
24 | builder.Services.AddHttpClient(httpClient => httpClient.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
25 | .AddHttpMessageHandler();
26 |
27 | // Configure Dependencies with Service Installers
28 | var installers = new[] { Assembly.GetExecutingAssembly() }.SelectMany(a => a.GetExportedTypes())
29 | .Where(c => c.IsClass && !c.IsAbstract && c.IsPublic && typeof(IInstaller).IsAssignableFrom(c))
30 | .Select(Activator.CreateInstance).Cast().ToList();
31 | installers.ForEach(i => i.InstallServices(builder.Services, new AppSettings { Client = clientAppSettings }));
32 |
33 | builder.UseLoadingBar();
34 |
35 | return builder
36 | .Build()
37 | .RunAsync();
38 | }
39 | }
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/LogStore/SeqLogStore.cs:
--------------------------------------------------------------------------------
1 | using Bit.Core.Contracts;
2 | using Bit.Core.Models;
3 | using Serilog;
4 | using Serilog.Context;
5 | using Serilog.Exceptions;
6 | using Template.Domain.Shared;
7 |
8 | namespace Template.Infrastructure.LogStore;
9 |
10 | public class SeqLogStore : ILogStore
11 | {
12 | public Task SaveLogAsync(LogEntry logEntry)
13 | {
14 | SaveLog(logEntry);
15 |
16 | return Task.CompletedTask;
17 | }
18 |
19 | public void SaveLog(LogEntry logEntry)
20 | {
21 | Log.Logger = new LoggerConfiguration()
22 | .Enrich.WithProperty("ApplicationName", AppMetadata.SolutionName)
23 | .Enrich.FromLogContext()
24 | .Enrich.WithExceptionDetails()
25 | .Enrich.WithMachineName()
26 | .Enrich.WithClientIp()
27 | .Enrich.WithClientAgent()
28 | .WriteTo.Seq("http://log.app.ataair.ir", apiKey: "iW1OLXzF01n3gSJ70qkR")
29 | .CreateLogger();
30 |
31 | foreach (var prop in logEntry.GetType().GetProperties())
32 | LogContext.PushProperty(prop.Name, prop.GetValue(logEntry));
33 |
34 | var trackingCode = logEntry.LogData.SingleOrDefault(l => l.Key == "X-Correlation-ID")?.Value?.ToString();
35 |
36 | if (!string.IsNullOrWhiteSpace(trackingCode))
37 | LogContext.PushProperty("TrackingCode", trackingCode);
38 |
39 | string message = string.IsNullOrWhiteSpace(trackingCode) ? logEntry.Message : $"TrackingCode: {trackingCode}";
40 |
41 | if (logEntry.Severity == LogSeverity.Fatal.ToString())
42 | Log.Logger.Fatal(message);
43 |
44 | else
45 | Log.Logger.Error(message);
46 | }
47 | }
48 |
49 | public enum LogSeverity
50 | {
51 | Warning,
52 | Fatal
53 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Introduction
4 | Template project conducted by me! This project developed using ASP.NET Core as Backend and Blazor WebAssembly as Frontend and SQLServer as database.
5 |
6 | - Also the Bit framework has been used both in Backend and Frontend for easy and fast development of the project.
7 | - CQRS and MediatR with Clean Architercture.
8 | - Fluent Validation added.
9 |
10 |
11 | Bit Platform
12 |
13 |
14 | # Architecture
15 | It is Clean Architechture, the one more aligned withJson Tylor and Nick Chapsas.
16 |
17 | ### Domain:
18 | - Things related to the domain (a little like DDD). No logic comes here.
19 | - This will contain all entities, enums, exceptions, interfaces, types and logic specific to the domain layer.
20 |
21 | ### Application:
22 | - Orchestrate the application. This layer contains all application logic. It is dependent on the domain layer, but has no dependencies on any other layer or project. This layer defines interfaces that are implemented by outside layers and DTOs. For example, if the application need to access a notification service, a new interface would be added to application and an implementation would be created within infrastructure.
23 |
24 | ### Infrastructure:
25 | - This layer contains classes for accessing external resources such as file systems, web services, smtp, and so on. These classes should be based on interfaces defined within the application layer.
26 |
27 | ### WebUI:
28 | - This layer depends on both the Application and Infrastructure layers, however, the dependency on Infrastructure is only to support dependency injection. Therefore only Startup.cs should reference Infrastructure.
29 | - They depend to Infrastrucutre project only for Service registration and nothing else!
30 |
31 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Extensions/JsRuntimeExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.JSInterop;
2 |
3 | namespace Template.WebUI.Client.Extensions;
4 |
5 | public static class JsRuntimeExtensions
6 | {
7 | public static ValueTask AlertAsync(this IJSRuntime jsRuntime, string alertMessage)
8 | {
9 | return jsRuntime.InvokeVoidAsync("alert", alertMessage);
10 | }
11 |
12 | public static ValueTask SetCookieAsync(this IJSRuntime jsRuntime, string cookieName, string cookieValue, double expireMinutes = 525600)
13 | {
14 | return jsRuntime.InvokeVoidAsync("setCookie", cookieName, cookieValue, expireMinutes);
15 | }
16 |
17 | public static ValueTask GetCookieAsync(this IJSRuntime jsRuntime, string cookieName)
18 | {
19 | return jsRuntime.InvokeAsync("getCookie", cookieName);
20 | }
21 |
22 | public static ValueTask DeleteCookieAsync(this IJSRuntime jsRuntime, string cookieName)
23 | {
24 | return jsRuntime.InvokeAsync("deleteCookie", cookieName);
25 | }
26 |
27 | public static ValueTask OpenInNewTabAsync(this IJSRuntime jsRuntime, string url)
28 | {
29 | return jsRuntime.InvokeVoidAsync("open", url, "_blank");
30 | }
31 |
32 | public static ValueTask ChangeAddressBarUrlAsync(this IJSRuntime jsRuntime, string newUrl)
33 | {
34 | return jsRuntime.InvokeVoidAsync("changeAddressBarUrl", newUrl);
35 | }
36 |
37 | public static ValueTask AddCSSClassByElementIdAsync(this IJSRuntime jsRuntime, string elementId, string className)
38 | {
39 | return jsRuntime.InvokeVoidAsync("addClassToElementById", elementId, className);
40 | }
41 |
42 | public static ValueTask SetFocusAsync(this IJSRuntime jsRuntime, string elementId)
43 | {
44 | return jsRuntime.InvokeVoidAsync("setFocus", elementId);
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Shared/MainLayout.razor:
--------------------------------------------------------------------------------
1 |
2 | @inherits LayoutComponentBase
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 | @if (_showMenu)
20 | {
21 |
22 |
23 |
24 | }
25 |
26 |
27 | @Body
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | @code {
46 |
47 | bool _showMenu;
48 |
49 | [CascadingParameter] private Task AuthenticationStateTask { get; set; }
50 |
51 | protected override async Task OnInitializedAsync()
52 | {
53 | var authState = await AuthenticationStateTask;
54 |
55 | if (authState.User.Identity is null)
56 | return;
57 |
58 | if (authState.User.Identity.IsAuthenticated)
59 | {
60 | var userRoles = await AuthenticationStateTask.GetUserRoles();
61 |
62 | _showMenu = userRoles.Count > 0;
63 | }
64 |
65 | await base.OnInitializedAsync();
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/abstracts/_fonts.scss:
--------------------------------------------------------------------------------
1 | /*#region Aeonik font*/
2 |
3 | @font-face {
4 | font-family: 'aeonik-bold';
5 | src: url("../../fonts/Aeonik-Bold.otf?v=uc2a313ce") format("truetype");
6 | font-weight: normal;
7 | font-style: normal;
8 | font-display: block;
9 | }
10 |
11 | @font-face {
12 | font-family: 'aeonik-medium';
13 | src: url("../../fonts/Aeonik-Medium.otf?v=uc2a313ce") format("truetype");
14 | font-weight: normal;
15 | font-style: normal;
16 | font-display: block;
17 | }
18 |
19 | @font-face {
20 | font-family: 'aeonik-regular';
21 | src: url("../../fonts/Aeonik-regular.otf?v=uc2a313ce") format("truetype");
22 | font-weight: normal;
23 | font-style: normal;
24 | font-display: block;
25 | }
26 |
27 | @font-face {
28 | font-family: 'aeonik-light';
29 | src: url("../../fonts/Aeonik-Light.otf?v=uc2a313ce") format("truetype");
30 | font-weight: normal;
31 | font-style: normal;
32 | font-display: block;
33 | }
34 |
35 | /*#endregion*/
36 |
37 | /*#region IranYekan font*/
38 |
39 | @font-face {
40 | font-family: 'iranyekan';
41 | src: url('../../fonts/Iran-Yekan.eot');
42 | src: url('../../fonts/Iran-Yekan.eot?#iefix') format('embedded-opentype'),url('../../fonts/Iran-Yekan.woff') format('woff'),url('../../fonts/Iran-Yekan.ttf') format('truetype'),url('../../fonts/Iran-Yekan.svg#iran_sans') format('svg');
43 | font-weight: normal;
44 | font-style: normal;
45 | }
46 |
47 | /*#endregion*/
48 |
49 | /*#region BHoma font */
50 |
51 | @font-face {
52 | font-family: 'bhoma';
53 | src: url('../../fonts/BHoma.eot');
54 | src: url('../../fonts/BHoma.eot?#iefix') format('embedded-opentype'), url('../../fonts/BHoma.woff2') format('woff2'), url('../../fonts/BHoma.woff') format('woff'), url('../../fonts/BHoma.ttf') format('truetype');
55 | }
56 |
57 | /*#endregion */
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/logo_inverse.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
50 |
--------------------------------------------------------------------------------
/Src/Template.Domain/Shared/Claims.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using Bit.Core.Exceptions;
4 |
5 | // ReSharper disable InconsistentNaming
6 |
7 | namespace Template.Domain.Shared;
8 |
9 | public class DefaultRole
10 | {
11 | public string? Name { get; set; }
12 |
13 | public IEnumerable Claims { get; set; } = Array.Empty();
14 | }
15 |
16 | public class DefaultRoles
17 | {
18 | public static DefaultRole Administrator => new()
19 | {
20 | Name = nameof(Administrator),
21 | Claims = Claims.GetAllAppClaims()
22 | };
23 | }
24 |
25 | public static class Claims //* Do not change Claim values *//
26 | {
27 | public const string Settings_Permissions_View = nameof(Settings_Permissions_View);
28 |
29 | private static string[]? _claimNames;
30 |
31 | public static string GetClaimDisplayName(string claimType)
32 | {
33 | return claimType switch
34 | {
35 | Settings_Permissions_View => "مشاهدهی کاربران و نقشهای سامانه",
36 | _ => throw new DomainLogicException("همه Claimها باید مقدار نمایشی داشته باشند.")
37 | };
38 | }
39 |
40 | public static IEnumerable GetAllAppClaims()
41 | {
42 | return _claimNames ??= typeof(Claims)
43 | .GetFields(BindingFlags.Public | BindingFlags.Static)
44 | .Select(field => (string?)field.GetValue(null))
45 | .ToArray();
46 | }
47 |
48 | // Automatic Check for all Claims have DisplayName With Module Initializer
49 | [ModuleInitializer]
50 | public static void AutomaticCheckAllClaimsHaveDisplayName()
51 | {
52 | var allClaims = GetAllAppClaims();
53 |
54 | foreach (var claim in allClaims)
55 | {
56 | GetClaimDisplayName(claim); //Throw error if no display is assigned for the Claim.
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/customize.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/logo_main.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
50 |
--------------------------------------------------------------------------------
/Src/Template.Application/Common/Implementations/StringProvider.cs:
--------------------------------------------------------------------------------
1 | using ATA.Food.Shared.Localization.Resources.ExceptionMessages;
2 | using ATA.Food.Shared.Localization.Resources.GeneralMessages;
3 | using Bit.Core.Exceptions;
4 | using Microsoft.Extensions.Localization;
5 | using Template.Application.Common.Contracts;
6 | using Template.Application.Common.Localization.Resources;
7 |
8 | namespace Template.Application.Common.Implementations;
9 |
10 | public class StringProvider : IStringProvider
11 | {
12 | public IStringLocalizer MessageStringsLocalizer { get; set; } = default!; //Property Injection
13 | public IStringLocalizer ExceptionStringsLocalizer { get; set; } = default!; //Property Injection
14 |
15 | ///
16 | /// Get value from MessageStrings resource
17 | ///
18 | /// Resource key
19 | ///
20 | public string? Message(string messageStringsKey)
21 | {
22 | return GetValueByKeyAndResource(messageStringsKey, StringResourceType.MessageStrings);
23 | }
24 |
25 | ///
26 | /// Get value from ExceptionStrings resource
27 | ///
28 | /// Resource key
29 | ///
30 | public string Exception(string exceptionStringsKey)
31 | {
32 | return GetValueByKeyAndResource(exceptionStringsKey, StringResourceType.ExceptionStrings) ?? string.Empty;
33 | }
34 |
35 | private string? GetValueByKeyAndResource(string key, StringResourceType stringResourceType)
36 | {
37 | if (stringResourceType == StringResourceType.MessageStrings)
38 | return MessageStringsLocalizer.GetString(key);
39 |
40 | if (stringResourceType == StringResourceType.ExceptionStrings)
41 | return ExceptionStringsLocalizer.GetString(key);
42 |
43 | throw new BadRequestException();
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/ConfirmDialog.razor.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Components;
2 | using System.ComponentModel.DataAnnotations;
3 | using Template.WebUI.Client.Contracts;
4 |
5 | namespace Template.WebUI.Client.Components;
6 |
7 | public partial class ConfirmDialog
8 | {
9 | // Props
10 | private bool _isLoading;
11 | private bool _isVisible;
12 |
13 | // DIs
14 | [Inject] public INotificationService NotificationService { get; set; } = default!; //Property Injection
15 | [Parameter] public string Title { get; set; }
16 | [Parameter, Required] public string Text { get; set; }
17 | //[Parameter] public string? SuccessMessage { get; set; }
18 | [Parameter] public RenderFragment ChildContent { get; set; }
19 | [Parameter] public EventCallback OnConfirm { get; set; }
20 |
21 | [Parameter]
22 | public bool IsVisible
23 | {
24 | get => _isVisible;
25 | set
26 | {
27 | if (value == _isVisible) return;
28 | _isVisible = value;
29 |
30 | _ = IsVisibleChanged.InvokeAsync(value);
31 | }
32 | }
33 |
34 | [Parameter] public EventCallback IsVisibleChanged { get; set; }
35 |
36 | public async Task OnActionConfirm()
37 | {
38 | if (_isLoading) return;
39 |
40 | _isLoading = true;
41 | try
42 | {
43 | await OnConfirm.InvokeAsync();
44 | }
45 | finally
46 | {
47 | _isLoading = false;
48 | Hide();
49 | }
50 |
51 | //ShowMessage(); //This method will call even the Confirm method throws error ;(
52 | }
53 |
54 | private void Hide()
55 | {
56 | IsVisible = false;
57 | }
58 |
59 | private void ShowMessage()
60 | {
61 | //if (string.IsNullOrEmpty(SuccessMessage) is false)
62 | //{
63 | // NotificationService.AlertAsync(NotifType.Success, SuccessMessage);
64 | //}
65 | }
66 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/import.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.Application/Order/DTOs/OrderDto.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Helper.Extensions;
2 | using System.ComponentModel.DataAnnotations.Schema;
3 | using Template.Domain.Enums.Order;
4 |
5 | namespace Template.Application.Order.DTOs;
6 |
7 | [ComplexType]
8 | public record OrderDto
9 | {
10 | public int Id { get; set; }
11 |
12 | public int OrderStatus { get; set; }
13 | public string? OrderStatusDisplay => ((OrderStatus)OrderStatus).ToDisplayName();
14 |
15 | public int CityId { get; set; }
16 | public string? CityDisplay => ((ReferenceCity)CityId).ToDisplayName();
17 |
18 | public int GroupCalendarId { get; set; }
19 |
20 | public DateTime GroupCalendarDate { get; set; } //Flattening
21 | //public string GroupCalendarDateJalali => GroupCalendarDate.ToJalaliString();
22 | // public string FoodDateDisplay => $"{GroupCalendarDateJalali} – {GroupCalendarDate.GetPersianWeekDayName()}";
23 |
24 | public DateTime? DateTime { get; set; }
25 |
26 | public int? FoodMenuId { get; set; }
27 | public string? FoodMenuName { get; set; } //Flattening
28 |
29 | public int? TbzFoodMenuId { get; set; }
30 | public string? TbzFoodMenuName { get; set; } //Flattening
31 |
32 | public int UserPersonnelCode { get; set; }
33 |
34 | public string? UserFullName { get; set; }
35 |
36 | public string? UserWorkLocation { get; set; }
37 |
38 | public string? UserUnit { get; set; }
39 |
40 | public string? Location { get; set; }
41 |
42 | public bool IsActive { get; set; } = false;
43 |
44 | public int? CreatedBy { get; set; }
45 |
46 | public int? UpdatedBy { get; set; }
47 |
48 | //public DateTime? CreatedDate { get; set; }
49 | //public string RegisteredAtJalali => CreatedDate.ToJalaliString(false);
50 |
51 | public DateTime? UpdatedDate { get; set; }
52 |
53 | public bool IsHalfServing { get; set; }
54 |
55 | public bool IsArchived { get; set; }
56 | }
--------------------------------------------------------------------------------
/Src/Template.Domain/Entities/Order/OrderEntity.cs:
--------------------------------------------------------------------------------
1 | using Template.Domain.Enums.Order;
2 |
3 | namespace Template.Domain.Entities.Order;
4 |
5 | public class OrderEntity : ATAEntity
6 | {
7 | public ReferenceCity CityId { get; private set; }
8 |
9 | public OrderStatus OrderStatus { get; private set; }
10 |
11 | public int GroupCalendarId { get; private set; }
12 |
13 | public int? UserId { get; private set; }
14 |
15 | public int UserPersonnelCode { get; private set; }
16 |
17 | public string? UserFullName { get; private set; }
18 |
19 | public string? Location { get; private set; }
20 |
21 | public bool IsActive { get; private set; } = false;
22 |
23 | public int? CreatedBy { get; private set; }
24 |
25 | public int? UpdatedBy { get; private set; }
26 |
27 | public DateTime? CreatedDate { get; private set; }
28 |
29 | public DateTime? UpdatedDate { get; private set; }
30 |
31 | public bool IsHalfServing { get; private set; } = false;
32 |
33 | // Nav Props
34 |
35 | // Constructors
36 |
37 | public OrderEntity()
38 | {
39 | // For EF
40 | }
41 |
42 | public OrderEntity(ReferenceCity cityId, OrderStatus orderStatus, int groupCalendarId, int? userId, int userPersonnelCode, string? userFullName, string? location, bool isActive, int? createdBy, int? updatedBy, DateTime? createdDate, DateTime? updatedDate, bool isHalfServing)
43 | {
44 | CityId = cityId;
45 | OrderStatus = orderStatus;
46 | GroupCalendarId = groupCalendarId;
47 | UserId = userId;
48 | UserPersonnelCode = userPersonnelCode;
49 | UserFullName = userFullName;
50 | Location = location;
51 | IsActive = isActive;
52 | CreatedBy = createdBy;
53 | UpdatedBy = updatedBy;
54 | CreatedDate = createdDate;
55 | UpdatedDate = updatedDate;
56 | IsHalfServing = isHalfServing;
57 | }
58 |
59 | // APIs
60 | public void ChangeOrderStatus(OrderStatus orderStatus)
61 | {
62 | OrderStatus = orderStatus;
63 | }
64 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/user.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Components/ConfirmDialog.razor:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/export.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/components/_Toast.scss:
--------------------------------------------------------------------------------
1 | @import '../utils/_base.scss';
2 |
3 | .toast-component {
4 | display: flex;
5 | align-items: center;
6 | padding: rem(9px) rem(15px);
7 | border-radius: 2px;
8 |
9 | &.Success {
10 | background-color: $success-notif-bg;
11 | border: 1px solid $success-notif-border;
12 | }
13 |
14 | &.Error {
15 | background-color: $error-notif-bg;
16 | border: 1px solid $error-notif-border;
17 | }
18 |
19 | &.Message {
20 | background-color: $info-notif-bg;
21 | border: 1px solid $info-notif-border;
22 | }
23 |
24 | &.Notify {
25 | background-color: $info-notif-bg;
26 | border: 1px solid $info-notif-border;
27 | }
28 |
29 | &.Warning {
30 | background-color: $warning-notif-bg;
31 | border: 1px solid $warning-notif-border;
32 | }
33 |
34 | .notif-type-icon-wrapper {
35 | margin-left: rem(18px);
36 | }
37 |
38 | .notif-message-wrapper {
39 | color: $black;
40 | margin-left: rem(16px);
41 | }
42 | }
43 |
44 | .blazored-toast-container {
45 | .blazored-toast-progressbar {
46 | height: rem(2px);
47 |
48 | span {
49 | height: rem(2px);
50 | background-color: #3f9a6f;
51 | left: 0;
52 | }
53 | }
54 |
55 | .Success + .blazored-toast-progressbar {
56 | span {
57 | background-color: $success-notif-border;
58 | }
59 | }
60 |
61 | .Error + .blazored-toast-progressbar {
62 | span {
63 | background-color: $error-notif-border;
64 | }
65 | }
66 |
67 | .Warning + .blazored-toast-progressbar {
68 | span {
69 | background-color: $warning-notif-border;
70 | }
71 | }
72 |
73 | .Notify + .blazored-toast-progressbar {
74 | span {
75 | background-color: $info-notif-border;
76 | }
77 | }
78 |
79 | .Message + .blazored-toast-progressbar {
80 | span {
81 | background-color: $info-notif-border;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/icons/my-foods.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Implementations/NotificationService.cs:
--------------------------------------------------------------------------------
1 | using Bit.Utils.Extensions;
2 | using Blazored.Toast;
3 | using Blazored.Toast.Services;
4 | using Microsoft.JSInterop;
5 | using Template.Domain.Shared;
6 | using Template.WebUI.Client.Components;
7 | using Template.WebUI.Client.Contracts;
8 | using Template.WebUI.Client.Enums;
9 |
10 | namespace Template.WebUI.Client.Implementations;
11 |
12 | public class NotificationService : INotificationService
13 | {
14 | private readonly IJSRuntime _jsRuntime;
15 | private readonly IToastService _toastService;
16 |
17 | public NotificationService(IJSRuntime jsRuntime, IToastService toastService)
18 | {
19 | _jsRuntime = jsRuntime;
20 | _toastService = toastService;
21 | }
22 |
23 | public async ValueTask AlertAsync(NotificationType notifType, string message, int waitSeconds = AppConstants.AlertDefaultTimeout, AlertifyPosition position = AlertifyPosition.TopCenter)
24 | {
25 | // Set position
26 | await _jsRuntime.InvokeVoidAsync("alertify.set", "notifier", "position", position.ToDisplayName()!);
27 |
28 | // Show alert
29 | string jsIdentifier = notifType switch
30 | {
31 | NotificationType.Success => "alertify.success",
32 | NotificationType.Error => "alertify.error",
33 | NotificationType.Message => "alertify.message",
34 | NotificationType.Notify => "alertify.notify",
35 | NotificationType.Warning => "alertify.warning",
36 | _ => throw new ArgumentOutOfRangeException(nameof(notifType), notifType, null)
37 | };
38 |
39 | await _jsRuntime.InvokeVoidAsync(jsIdentifier, message, waitSeconds);
40 | }
41 |
42 | public void Toast(NotificationType notifType, string message, int waitSeconds = 5, bool showProgressBar = true)
43 | {
44 | // Toast Params
45 | var toastParameters = new ToastParameters();
46 | // ReSharper disable once EntityNameCapturedOnly.Local
47 | Toast toastComponent;
48 | toastParameters.Add(nameof(toastComponent.Message), message);
49 | toastParameters.Add(nameof(toastComponent.NotifType), notifType);
50 |
51 | // Toast Settings
52 | var toastSettings = new ToastInstanceSettings(waitSeconds, showProgressBar);
53 |
54 | _toastService.ShowToast(toastParameters, toastSettings);
55 | }
56 |
57 | public ValueTask AlertGeneralError()
58 | {
59 | return AlertAsync(NotificationType.Error, "Some error happened");
60 | }
61 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/pages/report/_personnel-report-page.scss:
--------------------------------------------------------------------------------
1 | @import '../../utils/_base.scss';
2 |
3 | .personnel-report-page {
4 |
5 | @include lt-md {
6 | padding: 0 rem(15px);
7 | }
8 |
9 | .page-header-section {
10 | .page-header-wrapper {
11 | display: flex;
12 |
13 | @include lt-md {
14 | padding: rem(15px);
15 | display: flex;
16 | flex-direction: column;
17 | margin-top: rem(30px);
18 | text-align: center;
19 | }
20 |
21 | .back-to-select-food-link {
22 | color: $old-brick;
23 | font-weight: 700;
24 | }
25 | }
26 | }
27 |
28 | .filter-section {
29 |
30 | .filter-box {
31 | @include lt-xxl {
32 | margin-top: rem(15px);
33 | }
34 | }
35 |
36 | .food-date-filter {
37 | @include lt-md {
38 | margin-top: rem(15px);
39 | }
40 | }
41 | }
42 |
43 | .grid-section {
44 | .page-grid-wrapper {
45 | @include lt-md {
46 | margin-top: rem(40px);
47 | }
48 | }
49 |
50 | .orders-archive-status-container {
51 | display: flex;
52 | position: absolute;
53 | top: rem(18px);
54 | margin-right: rem(30px);
55 | z-index: 1;
56 |
57 | @include md {
58 | top: rem(22px);
59 | }
60 |
61 | @include lt-md {
62 | top: rem(-21px);
63 | }
64 |
65 | div {
66 | margin-left: rem(40px);
67 | padding: rem(10px) rem(5px);
68 | cursor: pointer;
69 | font-size: rem(14px);
70 | font-weight: normal;
71 | line-height: rem(20px);
72 | }
73 |
74 | .active {
75 | font-weight: bold;
76 | border-bottom: 4px solid $old-brick;
77 | border-radius: 1px;
78 | color: $old-brick;
79 | font-weight: bold;
80 | }
81 | }
82 |
83 | .deleted-order {
84 | background-color: $pale-red;
85 |
86 | &:hover {
87 | background-color: $pale-red-hover;
88 | }
89 | }
90 | }
91 |
92 | &.my-food-wrapper {
93 | padding: rem(110px) rem(40px) rem(40px) rem(40px);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/pages/report/_report-statistical-page.scss:
--------------------------------------------------------------------------------
1 | @import '../../utils/_base.scss';
2 |
3 | .report-statistical-page {
4 |
5 | .container-table100 {
6 | margin: 0 auto;
7 | display: -webkit-box;
8 | display: -webkit-flex;
9 | display: -moz-box;
10 | display: -ms-flexbox;
11 | display: flex;
12 | flex-wrap: wrap;
13 | align-items: center;
14 | justify-content: center;
15 | padding: 33px 100px;
16 |
17 | .wrap-table100 {
18 | width: 100%;
19 |
20 | .table100 {
21 | width: 100%;
22 | position: relative;
23 | background-color: #fff;
24 |
25 | .table100-firstcol {
26 | background-color: #fff;
27 | position: absolute;
28 | z-index: 1000;
29 | width: 310px;
30 | top: 0;
31 | left: 0;
32 |
33 | table {
34 | background-color: transparent;
35 |
36 | tr {
37 | border-bottom: 1px solid #f2f2f2;
38 |
39 | th {
40 | font-family: $fontPrimary;
41 | font-size: 14px;
42 | color: #333;
43 | line-height: 1.4;
44 | text-transform: uppercase;
45 | padding-top: 21px;
46 | padding-bottom: 21px;
47 | text-align: left;
48 | }
49 |
50 | td {
51 | color: #666;
52 | font-family: $fontPrimary;
53 | font-size: 15px;
54 | line-height: 1.4;
55 | padding-top: 16px;
56 | padding-bottom: 16px;
57 | }
58 |
59 | .column1 {
60 | width: 100%;
61 | padding-left: 40px;
62 | }
63 |
64 | th, td {
65 | font-weight: unset;
66 | padding-right: 10px;
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | - master
3 |
4 | variables:
5 | BuildConfiguration: 'Release'
6 | BuildPlatform: 'any cpu'
7 | PathToProjects: '**/ATA.Food.Server.Api.csproj'
8 |
9 | jobs:
10 | - job: Build
11 | displayName: Build Powered by YAML
12 | pool:
13 | name: Default
14 | steps:
15 | #task: Use .NET Core sdk 6.x
16 | - task: UseDotNet@2
17 | displayName: 'Use .NET Core sdk 6.x'
18 | inputs:
19 | version: 6.x
20 |
21 | #task: Use Node 6.x => Typscript build require it
22 | - task: NodeTool@0
23 | displayName: 'Use Node 6.x'
24 |
25 | #task: Restore
26 | - task: DotNetCoreCLI@2
27 | displayName: Restore
28 | inputs:
29 | command: restore
30 | projects: $(PathToProjects)
31 | vstsFeed: 'f5d0ca62-2bdf-417c-b55e-0f9a8acddc7a'
32 |
33 | #task: Powershell replace 'Client' with 'None' => In Directory.Build.props so the codes can be generated in client side without error
34 | - task: PowerShell@2
35 | displayName: Powershell replace 'Client' with 'None'
36 | inputs:
37 | targetType: 'inline'
38 | script: (Get-Content Directory.Build.props) -replace '>Client<' , '>None<' | Out-File Directory.Build.props
39 |
40 | #task: Build
41 | - task: DotNetCoreCLI@2
42 | displayName: Build
43 | inputs:
44 | command: 'build'
45 | projects: '$(PathToProjects)'
46 | arguments: '--configuration $(BuildConfiguration)'
47 |
48 | #task: Powershell replace 'None' to 'Client' => Now the codes are generated and everything is ready to full build of Bit Blazor application
49 | - task: PowerShell@2
50 | displayName: Powershell replace 'None' with 'Client'
51 | inputs:
52 | targetType: 'inline'
53 | script: (Get-Content Directory.Build.props) -replace '>None<' , '>Client<' | Out-File Directory.Build.props
54 |
55 | #task: Build
56 | - task: DotNetCoreCLI@2
57 | displayName: Build
58 | inputs:
59 | command: 'build'
60 | projects: '$(PathToProjects)'
61 | arguments: '--configuration $(BuildConfiguration)'
62 |
63 | #task: Publish
64 | - task: DotNetCoreCLI@2
65 | displayName: Publish
66 | inputs:
67 | command: publish
68 | publishWebProjects: false
69 | projects: $(PathToProjects)
70 | arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
71 | zipAfterPublish: True
72 |
73 | #task: Publish Artifact
74 | - task: PublishBuildArtifacts@1
75 | displayName: 'Publish Artifact'
76 | inputs:
77 | PathtoPublish: '$(build.artifactstagingdirectory)'
78 | condition: succeededOrFailed()
79 |
--------------------------------------------------------------------------------
/Src/Template.Infrastructure/ConfigureServices/DataAccessInstaller.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Data;
2 | using ATABit.Data.Contracts;
3 | using ATABit.Data.Interceptors;
4 | using ATABit.Model.Data.Contracts;
5 | using Bit.Core.Contracts;
6 | using Bit.Data;
7 | using Bit.Data.Contracts;
8 | using Bit.Owin.Implementations;
9 | using Microsoft.Data.SqlClient;
10 | using Microsoft.EntityFrameworkCore;
11 | using Microsoft.Extensions.Hosting;
12 | using System.Data.Common;
13 | using System.Reflection;
14 | using Template.Domain.Options;
15 | using Template.Infrastructure.Common.Contracts;
16 | using Template.Infrastructure.Persistence.EF;
17 | using Template.Infrastructure.Persistence.EF.Repository;
18 |
19 | namespace Template.Infrastructure.ConfigureServices;
20 |
21 | public class DataAccessInstaller : IBitInstaller
22 | {
23 | public void InstallServices(IServiceCollection services, IDependencyManager dependencyManager, AppSettings appSettings)
24 | {
25 | services.AddATABitDataAccess();
26 |
27 | dependencyManager.RegisterRepository(typeof(ATARepository<>).GetTypeInfo());
28 | dependencyManager.RegisterRepository(typeof(ATARepositoryReadOnly<>).GetTypeInfo());
29 |
30 | dependencyManager.RegisterGeneric(typeof(IATARepository<>).GetTypeInfo(), typeof(ATARepository<>).GetTypeInfo());
31 | dependencyManager.RegisterGeneric(typeof(IReadOnlyATARepository<>).GetTypeInfo(), typeof(ATARepositoryReadOnly<>).GetTypeInfo());
32 |
33 | dependencyManager.Register>();
34 |
35 | dependencyManager.RegisterEfCoreDbContext((serviceProvider, optionsBuilder) =>
36 | {
37 | var connectionString = appSettings.Server!.ConnectionStringOptions!.AppDbConnectionString!;
38 |
39 | DbConnection connection = serviceProvider.GetRequiredService().GetDbConnection(connectionString, rollbackOnScopeStatusFailure: true);
40 |
41 | optionsBuilder.UseSqlServer(connection, sqlServerOptions =>
42 | {
43 | sqlServerOptions.CommandTimeout((int)TimeSpan.FromMinutes(1)
44 | .TotalSeconds); //Default is 30 seconds
45 | });
46 |
47 | // Interceptors
48 | var entityAuditProvider = serviceProvider.GetRequiredService();
49 | optionsBuilder.AddInterceptors(new AuditSaveChangesInterceptor(entityAuditProvider));
50 | optionsBuilder.AddInterceptors(new FixSchemaInterceptor());
51 |
52 | // Show Detailed Errors
53 | if (AspNetCoreAppEnvironmentsProvider.Current.HostingEnvironment.IsDevelopment())
54 | optionsBuilder.EnableSensitiveDataLogging().EnableDetailedErrors();
55 | });
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/wwwroot/css/abstracts/_responsive.scss:
--------------------------------------------------------------------------------
1 | @import '_functions.scss';
2 |
3 | /// https://github.com/Necromancerx/media-queries-scss-mixins
4 | /// https://getbootstrap.com/docs/5.0/layout/breakpoints/
5 |
6 | // media aliases and breakpoints
7 | $screen-sm-min: em(576.2px);
8 | $screen-md-min: em(768.2px);
9 | $screen-lg-min: em(992.2px);
10 | $screen-xl-min: em(1200.2px);
11 | $screen-xxl-min: em(1400.2px);
12 |
13 | $screen-xs-max: em(576px);
14 | $screen-sm-max: em(768px);
15 | $screen-md-max: em(992px);
16 | $screen-lg-max: em(1200px);
17 | $screen-xl-max: em(1400px);
18 |
19 | // media devices
20 | @mixin xs {
21 | @media screen and (max-width: #{$screen-xs-max}) {
22 | @content;
23 | }
24 | }
25 |
26 | @mixin sm {
27 | @media screen and (min-width: #{$screen-sm-min}) and (max-width: #{$screen-sm-max}) {
28 | @content;
29 | }
30 | }
31 |
32 | @mixin md {
33 | @media screen and (min-width: #{$screen-md-min}) and (max-width: #{$screen-md-max}) {
34 | @content;
35 | }
36 | }
37 |
38 | @mixin lg {
39 | @media screen and (min-width: #{$screen-lg-min}) and (max-width: #{$screen-lg-max}) {
40 | @content;
41 | }
42 | }
43 |
44 | @mixin xl {
45 | @media screen and (min-width: #{$screen-xl-min}) and (max-width: #{$screen-xl-max}) {
46 | @content;
47 | }
48 | }
49 |
50 | @mixin xxl {
51 | @media screen and (min-width: #{$screen-xxl-min}) {
52 | @content;
53 | }
54 | }
55 |
56 | // media lt queries
57 | @mixin lt-sm {
58 | @media screen and (max-width: #{$screen-sm-min}) {
59 | @content;
60 | }
61 | }
62 |
63 | @mixin lt-md {
64 | @media screen and (max-width: #{$screen-md-min}) {
65 | @content;
66 | }
67 | }
68 |
69 | @mixin lt-lg {
70 | @media screen and (max-width: #{$screen-lg-min}) {
71 | @content;
72 | }
73 | }
74 |
75 | @mixin lt-xl {
76 | @media screen and (max-width: #{$screen-xl-min}) {
77 | @content;
78 | }
79 | }
80 |
81 | @mixin lt-xxl {
82 | @media screen and (max-width: #{$screen-xxl-min}) {
83 | @content;
84 | }
85 | }
86 |
87 | // media gt queries
88 | @mixin gt-xs {
89 | @media screen and (min-width: #{$screen-xs-max}) {
90 | @content;
91 | }
92 | }
93 |
94 | @mixin gt-sm {
95 | @media screen and (min-width: #{$screen-sm-max}) {
96 | @content;
97 | }
98 | }
99 |
100 | @mixin gt-md {
101 | @media screen and (min-width: #{$screen-md-max}) {
102 | @content;
103 | }
104 | }
105 |
106 | @mixin gt-lg {
107 | @media screen and (min-width: #{$screen-lg-max}) {
108 | @content;
109 | }
110 | }
111 |
112 | @mixin gt-xl {
113 | @media screen and (min-width: #{$screen-xl-max}) {
114 | @content;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/Src/Template.WebUI.Client/Extensions/AuthStateTaskExtensions.cs:
--------------------------------------------------------------------------------
1 | using ATABit.Shared.Dto.Identity;
2 | using Microsoft.AspNetCore.Components.Authorization;
3 | using System.Security.Claims;
4 |
5 | namespace Template.WebUI.Client.Extensions
6 | {
7 | public static class AuthStateTaskExtensions
8 | {
9 | public static async Task IsAuthenticated(this Task authStateTask)
10 | {
11 | var authState = await authStateTask;
12 |
13 | return authState.User.Identity is not null;
14 | }
15 |
16 | public static async Task GetUserId(this Task authStateTask)
17 | {
18 | var authState = await authStateTask;
19 |
20 | return authState.User.Claims
21 | .Where(c => c.Type == ClaimTypes.NameIdentifier)
22 | .Select(c => c.Value)
23 | .FirstOrDefault();
24 | }
25 |
26 | public static async Task GetUserFullName(this Task authStateTask)
27 | {
28 | var authState = await authStateTask;
29 |
30 | return authState.User.Claims
31 | .Where(c => c.Type == ClaimTypes.Name)
32 | .Select(c => c.Value)
33 | .FirstOrDefault();
34 | }
35 |
36 | public static async Task GetPersonnelCode(this Task authStateTask)
37 | {
38 | var authState = await authStateTask;
39 |
40 | return authState.User.Claims
41 | .Where(c => c.Type.Equals(nameof(ATATokenClaims.PersonnelCode), StringComparison.OrdinalIgnoreCase))
42 | .Select(c => c.Value)
43 | .FirstOrDefault();
44 | }
45 |
46 | public static async Task GetIsMale(this Task authStateTask)
47 | {
48 | var authState = await authStateTask;
49 |
50 | var isMaleClaim = authState.User.Claims.Single(c => c.Type.Equals(nameof(ATATokenClaims.IsMale), StringComparison.OrdinalIgnoreCase));
51 |
52 | return isMaleClaim.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
53 | }
54 |
55 | public static async Task> GetUserRoles(this Task authStateTask)
56 | {
57 | var authState = await authStateTask;
58 |
59 | return authState.User.Claims
60 | .Where(c => c.Type == ClaimTypes.Role)
61 | .Select(c => c.Value)
62 | .ToList();
63 | }
64 |
65 | public static async Task> GetUserClaims(this Task authStateTask)
66 | {
67 | var authState = await authStateTask;
68 |
69 | return authState.User.Claims
70 | .Select(c => c.Value)
71 | .ToList();
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------