Compare commits

..

5 Commits

Author SHA1 Message Date
Adam 0662bb77a7 Driver history grouped by date,
Hotel more clean transfer list
Hotel create transfer reload button after saved last transfer
Save message first then send message in email
Create guest user if email is not in userDb, set referral Id fixed
Some more little cleanups
2024-07-29 10:57:55 +02:00
Adam 6bfd97beba Merge branch 'master' of http://git2.aycode.com/Adam/TourIAm 2024-07-27 18:21:05 +02:00
Adam 6e345430cb ExchangeRateService and api 2024-07-27 18:19:56 +02:00
Adam 4b7692c0e6 Merge branch 'master' of http://git2.aycode.com/Adam/TourIAm 2024-07-25 08:32:32 +02:00
Adam 32c705383b Driver Tasks, Hotel Dashboard, changepassword 2024-07-25 08:32:20 +02:00
39 changed files with 1138 additions and 606 deletions

View File

@ -48,6 +48,7 @@ public class SignalRTags : AcSignalRTags
//public const int RemoveAddress = 34; //public const int RemoveAddress = 34;
public const int GetProfileById = 35; public const int GetProfileById = 35;
public const int GetProfileByUserId = 36;
//public const int GetProfiles = 36; //public const int GetProfiles = 36;
//public const int GetProfileByContextId = 37; //public const int GetProfileByContextId = 37;

View File

@ -69,6 +69,7 @@ namespace TIAMMobileApp
builder.Services.AddSingleton<SignalRService>(); builder.Services.AddSingleton<SignalRService>();
builder.Services.AddSingleton<SumupService>(); builder.Services.AddSingleton<SumupService>();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>(); builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddScoped<ExchangeRateService>();
builder.Services.AddAuthorizationCore(); builder.Services.AddAuthorizationCore();
builder.Services.Configure<AnimationOptions>(Guid.NewGuid().ToString(), c => { }); builder.Services.Configure<AnimationOptions>(Guid.NewGuid().ToString(), c => { });
return builder.Build(); return builder.Build();

View File

@ -16,7 +16,7 @@
OnInvalidSubmit="@HandleInvalidSubmit" OnInvalidSubmit="@HandleInvalidSubmit"
Context="EditFormContext"> Context="EditFormContext">
<DataAnnotationsValidator /> <DataAnnotationsValidator />
<div class="card cw-480"> <div class="card">
<div class="card-header text-center py-3"> <div class="card-header text-center py-3">
<h4>Edit Your Details</h4> <h4>Edit Your Details</h4>
</div> </div>
@ -31,7 +31,7 @@ else
<div class="card cw-480"> <div class="card cw-480">
<div class="card-header text-center py-3"> <div class="card-header text-center py-3">
<h4>Details</h4> <h4>Details</h4>
<DxButton Click="StartEditing" RenderStyle="ButtonRenderStyle.Primary">Edit</DxButton> @* <DxButton Click="StartEditing" RenderStyle="ButtonRenderStyle.Primary">Create new</DxButton> *@
</div> </div>
<div class="card-body"> <div class="card-body">
@CreateCardView() @CreateCardView()
@ -190,6 +190,8 @@ else
editor.AddAttribute(j++, "Date", property.GetValue(Data)); editor.AddAttribute(j++, "Date", property.GetValue(Data));
editor.AddAttribute(j++, "DateExpression", lambda); editor.AddAttribute(j++, "DateExpression", lambda);
editor.AddAttribute(j++, "CssClass", "form-field"); editor.AddAttribute(j++, "CssClass", "form-field");
editor.AddAttribute(j++, "TimeSectionVisible", true);
editor.AddAttribute(j++, "TimeSectionScrollPickerFormat", "tt h m");
editor.AddAttribute(j++, "DateChanged", EventCallback.Factory.Create<DateTime>(this, str => { property.SetValue(Data, str); })); editor.AddAttribute(j++, "DateChanged", EventCallback.Factory.Create<DateTime>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent(); editor.CloseComponent();
break; break;
@ -255,7 +257,7 @@ else
else if (property.PropertyType == typeof(string) && string.Compare(attrList.CustomDataType, "FullName", true) == 0) else if (property.PropertyType == typeof(string) && string.Compare(attrList.CustomDataType, "FullName", true) == 0)
{ {
editor.OpenComponent<FullNameEditor>(j); editor.OpenComponent<FullNameEditor>(j);
editor.AddAttribute(j++, "NullText", "Full name"); editor.AddAttribute(j++, "NullText", "");
editor.AddAttribute(j++, "FirstNameChanged", EventCallback.Factory.Create<string>(this, result => editor.AddAttribute(j++, "FirstNameChanged", EventCallback.Factory.Create<string>(this, result =>
{ {
_logger.DetailConditional($"FirstName changed to {result}"); _logger.DetailConditional($"FirstName changed to {result}");
@ -316,6 +318,7 @@ else
case DataType.MultilineText: case DataType.MultilineText:
editor.OpenComponent<DxMemo>(j); editor.OpenComponent<DxMemo>(j);
editor.AddAttribute(j++, "Text", property.GetValue(Data)); editor.AddAttribute(j++, "Text", property.GetValue(Data));
editor.AddAttribute(j++, "CssClass", "form-field");
editor.AddAttribute(j++, "TextExpression", lambda); editor.AddAttribute(j++, "TextExpression", lambda);
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); })); editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent(); editor.CloseComponent();
@ -323,6 +326,7 @@ else
default: default:
editor.OpenComponent<DxTextBox>(j++); editor.OpenComponent<DxTextBox>(j++);
editor.AddAttribute(j++, "Text", property.GetValue(Data)); editor.AddAttribute(j++, "Text", property.GetValue(Data));
editor.AddAttribute(j++, "CssClass", "form-field");
editor.AddAttribute(j++, "TextExpression", lambda); editor.AddAttribute(j++, "TextExpression", lambda);
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); })); editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<string>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent(); editor.CloseComponent();

View File

@ -0,0 +1,68 @@
@using BlazorAnimation
@using TIAM.Core.Enums
@using TIAM.Entities.Transfers
@using TIAM.Services
@using TIAMSharedUI.Shared.Components.Cards
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models.ClientSide.UI
@using TIAMWebApp.Shared.Application.Services
@using TIAM.Entities.Drivers
@inject IServiceProviderDataService ServiceProviderDataService
@inject AdminSignalRClient AdminSignalRClient;
<div class="e-card cw-480">
<div class="e-main d-flex align-items-center">
<div class="flex-shrink-0">
<img class="e-photo" src="_content/TIAMSharedUI/images/defaultcar_60.png" alt="" />
</div>
<div class="e-info flex-grow-1 ms-3">
<div class="e-name">@($"{MyCar.Color}")</div>
<p class="e-title"> @MyCar.Manufacture</p>
<p class="e-title"> @MyCar.CarModel</p>
</div>
</div>
<hr class="hr" />
<div class="row">
<div class="col-12 col-md-6">
@RenderDetailsItem("fa-solid fa-engine", "Engine", Enum.GetName(MyCar.CarMotorType))
</div>
<div class="col-12 col-md-6">
@RenderDetailsItem("fa-solid fa-location-dot", "Year", MyCar.YearOfMake.ToString())
</div>
<hr class="hr" />
<div class="col-12 col-md-4">
@RenderDetailsItem("fa-solid fa-users", "Seats", MyCar.SeatNumber.ToString())
</div>
</div>
</div>
@code {
[Parameter] public Car MyCar { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
protected override Task OnParametersSetAsync()
{
return base.OnParametersSetAsync();
}
RenderFragment RenderDetailsItem(string iconCssClass, string caption, string value)
{
return @<div class="d-flex m-1 align-items-center">
<div class="icon-container flex-shrink-0">
<span class="dxbl-image m-1 @iconCssClass"></span>
</div>
<div class="text-container m-1 flex-grow-1 ms-2">
<label>@caption:</label>
<div>@value</div>
</div>
</div>;
}
}

View File

@ -0,0 +1,29 @@
.e-name {
margin-bottom: 0.25rem;
font-size: 1.25rem;
font-weight: 500;
line-height: 1.2;
}
.e-email {
font-size: 0.75rem;
text-decoration: underline;
margin-bottom: 0;
}
.e-title {
font-size: 0.875rem;
margin-bottom: 0.5rem;
}
.e-details .text-container label {
font-size: 0.8125rem;
line-height: 1rem;
}
.e-details .text-container {
font-size: 0.875rem;
line-height: 1.125rem;
white-space: nowrap;
}

View File

@ -47,7 +47,7 @@
<div class="col-12 col-md-6"> <div class="col-12 col-md-6">
@RenderDetailsItem("fa-solid fa-list-check", "Status", AllStatuses.FirstOrDefault(x => x.StatusValue == (byte)Context.TransferStatusType).StatusName) @RenderDetailsItem("fa-solid fa-list-check", "Status", AllStatuses.FirstOrDefault(x => x.StatusValue == (byte)Context.TransferStatusType).StatusName)
</div> </div>
<div class="col-8 col-md-4"> <div class="col-9 col-md-5">
<DxComboBox Data="@Statuses" <DxComboBox Data="@Statuses"
@bind-Value="@CurrentStatusType" @bind-Value="@CurrentStatusType"
NullText="Select new status" NullText="Select new status"
@ -56,10 +56,16 @@
TextFieldName="@nameof(TransferStatusModel.StatusName)" /> TextFieldName="@nameof(TransferStatusModel.StatusName)" />
</div> </div>
<div class="col-4 col-md-2"> <div class="col-3 col-md-1">
<DxButton CssClass="btn btn-primary" Click="SaveStatus" Enabled="@isSaveActive"> Save</DxButton> <DxButton CssClass="btn btn-primary" Click="SaveStatus" Enabled="@isSaveActive"> Save</DxButton>
</div> </div>
@if(!Context.Paid)
{
<hr class="hr" />
<div class="col-3 col-md-1">
<DxButton CssClass="btn btn-primary" Click="PaidByCash">Paid in car</DxButton>
</div>
}
<p>@msg</p> <p>@msg</p>
</div> </div>
@ -151,7 +157,21 @@
await DataChanged.InvokeAsync(msg); await DataChanged.InvokeAsync(msg);
} }
protected async Task PaidByCash()
{
Context.Paid = true;
var result = await AdminSignalRClient.PostDataAsync<Transfer>(SignalRTags.UpdateTransfer, Context);
if (result != null)
{
msg = $"Payment status saved";
StateHasChanged();
}
else
{
msg = "Some error occured during saving, please try again later";
}
await DataChanged.InvokeAsync(msg);
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {

View File

@ -0,0 +1,167 @@
@using BlazorAnimation
@using TIAM.Core.Enums
@using TIAM.Entities.Transfers
@using TIAM.Entities.Users
@using TIAM.Models.Dtos.Users
@using TIAM.Services
@using TIAMSharedUI.Shared.Components.Cards
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models.ClientSide.UI
@using TIAMWebApp.Shared.Application.Models.PageModels
@using TIAMWebApp.Shared.Application.Services
@inject IServiceProviderDataService ServiceProviderDataService
@inject IUserDataService UserDataService;
@inject AdminSignalRClient AdminSignalRClient;
<div class="e-card cw-480">
<div class="e-main d-flex align-items-center">
<div class="flex-shrink-0">
<img class="e-photo" src="_content/TIAMSharedUI/images/defaultavatar_60.png" alt="" />
</div>
<div class="e-info flex-grow-1 ms-3">
<div class="e-name">@($"{Context.UserDto.Id}")</div>
<p class="e-title"><i class="fa-solid fa-at"></i> @Context.UserDto.EmailAddress</p>
<p class="e-title"><i class="fa-solid fa-phone"></i> @Context.UserDto.PhoneNumber</p>
</div>
</div>
<hr class="hr" />
<div class="row">
<div class="col-12 col-md-6">
@RenderDetailsItem("fa-solid fa-key", "Password", Context.UserDto.Password)
</div>
<div class="col-9 col-md-4">
<DxTextBox
@bind-Text="@NewPassword"
NullText="New password"
BindValueMode="BindValueMode.OnDelayedInput"
InputDelay="300"
Password="true"
CssClass="form-field"
/>
<DxTextBox @bind-Text="@ConfirmNewPassword"
ReadOnly="@PasswordNotSet"
NullText="Confirm new password"
BindValueMode="BindValueMode.OnDelayedInput"
InputDelay="300"
Password="true"
CssClass="form-field" />
</div>
<div class="col-3 col-md-2">
<DxButton CssClass="btn btn-primary" Click="SetPassword" Enabled="@isSaveActive"> Save</DxButton>
</div>
<p>@msg</p>
</div>
</div>
@code {
[Parameter] public UserModelDtoDetail Context { get; set; }
[Parameter] public EventCallback<string> DataChanged { get; set; }
private bool PasswordNotSet = true;
private bool PasswordNotConfirmed = true;
private string _newPassword;
public string NewPassword
{
get => _newPassword;
set
{
if (_newPassword != value)
{
_newPassword = value;
OnPasswordSet(value);
}
}
}
private string? _confirmNewPassword;
public string? ConfirmNewPassword
{
get => _confirmNewPassword;
set
{
if (value != null && _confirmNewPassword != value)
{
_confirmNewPassword = value;
OnPasswordConfirmed(value);
}
}
}
string msg;
private bool isSaveActive = false;
void OnPasswordSet(string password)
{
msg = $"Password to set: {NewPassword}";
PasswordNotSet = false;
StateHasChanged();
}
void OnPasswordConfirmed(string password)
{
if(NewPassword == ConfirmNewPassword)
{
PasswordNotConfirmed = false;
isSaveActive = true;
}
else
{
isSaveActive = false;
msg = "Password and confirmation not matching!";
}
}
protected async Task SetPassword()
{
isSaveActive = false;
User userToUpdate = new User(Context.Id, Context.UserDto.EmailAddress, NewPassword);
var result = await AdminSignalRClient.PostDataAsync<User>(SignalRTags.UpdateUser, userToUpdate);
if (result != null)
{
msg = $"Password saved";
StateHasChanged();
}
else
{
msg = "Some error occured during saving, please try again later";
}
await DataChanged.InvokeAsync(msg);
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
}
RenderFragment RenderDetailsItem(string iconCssClass, string caption, string value)
{
return @<div class="d-flex m-1 align-items-center">
<div class="icon-container flex-shrink-0">
<span class="dxbl-image m-1 @iconCssClass"></span>
</div>
<div class="text-container m-1 flex-grow-1 ms-2">
<label>@caption:</label>
<div>@value</div>
</div>
</div>;
}
}

View File

@ -0,0 +1,29 @@
.e-name {
margin-bottom: 0.25rem;
font-size: 1.25rem;
font-weight: 500;
line-height: 1.2;
}
.e-email {
font-size: 0.75rem;
text-decoration: underline;
margin-bottom: 0;
}
.e-title {
font-size: 0.875rem;
margin-bottom: 0.5rem;
}
.e-details .text-container label {
font-size: 0.8125rem;
line-height: 1rem;
}
.e-details .text-container {
font-size: 0.875rem;
line-height: 1.125rem;
white-space: nowrap;
}

View File

@ -34,8 +34,8 @@
<PageTitle>Transfers</PageTitle> <PageTitle>Transfers</PageTitle>
<div class="text-center m-5"> <div class="text-center m-5">
<h1>Transfer management</h1> <h1>Tasks</h1>
<h2 style="font-size:small">Manage transfers here!</h2> <h2 style="font-size:small">Manage your tasks here!</h2>
</div> </div>
@ -46,8 +46,8 @@
CloseOnOutsideClick="false" CloseOnOutsideClick="false"
ShowCloseButton="false" ShowCloseButton="false"
HeaderText="MessageBox" HeaderText="MessageBox"
Closing="EulaPopupClosing" Closing="EmailPopupClosing"
Closed="EulaPopupClosed"> Closed="EmailPopupClosed">
<BodyContentTemplate> <BodyContentTemplate>
<InputWizard Data=@_messageWizardModel <InputWizard Data=@_messageWizardModel
OnSubmit="SubmitForm" OnSubmit="SubmitForm"
@ -72,13 +72,12 @@
<div class="card"> <div class="card">
<DxTabs> <DxTabs>
<DxTabPage Text="List"> <DxTabPage Text="Upcoming">
<DxAccordion <DxAccordion ExpandMode="ExpandMode"
ExpandMode="ExpandMode"
ExpandCollapseAction="ExpandCollapseAction" ExpandCollapseAction="ExpandCollapseAction"
AnimationType="LayoutAnimationType.Slide"> AnimationType="LayoutAnimationType.Slide">
<Items> <Items>
@foreach (var (transfer, i) in Items) @foreach (var (transfer, i) in Upcoming)
{ {
<DxAccordionItem CssClass="@GetCustomColor(transfer.TransferStatusType)" Text=@($"{transfer.Appointment} - {transfer.FromAddress}") Expanded=@(i == 0)> <DxAccordionItem CssClass="@GetCustomColor(transfer.TransferStatusType)" Text=@($"{transfer.Appointment} - {transfer.FromAddress}") Expanded=@(i == 0)>
@ -92,140 +91,26 @@
</Items> </Items>
</DxAccordion> </DxAccordion>
</DxTabPage> </DxTabPage>
<DxTabPage Text="DataGrid"> <DxTabPage Text="Problems">
<div class="d-flex flex-column mb-4 pb-2"> <DxAccordion ExpandMode="ExpandMode"
<div class="align-self-end pl-2 pb-2"> ExpandCollapseAction="ExpandCollapseAction"
<DxButton Text="Column Chooser" AnimationType="LayoutAnimationType.Slide">
RenderStyle="ButtonRenderStyle.Secondary" <Items>
IconCssClass="btn-column-chooser" @foreach (var (transfer, i) in Problems)
Click="ColumnChooserButton_Click" /> {
<DxAccordionItem CssClass="@GetCustomColor(transfer.TransferStatusType)" Text=@($"{transfer.Appointment} - {transfer.FromAddress}") Expanded=@(i == 0)>
<ContentTemplate>
<div class="py-3 px-3">
<TransferCardComponent DataChanged="RefreshComponent" Context="@transfer" />
</div> </div>
</ContentTemplate>
<TransferGrid @ref="_gridTransfer" </DxAccordionItem>
Logger="_logger"
GetAllMessageTag="SignalRTags.GetTransfersByUserProductMappingId"
SignalRClient="AdminSignalRClient"
ContextIds="new object[] {driverId}"
OnDataSourceChanged="DataSourceChanged"
OnGridItemChanging="DataSourceItemChanging"
OnGridItemChanged="DataSourceItemChanged"
OnGridItemDeleting="DataItemDeleting"
OnGridEditModelSaving="DataItemSaving"
CustomizeElement="Grid_CustomizeElement"
CustomizeEditModel="Grid_CustomizeEditModel"
EditMode="GridEditMode.EditForm"
ColumnResizeMode="GridColumnResizeMode.NextColumn"
AllowSelectRowByClick="false"
PageSize="13"
ShowFilterRow="true">
<Columns>
<DxGridCommandColumn Visible="false" Width="80" MinWidth="80" FixedPosition="GridColumnFixedPosition.Left" />
<DxGridDataColumn FieldName="Id" ShowInColumnChooser="AcDomain.IsDeveloperVersion" Visible="AcDomain.IsDeveloperVersion" DisplayFormat="N" />
<DxGridDataColumn FieldName="OrderId" Caption="Order" SortIndex="1" SortOrder="GridColumnSortOrder.Descending" Width="70">
<CellDisplayTemplate>
@{
var idKeyField = ((Transfer)context.DataItem).Id.ToString("N");
var editUri = $"mytransfers/{idKeyField}";
<NavLink href="@editUri">
<text>@context.Value</text>
</NavLink>
} }
</CellDisplayTemplate> </Items>
</DxGridDataColumn> </DxAccordion>
<DxGridDataColumn FieldName="FromAddress" />
<DxGridDataColumn FieldName="ToAddress" />
<DxGridDataColumn FieldName="Appointment" DisplayFormat="g" Width="125" />
<DxGridDataColumn FieldName="PassengerCount" Caption="Passengers" Width="90" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="LuggageCount" Caption="Luggages" Width="80" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="FlightNumber" Caption="FlightNum" Width="95" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="FullName" />
<DxGridDataColumn FieldName="ContactPhone" Width="120" />
<DxGridDataColumn FieldName="ContactEmail" Width="120">
<CellDisplayTemplate>
@{
var keyField = context.Value;
var keyItem = (Transfer)context.DataItem;
string buttonText = "Contact";
<DxButton Click="() => SendMail(keyItem)" Text="@buttonText" RenderStyle="ButtonRenderStyle.Primary" />
}
</CellDisplayTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="PaymentId" DisplayFormat="N" Visible="false" />
<DxGridDataColumn Caption="Paid" FieldName="Paid" Width="75" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="TransferStatusType" Caption="Status" SortIndex="0" Width="120" SortOrder="GridColumnSortOrder.Ascending" SortMode="GridColumnSortMode.Value">
<CellDisplayTemplate>
@{
TransferStatusModel keyField = Statuses.FirstOrDefault(x => x.StatusValue == (byte)context.Value)!;
string transferStatusText = keyField.StatusName;
<text>@transferStatusText</text>
}
</CellDisplayTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="ReferralId" DisplayFormat="N" Visible="false" />
<DxGridDataColumn FieldName="Comment" Caption="Comment" />
<DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="125" Visible="false" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
</Columns>
<DetailRowTemplate>
<DxTabs>
@{
var transfer = ((Transfer)context.DataItem);
}
<DxTabPage Text="Messages">
<MessageDetailGridComponent ContextId="transfer.Id" />
</DxTabPage> </DxTabPage>
<DxTabPage Text="Driver">
<TransferToDriverGridComponent ContextId="transfer.Id" ParentData="transfer" DriverId="driverId" NewButtonVisible="false" DeleteButtonVisible="false" />
</DxTabPage>
</DxTabs>
</DetailRowTemplate>
<EditFormTemplate Context="editFormContext">
@{
var transfer2 = (Transfer)editFormContext.EditModel;
}
<DxFormLayout CssClass="w-100">
<DxFormLayoutItem Caption=@localizer.GetString(ResourceKeys.FirstName) ColSpanMd="6">
@editFormContext.GetEditor("FirstName")
</DxFormLayoutItem>
<DxFormLayoutItem Caption=@localizer.GetString(ResourceKeys.LastName) ColSpanMd="6">
@editFormContext.GetEditor("LastName")
</DxFormLayoutItem>
<DxFormLayoutItem Caption=@localizer.GetString(ResourceKeys.DestinationAddress) ColSpanMd="6">
@editFormContext.GetEditor("ToAddress")
</DxFormLayoutItem>
<DxFormLayoutItem Caption=@localizer.GetString(ResourceKeys.PickupAddress) ColSpanMd="6">
@editFormContext.GetEditor("FromAddress")
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Trip date:" ColSpanMd="6">
<DxDateEdit @bind-Date="@transfer2.Appointment"
TimeSectionVisible="true"
TimeSectionScrollPickerFormat="tt h m">
</DxDateEdit>
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Passengers:" ColSpanMd="6">
@editFormContext.GetEditor("PassengerCount")
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Paid:" ColSpanMd="6">
@editFormContext.GetEditor("Payed")
</DxFormLayoutItem>
<DxFormLayoutItem Caption="Status:" ColSpanMd="6">
@editFormContext.GetEditor("TransferStatusType")
</DxFormLayoutItem>
</DxFormLayout>
</EditFormTemplate>
</TransferGrid>
</div>
</DxTabPage>
<DxTabPage Text="Calendar"> <DxTabPage Text="Calendar">
<div class="d-flex flex-column mb-4 pb-2"> <div class="d-flex flex-column mb-4 pb-2">
@ -243,6 +128,38 @@
</DxScheduler> </DxScheduler>
</div> </div>
</DxTabPage> </DxTabPage>
<DxTabPage Text="History">
<div class="d-flex flex-column mb-4 pb-2">
<TransferDetailGrid @ref="_gridTransfer"
Logger="_logger"
GetAllMessageTag="SignalRTags.GetTransfersByUserProductMappingId"
SignalRClient="AdminSignalRClient"
ContextIds="new object[] {driverId}"
CustomizeElement="Grid_CustomizeElement"
ShowGroupPanel="true"
CustomGroup="Grid_CustomGroup"
CustomizeGroupValueDisplayText="Grid_CustomizeGroupValueDisplayText"
EditMode="GridEditMode.EditForm"
ColumnResizeMode="GridColumnResizeMode.NextColumn"
AllowSelectRowByClick="false"
PageSize="13"
ShowFilterRow="true">
<Columns>
<DxGridDataColumn FieldName="Id" ShowInColumnChooser="AcDomain.IsDeveloperVersion" Visible="AcDomain.IsDeveloperVersion" DisplayFormat="N" />
<DxGridDataColumn FieldName="Appointment" SortOrder="GridColumnSortOrder.Descending" GroupIndex="0" GroupInterval="GridColumnGroupInterval.Custom" DisplayFormat="g" Width="125" />
<DxGridDataColumn FieldName="OrderId" Caption="Order" SortIndex="1" SortOrder="GridColumnSortOrder.Descending" Width="70" />
<DxGridDataColumn FieldName="FromAddress" />
<DxGridDataColumn FieldName="ToAddress" />
<DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="125" Visible="false" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
</Columns>
</TransferDetailGrid>
</div>
</DxTabPage>
</DxTabs> </DxTabs>
</div> </div>
</div> </div>
@ -258,16 +175,24 @@
[Parameter] public Guid DriverId { get; set; } [Parameter] public Guid DriverId { get; set; }
private Guid driverId; private Guid driverId;
private LoggerClient<DriverManageTransfers> _logger; private LoggerClient<DriverManageTransfers> _logger;
private bool _popupVisible;
private TransferGrid _gridTransfer; private TransferGrid _gridTransfer;
private bool _popupVisible;
private List<Transfer>? transfers = []; private List<Transfer>? transfers = [];
IEnumerable<(Transfer, int)> Items = []; IEnumerable<(Transfer, int)> Upcoming = [];
IEnumerable<(Transfer, int)> Problems = [];
AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone; AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone;
AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick; AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick;
private MessageWizardModel _messageWizardModel = new();
public List<AppointmentModel> AppointmentModels { get; set; } = null!;
DateTime StartDate { get; set; } = DateTime.Today;
DxSchedulerDataStorage _dataStorage = new();
public List<string> IgnoreList = public List<string> IgnoreList =
[ [
"ReceiverEmailAddress", "ReceiverEmailAddress",
@ -292,88 +217,6 @@
new(Convert.ToByte(TransferStatusType.AdminDenied), "Admin cancelled") new(Convert.ToByte(TransferStatusType.AdminDenied), "Admin cancelled")
]; ];
private static List<TransferStatusModel> _selectedCategories = Statuses.Where(x => /* x.StatusValue != (byte)TransferStatusType.OrderSubmitted && */ x.StatusValue != (byte)TransferStatusType.Finished && x.StatusValue != (byte)TransferStatusType.UserCanceled && x.StatusValue != (byte)TransferStatusType.AdminDenied).ToList();
private string _filterText = GetFilterText(_selectedCategories.Select(x => (TransferStatusType)x.StatusValue).ToList());
private MessageWizardModel _messageWizardModel = new();
public List<AppointmentModel> AppointmentModels { get; set; } = null!;
DateTime StartDate { get; set; } = DateTime.Today;
DxSchedulerDataStorage _dataStorage = new();
private void RefreshComponent()
{
StateHasChanged();
}
protected override async Task OnParametersSetAsync()
{
driverId = DriverId;
// transfers = await AdminSignalRClient.GetByIdAsync<List<Transfer>>(SignalRTags.GetTransfersByUserProductMappingId, DriverId);
}
void SendMail(Transfer item)
{
_logger.Info($"Sending mail to {item.ContactEmail}, {item.Id}");
_messageWizardModel.ReceiverId = item.UserId;
_messageWizardModel.ContextId = item.Id;
_messageWizardModel.SenderEmailAddress = "info@touriam.com";
_messageWizardModel.ReceiverEmailAddress = item.ContactEmail;
_messageWizardModel.ReceiverFullName = item.FullName;
_popupVisible = true;
}
void CancelCreateClick()
{
_popupVisible = false;
}
void EulaPopupClosed()
{
//cancel clicked
}
void EulaPopupClosing(PopupClosingEventArgs args)
{
//myModel = new TransferWizardModel();
_messageWizardModel = new MessageWizardModel();
}
//-----------------------------------------------------------------------------------
public async Task SubmitForm(object result)
{
var messageModel = (result as MessageWizardModel)!;
messageModel.ContextId = _messageWizardModel.ContextId;
//messageModel.SenderId = sessionService.User.UserId;
string FormatEmailContent()
{
return $@"
<html>
<body>
<p>Dear {messageModel.ReceiverFullName},</p>
<p>{messageModel.Content}:</p>
<p>Best regards,<br/>Tour I Am team</p>
</body>
</html>";
}
messageModel.Content = FormatEmailContent();
_logger.Info(messageModel.Content);
var email = await wizardProcessor.ProcessWizardAsync<MessageWizardModel>(result.GetType(), messageModel);
_logger.Info($"Submitted nested form: {result.GetType().FullName}");
}
void Grid_CustomizeElement(GridCustomizeElementEventArgs e) void Grid_CustomizeElement(GridCustomizeElementEventArgs e)
{ {
try try
@ -413,6 +256,106 @@
} }
} }
void Grid_CustomGroup(GridCustomGroupEventArgs e)
{
if (e.FieldName == "Appointment")
{
e.SameGroup = Grid_CompareColumnValues(((DateTime)e.Value1).Date, ((DateTime)e.Value2).Date);
e.Handled = true;
}
}
bool Grid_CompareColumnValues(DateTime value1, DateTime value2)
{
if (value1 == value2)
return true;
else
return false;
}
void Grid_CustomizeGroupValueDisplayText(GridCustomizeGroupValueDisplayTextEventArgs e)
{
if (e.FieldName == "Appointment")
{
string displayText = ((DateTime)e.Value).Date.ToString();
e.DisplayText = displayText;
}
}
private void RefreshComponent()
{
StateHasChanged();
}
protected override async Task OnParametersSetAsync()
{
driverId = DriverId;
// transfers = await AdminSignalRClient.GetByIdAsync<List<Transfer>>(SignalRTags.GetTransfersByUserProductMappingId, DriverId);
}
void SendMail(Transfer item)
{
_logger.Info($"Sending mail to {item.ContactEmail}, {item.Id}");
_messageWizardModel.ReceiverId = item.UserId;
_messageWizardModel.ContextId = item.Id;
_messageWizardModel.SenderEmailAddress = "info@touriam.com";
_messageWizardModel.ReceiverEmailAddress = item.ContactEmail;
_messageWizardModel.ReceiverFullName = item.FullName;
_popupVisible = true;
}
void CancelCreateClick()
{
_popupVisible = false;
}
void EmailPopupClosed()
{
//cancel clicked
}
void EmailPopupClosing(PopupClosingEventArgs args)
{
//myModel = new TransferWizardModel();
_messageWizardModel = new MessageWizardModel();
}
//-----------------------------------------------------------------------------------
public async Task SubmitForm(object result)
{
var messageModel = (result as MessageWizardModel)!;
messageModel.ContextId = _messageWizardModel.ContextId;
//messageModel.SenderId = sessionService.User.UserId;
string FormatEmailContent()
{
return $@"
<html>
<body>
<p>Dear {messageModel.ReceiverFullName},</p>
<p>{messageModel.Content}:</p>
<p>Best regards,<br/>Tour I Am team</p>
</body>
</html>";
}
messageModel.Content = FormatEmailContent();
_logger.Info(messageModel.Content);
var email = await wizardProcessor.ProcessWizardAsync<MessageWizardModel>(result.GetType(), messageModel);
_logger.Info($"Submitted nested form: {result.GetType().FullName}");
}
string GetCustomColor(TransferStatusType transferStatusType) string GetCustomColor(TransferStatusType transferStatusType)
{ {
@ -438,81 +381,7 @@
} }
void Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e)
{
if (!e.IsNew) return;
var transferEditModel = (Transfer)e.EditModel; //TODO not valid cast
transferEditModel.Id = Guid.NewGuid();
transferEditModel.ToAddress = "Where to?";
transferEditModel.FromAddress = "From where?";
transferEditModel.Appointment = DateTime.UtcNow.AddDays(3);
transferEditModel.PassengerCount = 1;
transferEditModel.FirstName = "John";
transferEditModel.LastName = "Doe";
transferEditModel.ContactPhone = "+00000000000";
transferEditModel.ContactEmail = "your@email.address";
}
private static string GetFilterText(ICollection<TransferStatusType> selectedTransferStatuses)
=> selectedTransferStatuses.Count == 0 ? string.Empty : CriteriaOperator.FromLambda<Transfer>(t => selectedTransferStatuses.Contains(t.TransferStatusType)).ToString();
void TagBox_ValuesChanged(IEnumerable<TransferStatusModel> newSelectedCategories)
{
var filterText = string.Empty;
InOperator? filterCriteria = null;
_selectedCategories = newSelectedCategories.ToList();
if (_selectedCategories.Count > 0)
{
filterCriteria = new InOperator("TransferStatusType", _selectedCategories.Select(c => c.StatusValue));
filterText = GetFilterText(_selectedCategories.Select(x => (TransferStatusType)x.StatusValue).ToList());
}
_filterText = filterText;
_gridTransfer.SetFieldFilterCriteria("TransferStatusType", filterCriteria);
}
private void DataSourceChanged(IList<Transfer> transfers)
{
_logger.Info("DataSourceChanged called");
InitializeAppointments(transfers);
if (_selectedCategories.Count > 0)
TagBox_ValuesChanged(_selectedCategories);
// if(!SelectedCategories.Any())
// SelectedCategories = [Statuses.FirstOrDefault(x => x.StatusValue == (byte)TransferStatusType.Finished)!];
// var filterTransferStatusType = Statuses.FirstOrDefault(x => x.StatusValue == (byte)TransferStatusType.Finished)!;
// if (SelectedCategories.All(x => x.StatusValue != filterTransferStatusType.StatusValue))
// SelectedCategories.Add(filterTransferStatusType);
}
private void DataSourceItemChanging(GridDataItemChangingEventArgs<Transfer> args)
{
_logger.Info("DataSourceItemChanging called");
}
private void DataSourceItemChanged(GridDataItemChangedEventArgs<Transfer> args)
{
_logger.Info("DataSourceItemChanged called");
AppointmentModels.UpdateCollection(CreateAppointmentModel(args.DataItem), args.TrackingState == TrackingState.Remove);
}
private void DataItemSaving(GridEditModelSavingEventArgs e)
{
_logger.Info("DataItemSaving called");
}
private void DataItemDeleting(GridDataItemDeletingEventArgs e)
{
_logger.Info($"DataItemDeleting OnItemDeleting");
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@ -520,13 +389,21 @@
if (transfers != null) if (transfers != null)
{ {
var test = DriverId.ToString(); var test = DriverId.ToString();
transfers = await AdminSignalRClient.GetByIdAsync<List<Transfer>>(SignalRTags.GetTransfersByUserProductMappingId, DriverId); var result = await AdminSignalRClient.GetByIdAsync<List<Transfer>>(SignalRTags.GetTransfersByUserProductMappingId, DriverId);
Items = transfers.Select((item, index) => (item, index)); transfers = result.Where(t => t.TransferStatusType != TransferStatusType.UserCanceled && t.TransferStatusType != TransferStatusType.AdminDenied).ToList();
Upcoming = transfers.Where(x => x.Appointment >= DateTime.Now).Select((item, index) => (item, index));
Problems = transfers.Where(x => x.Appointment < DateTime.Now && x.TransferStatusType != TransferStatusType.Finished).Select((item, index) => (item, index));
InitializeAppointments(transfers);
} }
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
private void GroupTransfers(List<Transfer> transferDataList)
{
}
private void InitializeAppointments(ICollection<Transfer> transferDataList) private void InitializeAppointments(ICollection<Transfer> transferDataList)
{ {
_logger.Info("InitializeAppointments called"); _logger.Info("InitializeAppointments called");
@ -569,17 +446,5 @@
return new AppointmentModel { Id = transfer.Id, StartDate = transfer.Appointment, EndDate = transfer.Appointment.AddMinutes(30), Description = $"{transfer.FullName}, {transfer.ToAddress}", Location = transfer.FromAddress, Caption = "Simple transfer" }; return new AppointmentModel { Id = transfer.Id, StartDate = transfer.Appointment, EndDate = transfer.Appointment.AddMinutes(30), Description = $"{transfer.FullName}, {transfer.ToAddress}", Location = transfer.FromAddress, Caption = "Simple transfer" };
} }
void ColumnChooserButton_Click()
{
_gridTransfer.ShowColumnChooser();
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
//_gridTransfer.ExpandDetailRow(0);
}
}
} }

View File

@ -1,5 +1,8 @@
@page "/user/createAndManageTransfer" @page "/user/createAndManageTransfer"
@using AyCode.Core.Consts
@using AyCode.Core.Helpers
@using TIAM.Entities.Products @using TIAM.Entities.Products
@using TIAM.Entities.ServiceProviders
@using TIAM.Entities.Transfers @using TIAM.Entities.Transfers
@using TIAM.Services @using TIAM.Services
@using TIAMSharedUI.Pages.Components.EditComponents @using TIAMSharedUI.Pages.Components.EditComponents
@ -7,6 +10,7 @@
@using AyCode.Services.Loggers @using AyCode.Services.Loggers
@using TIAMWebApp.Shared.Application.Interfaces; @using TIAMWebApp.Shared.Application.Interfaces;
@using TIAMWebApp.Shared.Application.Models.ClientSide.UI.WizardModels @using TIAMWebApp.Shared.Application.Models.ClientSide.UI.WizardModels
@using TIAMWebApp.Shared.Application.Models.PageModels
@using TIAMWebApp.Shared.Application.Services @using TIAMWebApp.Shared.Application.Services
@using TIAMWebApp.Shared.Application.Utility @using TIAMWebApp.Shared.Application.Utility
@layout AdminLayout @layout AdminLayout
@ -15,6 +19,7 @@
@inject IUserDataService UserDataService @inject IUserDataService UserDataService
@inject IEnumerable<IAcLogWriterClientBase> LogWriters @inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject AdminSignalRClient _adminSignalRClient @inject AdminSignalRClient _adminSignalRClient
@inject NavigationManager navManager
<PageTitle>Create transfer</PageTitle> <PageTitle>Create transfer</PageTitle>
@ -26,6 +31,11 @@
<!--We need to check if the user is owner of a swerviceprovider--> <!--We need to check if the user is owner of a swerviceprovider-->
<div class="container-fluid"> <div class="container-fluid">
<div class="row d-flex justify-content-center">
<div class="col-12 col-md-6">
<h3>Selected Hotel:</h3> <h3>Selected Hotel:</h3>
<DxComboBox Data="@Hotels" <DxComboBox Data="@Hotels"
@bind-Value="@SelectedHotel" @bind-Value="@SelectedHotel"
@ -35,19 +45,24 @@
TextFieldName="Name"></DxComboBox> TextFieldName="Name"></DxComboBox>
<div class="row py-3"> <div class="row py-3">
<div class=" col-12 col-xl-3">
</div>
<DynamicEditForm Data="Data" isEditing="true" IgnoreReflection="TransferIgnorList" OnSubmit="SubmitForm"></DynamicEditForm> <DynamicEditForm Data="Data" isEditing="true" IgnoreReflection="TransferIgnorList" OnSubmit="SubmitForm"></DynamicEditForm>
</div> </div>
<div class="row py-3">
<DxButton RenderStyle="ButtonRenderStyle.Primary" Click="@Reload" Visible="@isReloadVisible">Reload</DxButton>
</div>
</div>
</div>
</div> </div>
@code { @code {
private LoggerClient<CreateAndManageTransfer> _logger; private LoggerClient<CreateAndManageTransfer> _logger;
private TransferWizardModel Data; private TransferWizardModel Data = new();
private List<Product> Hotels = new List<Product>(); private List<Product> Hotels = new List<Product>();
private Product SelectedHotel; private Product SelectedHotel;
public List<string> TransferIgnorList = new List<string> public List<string> TransferIgnorList = new List<string>
@ -62,7 +77,7 @@
nameof(TransferWizardModel.ReferralId), nameof(TransferWizardModel.ReferralId),
nameof(TransferWizardModel.Price) nameof(TransferWizardModel.Price)
}; };
private bool isReloadVisible = false;
protected override void OnInitialized() protected override void OnInitialized()
{ {
@ -87,11 +102,60 @@
var valami = ((TransferWizardModel)result).CopyToTransfer(); var valami = ((TransferWizardModel)result).CopyToTransfer();
valami.Id = Guid.NewGuid(); valami.Id = Guid.NewGuid();
valami.ProductId = SelectedHotel.Id; valami.ProductId = SelectedHotel.Id;
var user = await UserDataService.GetUserByEmailAsync(valami.ContactEmail);
if (user != null && user.Id != Guid.Empty)
{
//user exists already
var userDetail = await UserDataService.GetUserDetailByIdAsync(user.Id);
valami.ReferralId = userDetail.UserDto.RefferalId;
valami.UserId = userDetail.Id;
}
else
{
//create a guest user and set referralId
var registration = new RegistrationModel();
//TODO: Refractor to userDataService
// var random = new Random();
// const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
// var password = new string(Enumerable.Repeat(chars, 10)
// .Select(s => s[random.Next(s.Length)]).ToArray());
var password = AcCharsGenerator.NewPassword(AcConst.MinPasswordLength, 16);
registration.Email = valami.ContactEmail;
registration.PhoneNumber = valami.ContactPhone;
registration.Password = password;
//get list with one member!
var productOwner = await _adminSignalRClient.GetByIdAsync<List<Company>>(SignalRTags.GetCompaniesById, SelectedHotel.ServiceProviderId);
registration.ReferralId = productOwner[0].AffiliateId;
var createResult = await UserDataService.CreateGuestUser(registration);
if(createResult.isSuccess)
{
if (createResult.user != null)
{
valami.UserId = createResult.user.Id;
}
}
_logger.Info("New user created added");
}
//valami.ProductId = SessionService.User.UserId; //TODO ProductID! //valami.ProductId = SessionService.User.UserId; //TODO ProductID!
// await WizardProcessor.ProcessWizardAsync<TransferDestinationWizardModel>(result.GetType(), result); // await WizardProcessor.ProcessWizardAsync<TransferDestinationWizardModel>(result.GetType(), result);
var saveResult = await _adminSignalRClient.PostDataAsync<Transfer>(SignalRTags.AddTransfer, valami); var saveResult = await _adminSignalRClient.PostDataAsync<Transfer>(SignalRTags.AddTransfer, valami);
_logger.Info($"Submitted nested form: {result.GetType().FullName}, {valami.ToAddress}, {valami.FromAddress}, {valami.ProductId}"); _logger.Info($"Submitted form: {result.GetType().FullName}, {valami.ToAddress}, {valami.FromAddress}, {valami.ProductId}");
isReloadVisible = true;
} }
public void Reload()
{
Data = new TransferWizardModel();
isReloadVisible = false;
StateHasChanged();
}
} }

View File

@ -13,7 +13,7 @@
<!--We need to check if the user is owner of a swerviceprovider--> <!--We need to check if the user is owner of a swerviceprovider-->
<div class="container"> <div class="container-fluid">
<HotelComponent Id="@id"></HotelComponent> <HotelComponent Id="@id"></HotelComponent>

View File

@ -103,25 +103,13 @@
} }
</CellDisplayTemplate> </CellDisplayTemplate>
</DxGridDataColumn> </DxGridDataColumn>
<DxGridDataColumn FieldName="Revenue" Caption="Revenue" Width="70" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="FullName" /> <DxGridDataColumn FieldName="FullName" />
<DxGridDataColumn FieldName="ContactPhone" Width="120" /> <DxGridDataColumn FieldName="ContactPhone" Width="120" />
<DxGridDataColumn FieldName="ContactEmail" Width="120"> <DxGridDataColumn FieldName="ContactEmail" Width="120">
</DxGridDataColumn> </DxGridDataColumn>
<DxGridDataColumn FieldName="PaymentId" DisplayFormat="N" Visible="false" />
<DxGridDataColumn Caption="Paid" FieldName="Paid" Width="75" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="TransferStatusType" Caption="Status" SortIndex="0" Width="120" SortOrder="GridColumnSortOrder.Ascending" SortMode="GridColumnSortMode.Value">
<CellDisplayTemplate>
@{
TransferStatusModel keyField = Statuses.FirstOrDefault(x => x.StatusValue == (byte)context.Value)!;
string transferStatusText = keyField.StatusName; <DxGridDataColumn FieldName="ReferralId" DisplayFormat="N" Visible="true" />
<text>@transferStatusText</text>
}
</CellDisplayTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="ReferralId" DisplayFormat="N" Visible="false" />
<DxGridDataColumn FieldName="Comment" Caption="Comment" /> <DxGridDataColumn FieldName="Comment" Caption="Comment" />
<DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="125" Visible="false" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" /> <DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="125" Visible="false" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
</Columns> </Columns>
@ -143,9 +131,7 @@
</div> </div>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div> </div>
<div class="card-footer py-2 px-4"> <div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -174,43 +160,11 @@
</div> </div>
</div> </div>
<div class="card-body card-admin-body py-2 px-4"> <div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-column mb-4 pb-2"> @if (Id != null)
{
<MessageDetailGridComponent ContextId="@Id"></MessageDetailGridComponent>
}
<div class="media text-muted pt-3">
<!--img src="https://bootdey.com/img/Content/avatar/avatar7.png" alt="" class="mr-2 rounded" width="32" height="32"-->
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
<strong class="d-block text-gray-dark">username</strong>
Donec id elit non mi porta gravida at eget metus...
</p>
</div>
<div class="media text-muted pt-3">
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
<strong class="d-block text-gray-dark">username</strong>
Donec id elit non mi porta gravida at eget metus...
</p>
</div>
<div class="media text-muted pt-3">
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
<strong class="d-block text-gray-dark">username</strong>
Donec id elit non mi porta gravida at eget metus...
</p>
</div>
<div class="media text-muted pt-3">
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
<strong class="d-block text-gray-dark">username</strong>
Donec id elit non mi porta gravida at eget metus...
</p>
</div>
</div>
</div> </div>
<div class="card-footer py-2 px-4"> <div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -253,7 +207,7 @@
<Columns> <Columns>
<DxGridDataColumn FieldName="Id" ShowInColumnChooser="AcDomain.IsDeveloperVersion" Visible="AcDomain.IsDeveloperVersion" DisplayFormat="N" /> <DxGridDataColumn FieldName="Id" ShowInColumnChooser="AcDomain.IsDeveloperVersion" Visible="AcDomain.IsDeveloperVersion" DisplayFormat="N" />
<DxGridDataColumn FieldName="OrderId" Caption="Order" SortIndex="1" SortOrder="GridColumnSortOrder.Descending" Width="70"> <DxGridDataColumn FieldName="OrderId" Caption="Order" SortIndex="1" SortOrder="GridColumnSortOrder.Descending">
<CellDisplayTemplate> <CellDisplayTemplate>
@{ @{
var idKeyField = ((Transfer)context.DataItem).Id.ToString("N"); var idKeyField = ((Transfer)context.DataItem).Id.ToString("N");
@ -264,8 +218,8 @@
} }
</CellDisplayTemplate> </CellDisplayTemplate>
</DxGridDataColumn> </DxGridDataColumn>
<DxGridDataColumn Caption="Paid" FieldName="Paid" Width="75" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" /> <DxGridDataColumn Caption="Paid" FieldName="Paid" TextAlignment="GridTextAlignment.Center" CaptionAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="Revenue" Caption="Revenue" Width="70" CaptionAlignment="GridTextAlignment.Center" /> <DxGridDataColumn FieldName="Revenue" Caption="Revenue" CaptionAlignment="GridTextAlignment.Center" />
</Columns> </Columns>
</TransferGrid> </TransferGrid>
</div> </div>

View File

@ -0,0 +1,192 @@
@page "/user/account/{userId:guid}"
@using BlazorAnimation
@using TIAM.Core.Enums
@using TIAM.Entities.Emails
@using TIAM.Entities.Profiles
@using TIAM.Entities.Transfers
@using TIAM.Models.Dtos.Users
@using TIAM.Resources
@using TIAM.Services
@using TIAMSharedUI.Pages.Components
@using TIAMSharedUI.Pages.User.CardComponents
@using TIAMSharedUI.Pages.User.SysAdmins
@using TIAMSharedUI.Shared
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models.ClientSide.UI
@using TIAMWebApp.Shared.Application.Models.ClientSide.UI.WizardModels
@using TIAMWebApp.Shared.Application.Models.PageModels
@using TIAMWebApp.Shared.Application.Utility
@using AyCode.Services.Loggers
@using TIAMWebApp.Shared.Application.Services
@using TIAMSharedUI.Shared.Components.Grids
@using AyCode.Core.Enums
@using AyCode.Core.Extensions
@using AyCode.Core.Consts
@using AyCode.Core
@using AyCode.Core.Helpers
@using DevExpress.Data.Filtering
@layout AdminLayout
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject IStringLocalizer<TIAMResources> localizer
@inject IWizardProcessor wizardProcessor
@inject ITransferDataService transferDataService
@inject ISessionService sessionService
@inject AdminSignalRClient AdminSignalRClient;
<PageTitle>Transfers</PageTitle>
<div class="text-center m-5">
<h1>Tasks</h1>
<h2 style="font-size:small">Manage your tasks here!</h2>
</div>
<DxPopup CssClass="popup-demo-events"
@bind-Visible="@_popupVisible"
ShowFooter="true"
CloseOnEscape="true"
CloseOnOutsideClick="false"
ShowCloseButton="false"
HeaderText="Change password"
Closing="PasswordPopupClosing"
Closed="PasswordPopupClosed">
<BodyContentTemplate>
Change your password here
</BodyContentTemplate>
<FooterContentTemplate Context="Context">
<div class="popup-demo-events-footer">
<!--DxCheckBox CssClass="popup-demo-events-checkbox" @bind-Checked="@EulaAccepted">I accept the terms of the EULA</!--DxCheckBox-->
<!--DxButton CssClass="popup-demo-events-button ms-2" RenderStyle="ButtonRenderStyle.Primary" Text="OK" Click="Context.CloseCallback" /-->
<DxButton CssClass="popup-demo-events-button ms-2" RenderStyle="ButtonRenderStyle.Secondary" Text="Cancel" Click="CancelCreateClick" />
</div>
</FooterContentTemplate>
</DxPopup>
<div class="container-fluid">
<div class="row">
<div class=" col-12">
<div class="card">
<DxTabs>
<DxTabPage Text="Account details">
<div class="py-3 px-3">
<div class="d-flex flex-column mb-4 pb-2">
<UserCardComponent Context="@myUser" />
</div>
</div>
</DxTabPage>
<DxTabPage Text="Profiles">
<DxAccordion ExpandMode="ExpandMode"
ExpandCollapseAction="ExpandCollapseAction"
AnimationType="LayoutAnimationType.Slide">
<Items>
@foreach (var (profile, i) in ProfileItems)
{
<DxAccordionItem Text=@($"{profile.Name}") Expanded=@(i == 0)>
<ContentTemplate>
@* <div class="py-3 px-3">
<ProfileCardComponent DataChanged="RefreshComponent" Context="@transfer" />
</div> *@
</ContentTemplate>
</DxAccordionItem>
}
</Items>
</DxAccordion>
</DxTabPage>
</DxTabs>
</div>
</div>
<div class=" col-12 col-xl-6">
</div>
</div>
</div>
@code {
[Parameter] public Guid UserId { get; set; }
private Guid userId;
private LoggerClient<ManageAccount> _logger;
private bool _popupVisible;
private UserModelDtoDetail myUser;
private List<Profile> profiles = [];
IEnumerable<(Profile, int)> ProfileItems = [];
AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone;
AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick;
DateTime StartDate { get; set; } = DateTime.Today;
DxSchedulerDataStorage _dataStorage = new();
private void RefreshComponent()
{
StateHasChanged();
}
protected override async Task OnParametersSetAsync()
{
userId = UserId;
// transfers = await AdminSignalRClient.GetByIdAsync<List<Transfer>>(SignalRTags.GetTransfersByUserProductMappingId, DriverId);
}
void CancelCreateClick()
{
_popupVisible = false;
}
void PasswordPopupClosed()
{
//cancel clicked
}
void PasswordPopupClosing(PopupClosingEventArgs args)
{
}
//-----------------------------------------------------------------------------------
public async Task SubmitForm(object result)
{
_logger.Info($"Submitted nested form: {result.GetType().FullName}");
}
protected override async Task OnInitializedAsync()
{
_logger = new LoggerClient<ManageAccount>(LogWriters.ToArray());
if (!UserId.IsNullOrEmpty())
{
var test = UserId.ToString();
if (sessionService.User != null)
{
myUser = sessionService.User.UserModelDto;
}
profiles.Add(myUser.ProfileDto);
ProfileItems = profiles.Select((item, index) => (item, index));
//further profile by userproductmapping
}
await base.OnInitializedAsync();
}
}

View File

@ -0,0 +1,5 @@
<h3>ManageMessages</h3>
@code {
}

View File

@ -32,14 +32,12 @@
<Animation Effect="@Effect.FadeIn" Speed="@Speed.Fast" Delay="@TimeSpan.FromMilliseconds(250)"> <Animation Effect="@Effect.FadeIn" Speed="@Speed.Fast" Delay="@TimeSpan.FromMilliseconds(250)">
<div class="card"> <div class="card">
<div class="d-flex flex-column mb-4 pb-2"> <div class="d-flex flex-column mb-4 pb-2">
<div class="align-self-end pl-2 pb-2">
<DxButton Text="Column Chooser"
RenderStyle="ButtonRenderStyle.Secondary"
IconCssClass="btn-column-chooser"
Click="ColumnChooserButton_Click" />
</div>
<CarGridComponent DetailExpandButtonDisplayMode="GridDetailExpandButtonDisplayMode.Auto" GetAllTag="SignalRTags.GetAllCars"></CarGridComponent> <CarGridComponent
@ref="@Grid"
DetailExpandButtonDisplayMode="GridDetailExpandButtonDisplayMode.Auto"
GetAllTag="SignalRTags.GetAllCars">
</CarGridComponent>
</div> </div>
@ -57,123 +55,9 @@
private LoggerClient<ManageUserProductMappings> _logger; private LoggerClient<ManageUserProductMappings> _logger;
//public UserModelDtoDetail UserModelDtoDetail = new(); //public UserModelDtoDetail UserModelDtoDetail = new();
CarGridComponent Grid { get; set; }
bool PopupVisible { get; set; }
IGrid Grid { get; set; }
//object? MasterGridData { get; set; } //object? MasterGridData { get; set; }
public List<string> IgnoreList =
[
"ReceiverEmailAddress",
"ReceiverId",
"SenderEmailAddress",
"SenderId",
"ContextId"
];
void Grid_CustomizeElement(GridCustomizeElementEventArgs e)
{
if (e.ElementType == GridElementType.DataRow && e.VisibleIndex % 2 == 1)
{
e.CssClass = "bg-alt";
}
else if (e.ElementType == GridElementType.HeaderCell)
{
e.Style = "background-color: rgba(0, 0, 0, 0.08); font-style=bold";
}
}
void Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e)
{
if (!e.IsNew) return;
var userEditModel = (UserModelDtoDetail)e.EditModel; //TODO not valid cast
userEditModel.Id = Guid.NewGuid();
userEditModel.UserDto = new UserDtoDetail
{
AffiliateId = Guid.NewGuid(),
EmailAddress = "",
PhoneNumber = ""
};
userEditModel.ProfileDto = new TIAM.Entities.Profiles.Profile
{
Name = "New user"
};
userEditModel.Products = [];
userEditModel.ServiceProviders = [];
userEditModel.UserProductMappings = [];
}
async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e)
{
var userModelDtoDetail = ((UserModelDtoDetail)e.EditModel);
if (e.IsNew)
{
//add new orderData to orderData array
var registration = new RegistrationModel();
//TODO: Refractor to userDataService
// var random = new Random();
// const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
// var password = new string(Enumerable.Repeat(chars, 10)
// .Select(s => s[random.Next(s.Length)]).ToArray());
var password = AcCharsGenerator.NewPassword(AcConst.MinPasswordLength, 16);
registration.Email = userModelDtoDetail.UserDto.EmailAddress;
registration.PhoneNumber = userModelDtoDetail.UserDto.PhoneNumber;
registration.Password = password;
registration.ReferralId = null;
await UserDataService.CreateGuestUser(registration);
_logger.Info("New user created added");
}
else
{
_logger.Info("orderData updated at id " + userModelDtoDetail.Id);
//await transferDataService.UpdateTransferAsync((TransferWizardModel)e.EditModel);
//modify transferData where transferData.Id == e.EditModel.Id
}
//get transfer from TransferData by Id
// foreach (var transferToModify in (List<Transfer>)TransferData)
// {
// myModel = (Transfer)e.EditModel;
// if (transferToModify.Id == myModel.Id)
// {
// //transferToModify.Driver = myModel.Driver;
// }
// }
//TODO: ne a teljes grid-et refresh-eljük, elég lenne csak az adott sort! - J.
await UpdateDataAsync();
}
async Task Grid_DataItemDeleting(GridDataItemDeletingEventArgs e)
{
//await NwindDataService.RemoveEmployeeAsync((EditableEmployee)e.DataItem);
//remove orderData from orderData array
_logger.Info("orderData deleted");
//await UpdateDataAsync();
}
async Task UpdateDataAsync()
{
//refresh grid
_logger.Info("orderData grid refreshed");
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
_logger = new LoggerClient<ManageUserProductMappings>(LogWriters.ToArray()); _logger = new LoggerClient<ManageUserProductMappings>(LogWriters.ToArray());
@ -181,9 +65,6 @@
base.OnInitialized(); base.OnInitialized();
} }
void ColumnChooserButton_Click()
{
Grid.ShowColumnChooser();
}
} }

View File

@ -15,7 +15,7 @@
<h2 style="font-size:small">Manage transfers here!</h2> <h2 style="font-size:small">Manage transfers here!</h2>
</div> </div>
<div class="container"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<h3>@localizer.GetString("TransferDestination")</h3> <h3>@localizer.GetString("TransferDestination")</h3>

View File

@ -68,7 +68,7 @@
<Animation Effect="@Effect.FadeIn" Speed="@Speed.Fast" Delay="@TimeSpan.FromMilliseconds(250)"> <Animation Effect="@Effect.FadeIn" Speed="@Speed.Fast" Delay="@TimeSpan.FromMilliseconds(250)">
<div class="card"> <div class="card">
<DxTabs>+- <DxTabs>
<DxTabPage Text="DataGrid"> <DxTabPage Text="DataGrid">
<div class="d-flex flex-column mb-4 pb-2"> <div class="d-flex flex-column mb-4 pb-2">

View File

@ -61,19 +61,17 @@
</CellDisplayTemplate> </CellDisplayTemplate>
</DxGridDataColumn> </DxGridDataColumn>
<DxGridDataColumn Caption=@Localizer.GetString(ResourceKeys.Price) FieldName="Price" Width="100" /> <DxGridDataColumn Caption=@Localizer.GetString(ResourceKeys.Price) FieldName="Price" Width="100" />
<DxGridDataColumn Caption=@Localizer.GetString(ResourceKeys.ProductDescription) FieldName="Description" /> <DxGridDataColumn Caption="Options">
<DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="140" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" /> <CellDisplayTemplate>
<DxGridDataColumn FieldName="Modified" DisplayFormat="g" Width="140" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
</Columns>
<DetailRowTemplate>
@{ @{
//check if has transferdestination //check if has transferdestination
var AddressId = ((Product)context.DataItem).Profile.AddressId; var AddressId = ((Product)context.DataItem).Profile.AddressId;
var result = CheckDestinations(AddressId); var result = CheckDestinations(AddressId);
//if not, display button //if not, display button
if(!result) if (!result)
{ <p>Address:</p> {
<p>@(((Product)context.DataItem).Profile.Address.AddressText)</p> // <p>Address:</p>
// <p>@(((Product)context.DataItem).Profile.Address.AddressText)</p>
<DxButton Click="() => SaveAsDestination(((Product)context.DataItem).Profile.Address, (Product)context.DataItem)" Text="Save as destination" RenderStyle="ButtonRenderStyle.Primary" /> <DxButton Click="() => SaveAsDestination(((Product)context.DataItem).Profile.Address, (Product)context.DataItem)" Text="Save as destination" RenderStyle="ButtonRenderStyle.Primary" />
} }
else else
@ -81,9 +79,16 @@
<p>Address:</p> <p>Address:</p>
<p>@(((Product)context.DataItem).Profile.Address.AddressText)</p> <p>@(((Product)context.DataItem).Profile.Address.AddressText)</p>
} }
} }
</CellDisplayTemplate>
</DxGridDataColumn>
<DxGridDataColumn Caption=@Localizer.GetString(ResourceKeys.ProductDescription) FieldName="Description" />
<DxGridDataColumn FieldName="Created" DisplayFormat="g" Width="140" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
<DxGridDataColumn FieldName="Modified" DisplayFormat="g" Width="140" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center" />
</Columns>
<DetailRowTemplate>
<DxTabs> <DxTabs>
<DxTabPage Text="Permissions"> <DxTabPage Text="Permissions">
<UserProductMappingGridComponent DetailExpandButtonDisplayMode="GridDetailExpandButtonDisplayMode.Never" ContextIds="new [] {((Product)context.DataItem).Id}" GetAllTag="SignalRTags.GetUserProductMappingsByProductId"> <UserProductMappingGridComponent DetailExpandButtonDisplayMode="GridDetailExpandButtonDisplayMode.Never" ContextIds="new [] {((Product)context.DataItem).Id}" GetAllTag="SignalRTags.GetUserProductMappingsByProductId">
@ -179,6 +184,7 @@
transferDestination.AddressString = address.AddressText; transferDestination.AddressString = address.AddressText;
var result = await AdminSignalRClient.PostDataAsync<TransferDestination>(SignalRTags.CreateTransferDestination, transferDestination); var result = await AdminSignalRClient.PostDataAsync<TransferDestination>(SignalRTags.CreateTransferDestination, transferDestination);
_productGrid.Reload(); _productGrid.Reload();
await InvokeAsync(StateHasChanged);
} }
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()

View File

@ -58,7 +58,14 @@
<NavLink href="@($"mytransfers/{Guid.Parse("108E5A63-AA9E-47BE-ACFA-00306FFC5215")}")"> <NavLink href="@($"mytransfers/{Guid.Parse("108E5A63-AA9E-47BE-ACFA-00306FFC5215")}")">
My trasnfers My transfers
</NavLink>
</li>
<li>
<NavLink href="exchange-rate">
Exchange Rate
</NavLink> </NavLink>
</li> </li>
<li></li> <li></li>

View File

@ -0,0 +1,32 @@
<!-- Pages/ExchangeRate.razor -->
@page "/exchange-rate"
@using TIAMWebApp.Shared.Application.Models
@using TIAMWebApp.Shared.Application.Services
@inject ExchangeRateService ExchangeRateService
<h3>Exchange Rate</h3>
@if (exchangeRate == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>Current EUR to HUF exchange rate: @exchangeRate.EURtoHUF</p>
<input type="number" @bind="exchangeRate.EURtoHUF" step="0.01" />
<button @onclick="SaveExchangeRate">Save</button>
}
@code {
private ExchangeRate exchangeRate;
protected override async Task OnInitializedAsync()
{
exchangeRate = await ExchangeRateService.GetExchangeRateAsync();
}
private async Task SaveExchangeRate()
{
await ExchangeRateService.SetExchangeRateAsync(exchangeRate);
}
}

View File

@ -85,7 +85,7 @@
<div class="text-center">@SessionService.User.UserModelDto.ProfileDto.FullName</div> <div class="text-center">@SessionService.User.UserModelDto.ProfileDto.FullName</div>
</div> </div>
<div class="d-flex justify-content-center log-off-btn"> <div class="d-flex justify-content-center log-off-btn">
<DxButton Text="Log Off" RenderStyle="@ButtonRenderStyle.Secondary"></DxButton> <DxButton Text="Manage" RenderStyle="@ButtonRenderStyle.Secondary" Click="NavToAcc"></DxButton>
</div> </div>
</div> </div>
</div> </div>
@ -248,6 +248,12 @@
MenuDisplayMode DisplayMode { get; set; } = MenuDisplayMode.Auto; MenuDisplayMode DisplayMode { get; set; } = MenuDisplayMode.Auto;
Orientation Orientation { get; set; } = Orientation.Horizontal; Orientation Orientation { get; set; } = Orientation.Horizontal;
private void NavToAcc()
{
var url = $"user/account/{SessionService.User.UserId}";
NavigationManager.NavigateTo(url);
}
protected override void OnInitialized() protected override void OnInitialized()
{ {
_logger = new LoggerClient<AdminNavMenu>(LogWriters.ToArray()); _logger = new LoggerClient<AdminNavMenu>(LogWriters.ToArray());

View File

@ -434,8 +434,8 @@ select:focus-visible {
.form-field, .card .form-field { .form-field, .card .form-field {
padding-left: 10px; padding-left: 10px;
border-bottom: 1px solid; border-bottom: 1px solid;
margin-bottom: 20px; /*margin-bottom: 20px;
/*border-radius: 20px; border-radius: 20px;
box-shadow: inset 3px 3px 3px #cbced1, inset -3px -3px 3px #fff;*/ box-shadow: inset 3px 3px 3px #cbced1, inset -3px -3px 3px #fff;*/
} }
@ -489,6 +489,28 @@ select:focus-visible {
} }
} }
@media (max-width: 576px) {
.wrapper {
margin: 30px 20px;
padding: 40px 15px 15px 15px;
}
.carousel-item {
height: 30vh;
min-height: 350px;
background: no-repeat center center scroll;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.container-fluid {
padding-left: 0px;
padding-right: 0px;
}
}
/*forms end*/ /*forms end*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -46,6 +46,7 @@ builder.Services.AddSingleton<SignalRService>();
builder.Services.AddSingleton<SumupService>(); builder.Services.AddSingleton<SumupService>();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>(); builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddAuthorizationCore(); builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<ExchangeRateService>();
//builder.Services.AddScoped<BrowserConsoleLogWriter>(); //builder.Services.AddScoped<BrowserConsoleLogWriter>();
//WebSpecific end //WebSpecific end

View File

@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using QRCoder;
using System.Drawing;
using System.Drawing.Imaging;
using AyCode.Core.Enums;
using AyCode.Core.Extensions;
using TIAM.Database.DataLayers.Admins;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
using TIAMWebApp.Shared.Application.Models;
using Product = TIAM.Entities.Products.Product;
using TIAM.Entities.Addresses;
using TIAM.Entities.Profiles;
using AyCode.Core.Loggers;
using AyCode.Entities;
using AyCode.Services.SignalRs;
using AyCode.Utils.Extensions;
using TIAM.Entities.Drivers;
using TIAM.Services;
using TIAMWebApp.Server.Services;
using GoogleApi.Entities.Search.Video.Common;
namespace TIAMWebApp.Server.Controllers
{
[ApiController]
[Route("api/v1/[controller]")]
public class ExchangeRateAPIController(ExchangeRateService _service,IEnumerable<IAcLogWriterBase> logWriters) : ControllerBase
{
private readonly TIAM.Core.Loggers.Logger<ExchangeRateAPIController> _logger = new(logWriters.ToArray());
[AllowAnonymous]
[HttpGet]
[Route(APIUrls.GetExchangeRateRouteName)]
//[SignalR(SignalRTags.GetProfileById)]
public async Task<IActionResult> GetExchangeRate()
{
_logger.Info($@"GetExchangeRate called");
var rate = await _service.GetExchangeRateAsync();
return Ok(rate);
}
[AllowAnonymous]
[HttpPost]
[Route(APIUrls.UpdateExchangeRateRouteName)]
//[SignalR(SignalRTags.GetProfileById)]
public async Task<IActionResult> Set([FromBody] ExchangeRate rate)
{
_logger.Info($@"GetServiceProviderById called with rate: {rate.EURtoHUF}");
await _service.SetExchangeRateAsync(rate);
return Ok();
}
}
}

View File

@ -13,6 +13,9 @@ using TIAM.Services;
using AyCode.Core.Loggers; using AyCode.Core.Loggers;
using AyCode.Core.Extensions; using AyCode.Core.Extensions;
using TIAM.Entities.Products; using TIAM.Entities.Products;
using AyCode.Core.Consts;
using AyCode.Core;
using TIAM.Core.Consts;
namespace TIAMWebApp.Server.Controllers namespace TIAMWebApp.Server.Controllers
{ {
@ -54,12 +57,12 @@ namespace TIAMWebApp.Server.Controllers
var messageElement = message.Message; var messageElement = message.Message;
_logger.Debug(message.Message.Subject); _logger.Debug(message.Message.Subject);
messageElement.EmailAddress = "noreply@anataworld.com"; messageElement.EmailAddress = TiamConstClient.SystemEmailAddress;
await _adminDal.AddEmailMessageAsync(messageElement);
var result = await _messageSenderService.SendMessageAsync(messageElement, (int)message.MessageType); var result = await _messageSenderService.SendMessageAsync(messageElement, (int)message.MessageType);
//_adminDal.AddEmailMessageAsync((TIAM.Entities.Emails.EmailMessage)SerializedMessageSenderModel.Message); //_adminDal.AddEmailMessageAsync((TIAM.Entities.Emails.EmailMessage)SerializedMessageSenderModel.Message);
await _adminDal.AddEmailMessageAsync(messageElement);
_logger.Debug($"SendEmail result: {result}"); _logger.Debug($"SendEmail result: {result}");
return Ok(result); return Ok(result);

View File

@ -27,7 +27,7 @@ namespace TIAMWebApp.Server.Controllers
[Authorize] [Authorize]
[ApiController] [ApiController]
[Route("api/v1/[controller]")] [Route("api/v1/[controller]")]
public class ServiceProviderAPIController(AdminDal adminDal, IEnumerable<IAcLogWriterBase> logWriters) : ControllerBase public class ServiceProviderAPIController(AdminDal adminDal, IWebHostEnvironment env, IEnumerable<IAcLogWriterBase> logWriters) : ControllerBase
{ {
private readonly TIAM.Core.Loggers.Logger<ServiceProviderAPIController> _logger = new(logWriters.ToArray()); private readonly TIAM.Core.Loggers.Logger<ServiceProviderAPIController> _logger = new(logWriters.ToArray());
@ -510,7 +510,8 @@ namespace TIAMWebApp.Server.Controllers
var qrCodeData = qrGenerator.CreateQrCode($"https://touriam.com/{productId}", QRCodeGenerator.ECCLevel.Q); var qrCodeData = qrGenerator.CreateQrCode($"https://touriam.com/{productId}", QRCodeGenerator.ECCLevel.Q);
var qrCode = new QRCode(qrCodeData); var qrCode = new QRCode(qrCodeData);
//Bitmap qrCodeImage = qrCode.GetGraphic(20); //Bitmap qrCodeImage = qrCode.GetGraphic(20);
var rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "assets"); //var rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "assets");
var rootpath = System.IO.Path.Combine(env.WebRootPath, "assets");
var qrCodeImage = qrCode.GetGraphic(20, Color.DarkMagenta, Color.White, (Bitmap)Bitmap.FromFile(rootpath + "/myimage.png")); var qrCodeImage = qrCode.GetGraphic(20, Color.DarkMagenta, Color.White, (Bitmap)Bitmap.FromFile(rootpath + "/myimage.png"));
_logger.Info($@"qrCodeLogo: {rootpath}/myimage.png"); _logger.Info($@"qrCodeLogo: {rootpath}/myimage.png");
var ms = new MemoryStream(); var ms = new MemoryStream();

View File

@ -68,6 +68,7 @@ namespace TIAMWebApp.Server.Controllers
//[Authorize] //[Authorize]
//[HttpGet] //[HttpGet]
//[Route(APIUrls.GetTransferDriversByTransferIdRouteName)] //[Route(APIUrls.GetTransferDriversByTransferIdRouteName)]
[NonAction]
[SignalR(SignalRTags.GetTransferDestinationById)] [SignalR(SignalRTags.GetTransferDestinationById)]
public async Task<TransferDestination?> GetTransferDestinationById(Guid transferDestinationId) public async Task<TransferDestination?> GetTransferDestinationById(Guid transferDestinationId)
{ {
@ -139,6 +140,7 @@ namespace TIAMWebApp.Server.Controllers
//[Authorize] //[Authorize]
//[HttpGet] //[HttpGet]
//[Route(APIUrls.GetTransferDriversByTransferIdRouteName)] //[Route(APIUrls.GetTransferDriversByTransferIdRouteName)]
[NonAction]
[SignalR(SignalRTags.RemoveTransferDestination)] [SignalR(SignalRTags.RemoveTransferDestination)]
public async Task<TransferDestination?> RemoveTransferDestination([FromBody] TransferDestination transferDestination) public async Task<TransferDestination?> RemoveTransferDestination([FromBody] TransferDestination transferDestination)
{ {
@ -396,17 +398,36 @@ namespace TIAMWebApp.Server.Controllers
var from = destList.FirstOrDefault(x => x.AddressString == transfer.FromAddress); var from = destList.FirstOrDefault(x => x.AddressString == transfer.FromAddress);
var to = destList.FirstOrDefault(x => x.AddressString == transfer.ToAddress); var to = destList.FirstOrDefault(x => x.AddressString == transfer.ToAddress);
////TODO
//if (!transfer.ProductId.IsNullOrEmpty())
// transfer.Price = _transferBackendService.GetTransferPrice(transfer.ProductId.Value, from, to, transfer.PassengerCount);
Product? product = null;
//TODO //TODO
if (!transfer.ProductId.IsNullOrEmpty()) if (!transfer.ProductId.IsNullOrEmpty())
{
product = await _adminDal.GetProductByIdAsync((Guid)transfer.ProductId);
transfer.Price = _transferBackendService.GetTransferPrice(transfer.ProductId.Value, from, to, transfer.PassengerCount); transfer.Price = _transferBackendService.GetTransferPrice(transfer.ProductId.Value, from, to, transfer.PassengerCount);
}
transfer.TransferStatusType = TransferStatusType.OrderSubmitted; transfer.TransferStatusType = TransferStatusType.OrderSubmitted;
if (transfer.Price != null && transfer.Price > 0 && product != null)
{
if (product.ServiceProvider.CommissionPercent != null)
{
transfer.Revenue = transfer.Price * product.ServiceProvider.CommissionPercent / 100;
}
else
{
transfer.Revenue = 0;
}
}
await _adminDal.AddTransferAsync(transfer); await _adminDal.AddTransferAsync(transfer);
_logger.Info($"Created transfer, send emailMessage!!!"); _logger.Info($"Created transfer, send emailMessage!!!");
var message = new MessageSenderModel<EmailMessage>(); var message = new MessageSenderModel<EmailMessage>();
message.Message = new EmailMessage();
message.Message.Id = Guid.NewGuid(); message.Message.Id = Guid.NewGuid();
message.Message.Subject = "[Tour I Am] New transfer in Budapest"; message.Message.Subject = "[Tour I Am] New transfer in Budapest";
message.Message.ContextId = transfer.Id; message.Message.ContextId = transfer.Id;
@ -498,7 +519,7 @@ namespace TIAMWebApp.Server.Controllers
{ {
if(product.ServiceProvider.CommissionPercent!=null) if(product.ServiceProvider.CommissionPercent!=null)
{ {
transfer.Revenue = transfer.Price * product.ServiceProvider.CommissionPercent; transfer.Revenue = transfer.Price * product.ServiceProvider.CommissionPercent / 100;
} }
else else
{ {
@ -750,6 +771,7 @@ namespace TIAMWebApp.Server.Controllers
return result; return result;
} }
[NonAction]
//[Authorize] //[Authorize]
//[HttpGet] //[HttpGet]
//[Route(APIUrls.GetTransferDriverRouteName)] //[Route(APIUrls.GetTransferDriverRouteName)]

View File

@ -47,6 +47,7 @@ builder.Services.AddScoped<TransferDataAPIController>();
builder.Services.AddScoped<MessageAPIController>(); builder.Services.AddScoped<MessageAPIController>();
builder.Services.AddScoped<ProfileAPIController>(); builder.Services.AddScoped<ProfileAPIController>();
builder.Services.AddScoped<LoggerApiController>(); builder.Services.AddScoped<LoggerApiController>();
builder.Services.AddSingleton<ExchangeRateService>();
builder.Services.AddSignalR(options => options.MaximumReceiveMessageSize = 102400 * 1024);//.AddMessagePackProtocol(options => options.SerializerOptions = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData)); builder.Services.AddSignalR(options => options.MaximumReceiveMessageSize = 102400 * 1024);//.AddMessagePackProtocol(options => options.SerializerOptions = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData));

View File

@ -0,0 +1,34 @@
using System.IO;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.AspNetCore.Hosting;
using TIAMWebApp.Shared.Application.Models;
namespace TIAMWebApp.Server.Services
{
public class ExchangeRateService
{
private readonly IWebHostEnvironment _env;
private readonly string _filePath;
public ExchangeRateService(IWebHostEnvironment env)
{
_env = env;
_filePath = Path.Combine(_env.WebRootPath, "ExchangeRate.xml");
}
public async Task<ExchangeRate> GetExchangeRateAsync()
{
using var stream = new FileStream(_filePath, FileMode.Open);
var serializer = new XmlSerializer(typeof(ExchangeRate));
return (ExchangeRate)serializer.Deserialize(stream);
}
public async Task SetExchangeRateAsync(ExchangeRate rate)
{
using var stream = new FileStream(_filePath, FileMode.Create);
var serializer = new XmlSerializer(typeof(ExchangeRate));
serializer.Serialize(stream, rate);
}
}
}

View File

@ -8,6 +8,9 @@
<PropertyGroup> <PropertyGroup>
<WasmEnableSIMD>false</WasmEnableSIMD> <WasmEnableSIMD>false</WasmEnableSIMD>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Include="wwwroot\Assets\myimage.png" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<ExchangeRate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<EURtoHUF>380</EURtoHUF>
</ExchangeRate>

View File

@ -19,6 +19,7 @@ namespace TIAMWebApp.Shared.Application.Models
public const string FileAPI = BaseUrlWithSlashAndVersion + "FileAPI/"; public const string FileAPI = BaseUrlWithSlashAndVersion + "FileAPI/";
public const string MessageAPI = BaseUrlWithSlashAndVersion + "MessageAPI/"; public const string MessageAPI = BaseUrlWithSlashAndVersion + "MessageAPI/";
public const string PaymentAPI = BaseUrlWithSlashAndVersion + "PaymentAPI/"; public const string PaymentAPI = BaseUrlWithSlashAndVersion + "PaymentAPI/";
public const string ExchangeRateAPI = BaseUrlWithSlashAndVersion + "ExchangeRateAPI/";
public const string AddLogItemRouteName = "AddLogItem"; public const string AddLogItemRouteName = "AddLogItem";
public const string AddLogItem = LoggerApi + AddLogItemRouteName; public const string AddLogItem = LoggerApi + AddLogItemRouteName;
@ -132,7 +133,7 @@ namespace TIAMWebApp.Shared.Application.Models
public const string GetTransferDriverRouteName = "GetTransfersByDriverId"; public const string GetTransferDriverRouteName = "GetTransfersByDriverId";
public const string GetTransferDriver = TransferDataAPI + GetTransferDriverRouteName; public const string GetTransferDriver = TransferDataAPI + GetTransferDriverRouteName;
public const string GetTransferDriversByTransferIdRouteName = "GetTransfersByDriverId"; public const string GetTransferDriversByTransferIdRouteName = "GetTransferDriversByTransferId";
public const string GetTransferDriversByTransferId = TransferDataAPI + GetTransferDriversByTransferIdRouteName; public const string GetTransferDriversByTransferId = TransferDataAPI + GetTransferDriversByTransferIdRouteName;
//serviceprovider //serviceprovider
@ -268,5 +269,10 @@ namespace TIAMWebApp.Shared.Application.Models
public const string GetPaymentRouteName = "GetPaymentById"; public const string GetPaymentRouteName = "GetPaymentById";
public const string GetPaymentById = PaymentAPI + GetPaymentRouteName; public const string GetPaymentById = PaymentAPI + GetPaymentRouteName;
public const string UpdateExchangeRateRouteName = "UpdateExchangeRate";
public const string UpdateExchangeRate = ExchangeRateAPI + UpdateExchangeRateRouteName;
public const string GetExchangeRateRouteName = "GetExchangeRate";
public const string GetExchangeRate = ExchangeRateAPI + GetExchangeRateRouteName;
} }
} }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TIAMWebApp.Shared.Application.Models
{
public class ExchangeRate
{
public decimal EURtoHUF { get; set; }
}
}

View File

@ -0,0 +1,35 @@
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Models.ClientSide;
namespace TIAMWebApp.Shared.Application.Services
{
public class ExchangeRateService
{
private readonly HttpClient _httpClient;
public ExchangeRateService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<ExchangeRate> GetExchangeRateAsync()
{
var url = $"{Setting.ApiBaseUrl}/{APIUrls.GetExchangeRate}";
return await _httpClient.GetFromJsonAsync<ExchangeRate>(url);
}
public async Task SetExchangeRateAsync(ExchangeRate rate)
{
var url = $"{Setting.ApiBaseUrl}/{APIUrls.UpdateExchangeRate}";
await _httpClient.PostAsJsonAsync(url, rate);
}
}
}