Product, Perssions, ServideProvider, AssignedUser, Sessionmanagement improvements, Localization

This commit is contained in:
Adam 2023-12-10 12:05:54 +01:00
parent affed0c7a5
commit 558f6de8e4
95 changed files with 4874 additions and 577 deletions

View File

@ -39,9 +39,18 @@ namespace TIAM.Database.DataLayers.Users
public Task<bool> UpdateUserAsync(User user)
{
user.Modified = DateTime.UtcNow;
Ctx.Users.Update(user);
var existingUser = Ctx.Users.FirstOrDefault(u => u.Email == user.Email);
if (existingUser != null)
{
//user.Modified = DateTime.UtcNow; //ezt nem kell megadni, a háttérben ezt magától megcsinálja a DbContextBase - J.
existingUser = user;
Ctx.Users.Update(existingUser);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
throw new Exception("User not found");
}
}
}
}

View File

@ -0,0 +1,588 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Models.Enums;
using Microsoft.EntityFrameworkCore;
using TIAM.Database.DbContexts;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Products.DTOs;
using TIAM.Entities.Users;
namespace TIAM.Database.DataLayers.ServiceProviders
{
public class ServiceProviderDal : TiamDalBase<ServiceProviderDbContext>
{
public ServiceProviderDal() : base()
{
}
public ServiceProviderDal(ServiceProviderDbContext _object)
{
}
#region ServiceProviders
//16. (IServiceProviderDataService) get all service providers
public Task<List<TiamServiceProvider>> GetServiceProvidersAsync()
{
return Ctx.ServiceProviders.ToListAsync();
}
//18. (IServiceProviderDataService) get serviceProvider by Id
public virtual Task<TiamServiceProvider?> GetServiceProviderByIdAsync(Guid id)
{
Console.WriteLine($"Getting serviceProvider from db {id}");
return Ctx.ServiceProviders.SingleOrDefaultAsync(x=>x.Id == id);
}
//15. (IServiceProviderDataService) Create service provider
public Task<bool> CreateServiceProviderAsync(TiamServiceProvider serviceProvider)
{
if(serviceProvider.Name == Ctx.ServiceProviders.FirstOrDefault(x=>x.Name == serviceProvider.Name)?.Name)
{
throw new Exception("ServiceProvider already exists");
}
else
{
Ctx.ServiceProviders.Add(serviceProvider);
Console.WriteLine($"Saving serviceProvider to db {serviceProvider.Id}, {serviceProvider.Name}, {serviceProvider.OwnerId}");
return Ctx.SaveChangesAsync().ContinueWith(x=>x.Result > 0);
}
}
//14. (IserviceProviderDataService) Update service provider
public Task<bool> UpdateServiceProviderAsync(TiamServiceProvider serviceProvider)
{
var dbServiceProvider = Ctx.ServiceProviders.FirstOrDefault(u => u.Id == serviceProvider.Id);
if (dbServiceProvider != null)
{
dbServiceProvider = serviceProvider;
Ctx.ServiceProviders.Update(dbServiceProvider);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
throw new Exception("ServiceProvider not found");
}
}
//13. (IserviceProviderDataService) delete service provider
public Task<bool> DeleteServiceProviderAsync(Guid id)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var dbServiceProvider = Ctx.ServiceProviders.FirstOrDefault(u => u.Id == id);
if (dbServiceProvider != null)
{
//get products for this provider
var products = Ctx.Products.Where(x => x.OwnerId == id).ToList();
/*foreach (var productItem in products)
{
//delete products
var permissionContextMappings = Ctx.PermissionContextMappings.Where(x => x.ContextId == productItem.Id).ToList();
//iterate through every row
foreach (var item in permissionContextMappings)
{
if (item.SubjectType == (int)PermissionContextMappingSubjectType.Group)
{
//get users in the permissiongroup
var permissionGroupUserMapping = Ctx.PermissionGroupUserMappings.Where(x => x.PermissionContextMappingId == item.Id).ToList();
//remove every row (users) from permissiongroup
foreach (var user in permissionGroupUserMapping)
{
Ctx.PermissionGroupUserMappings.Remove(user);
}
}
}
//remove permissioncontextmappings
Ctx.PermissionContextMappings.RemoveRange(permissionContextMappings);
}*/
Ctx.Products.RemoveRange(products);
Ctx.ServiceProviders.Remove(dbServiceProvider);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
return Task.FromResult(false);
}
}
}
//17. (IServiceProviderDataService) get service provider by ownerId
public Task<List<TiamServiceProvider>> GetServiceProvidersByOwnerIdAsync()
{
throw new NotImplementedException();
}
#endregion
#region PermissionTypes
//10. (IPermissionService) create permission type
public Task<bool> CreatePermissionsTypeAsync(PermissionsType permissionsType)
{
bool result = false;
using (var transaction = Ctx.Database.BeginTransaction())
{
var existingPermission = Ctx.PermissionsTypes
.FirstOrDefault(x => x.PermissionName == permissionsType.PermissionName)?.PermissionName;
if (existingPermission == null)
{
//get all the permissiontypes for this context
var permissionTypes = new List<PermissionsType>();
var nextBitValue = 0.0;
permissionTypes = Ctx.PermissionsTypes
.Where(x => x.ContextId == permissionsType.ContextId)
.ToList();
//get the max value of the permissiontypes
if (permissionTypes != null)
{
//next bit value is the power of two of the count of the permissiontypes
nextBitValue = Math.Pow(2, permissionTypes.Count);
}
else
{
nextBitValue = Math.Pow(2,0);
}
permissionsType.PermissionBit = (int)nextBitValue;
Ctx.PermissionsTypes.Add(permissionsType);
Ctx.SaveChanges();
transaction.Commit();
result = true;
}
else
{
result = false;
}
}
return Task.FromResult(result);
}
//11. (IPermissionService) get permission types for context
public Task<List<PermissionsType>>? GetPermissionTypesByContextIdAsync(Guid contextId)
{
return Ctx.PermissionsTypes.Where(x => x.ContextId == contextId).ToListAsync();
}
public Task<int> GetPermissionFromPermissionType(PermissionsType pType)
{
if(Ctx.PermissionsTypes.FirstOrDefault(x=>x.Id == pType.Id) != null)
{
return Task.FromResult(pType.PermissionBit);
}
else
{
return Task.FromResult(0);
}
}
#endregion
#region PermissionMappings
//2. get the contexts where the user has permission
public async Task<List<AssignedPermissionModel>> GetPermissionContextByUserIdAsync(Guid UserId)
{
List<AssignedPermissionModel> _permissions = new List<AssignedPermissionModel>();
//get all assignedUsers
List<AssignedUser> assignedUsers = await Ctx.AssignedUsers.Where(x => x.EmployeeUserId == UserId).ToListAsync();
//List<PermissionContextMapping> _permissionContextMappings = new List<PermissionContextMapping>();
List<PermissionGroupUserMapping> _permissionGroupUserMappings = new List<PermissionGroupUserMapping>();
//get contexts where the user has permission
foreach (var item in assignedUsers)
{
//get the product where the permissioncontextmapping is
var contextMapping = await Ctx.PermissionContextMappings.FirstOrDefaultAsync(x => x.SubjectId == item.Id);
if (contextMapping != null)
{
_permissions.Add(new AssignedPermissionModel(item.ContextId, item.Id, (short)PermissionContextMappingSubjectType.User, item.Id.ToString(), contextMapping.Permissions));
}
//get permissiongroupusermappings where the user is in the group
_permissionGroupUserMappings = await Ctx.PermissionGroupUserMappings.Where(x => x.AssignedUserId == item.Id).ToListAsync();
foreach (var groupUserMapping in _permissionGroupUserMappings)
{
//get the permissioncontextmapping where the permissiongroup is
var contextMapping2 = await Ctx.PermissionContextMappings.FirstOrDefaultAsync(x => x.Id == groupUserMapping.PermissionContextMappingId);
if (contextMapping2 != null)
{
//get the group so we have the contextId
var group = await Ctx.PermissionGroups.FirstOrDefaultAsync(x => x.Id == contextMapping2.SubjectId);
_permissions.Add(new AssignedPermissionModel(group.ContextId, contextMapping2.SubjectId, (short)PermissionContextMappingSubjectType.Group, group.GroupName, contextMapping2.Permissions));
}
}
}
return _permissions;
}
//3. (IPermissionService) get permissions of assigned users and groups
public Task<List<AssignedPermissionModel>> GetPermissionsOfAssignedUsersAndGroupsAsyncByContextId(Guid contextId)
{
List<AssignedPermissionModel> result = new List<AssignedPermissionModel>();
var AssignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == contextId).ToListAsync();
if (AssignedUsers.Result != null)
{
foreach (var item in AssignedUsers.Result)
{
var mappingRow = Ctx.PermissionContextMappings.Where(x => x.SubjectId == item.Id).ToListAsync();
if (mappingRow.Result == null)
{
//user has no permission but is assigned... must be banned
}
else if (mappingRow.Result.Count > 1)
{
//user has been assigned more than onece to same context
}
else
{
foreach (var mapping in mappingRow.Result)
{
result.Add(new AssignedPermissionModel(item.ContextId, item.Id, mapping.SubjectType, item.EmployeeUserId.ToString(), mapping.Permissions));
}
}
}
}
var AssingedGroups = Ctx.PermissionGroups.Where(x => x.ContextId == contextId).ToListAsync();
if (AssingedGroups.Result != null)
{
foreach (var group in AssingedGroups.Result)
{
var mappingRow = Ctx.PermissionContextMappings.Where(x => x.SubjectId == group.Id).ToListAsync();
if (mappingRow.Result == null)
{
//group has no permission but is assigned...
}
else if (mappingRow.Result.Count > 1)
{
//group has been assigned more than onece to same context
}
else
{
foreach (var mapping in mappingRow.Result)
{
result.Add(new AssignedPermissionModel(group.ContextId, group.Id, mapping.SubjectType, group.GroupName, mapping.Permissions));
}
}
}
}
foreach (var row in result)
{
Console.WriteLine($"GetPermissionsOfAssignedUsersAndGroupsAsyncByContextId: {row.ContextId}, {row.SubjectId}, {row.SubjectType}, {row.Name}, {row.PermissionsValue}");
}
return Task.FromResult(result);
}
//12. (IPermissionService) get permission groups for context
public Task<List<PermissionContextMapping>> GetPermissionsForContextByContextIdAsync(Guid contextId)
{
List<PermissionContextMapping> permissionContextMappings = new List<PermissionContextMapping>();
//get all Groups where the contextId is the same
var groups = Ctx.PermissionGroups.Where(x => x.ContextId == contextId).ToListAsync();
foreach (var item in groups.Result)
{
//get permissioncontextmapping for the group if there is, so we know what permissions the group has
var pCm = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == item.Id);
permissionContextMappings.Add(pCm);
}
return Task.FromResult(permissionContextMappings);
}
//9. (IPermissionService) add user to permission group
public Task<bool> AddUserToPermissionGroupAsync(Guid permissionGroupId, Guid userId)
{
bool result = false;
using (var transaction = Ctx.Database.BeginTransaction())
{
//do we need to check if PermissionContextMappingId exists?
var permissionGroupUserMapping = new PermissionGroupUserMapping(userId, permissionGroupId);
Ctx.PermissionGroupUserMappings.Add(permissionGroupUserMapping);
Ctx.SaveChanges();
transaction.Commit();
result = true;
}
return Task.FromResult(result);
}
//8. (IPermissionService) create permission group
public Task<bool> CreatePermissionGroupAsync(PermissionGroup permissionGroup, TiamServiceProvider serviceProvider)
{
bool result = false;
using (var transaction = Ctx.Database.BeginTransaction())
{
var existingPermissionGroup = Ctx.PermissionGroups.FirstOrDefault(x => x.GroupName == permissionGroup.GroupName)?.GroupName;
if (existingPermissionGroup == null)
{
//create permission type 1 for the group
var permissionType = new PermissionsType(serviceProvider.Id, "View");
Ctx.PermissionsTypes.Add(permissionType);
//Create PermissionContextMapping for the group
//create Id for the group
Guid Id = Guid.NewGuid();
permissionGroup.Id = Id;
var permissionContextMapping = new PermissionContextMapping(serviceProvider.Id, Id, (short)PermissionContextMappingSubjectType.Group, 1, true);
Ctx.PermissionContextMappings.Add(permissionContextMapping);
Ctx.PermissionGroups.Add(permissionGroup);
Ctx.SaveChanges();
transaction.Commit();
result = true;
}
else
{
//group with same name already exists
result = false;
}
}
return Task.FromResult(result);
}
public Task<List<AssignedUser>> GetAssingedUsersInPermissionGroupByGroupId(Guid groupId)
{
List<AssignedUser> assignedUsers = new List<AssignedUser>();
//let's get the permissioncontextmapping for the group
var pCm = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == groupId);
Guid pCmId = pCm.Id;
//let's get the permissiongroupusermappings for the permissioncontextmapping
var pGum = Ctx.PermissionGroupUserMappings.Where(x => x.PermissionContextMappingId == pCmId).ToList();
if (pGum.Count > 0)
{
foreach (var group in pGum)
{
assignedUsers.Add(Ctx.AssignedUsers.FirstOrDefault(x => x.Id == group.AssignedUserId));
}
}
return Task.FromResult(assignedUsers);
}
#endregion
#region Products
//19. (IServiceProviderDataService) Create product
public Task<bool> CreateProductAsync(TiamProduct product)
{
Ctx.Products.Add(product);
Console.WriteLine($"Saving product to db {product.Id}, {product.Name}, {product.OwnerId}");
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
//20. (IServiceProviderDataService) Update product
public Task<bool> UpdateProductAsync(TiamProduct product)
{
var dbProduct = Ctx.Products.FirstOrDefault(u => u.Id == product.Id);
if (dbProduct != null)
{
dbProduct = product;
Ctx.Products.Update(dbProduct);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
throw new Exception("Product not found");
}
}
//21. (IServiceProviderDataService) delete product
public Task<bool> DeleteProductAsync(Guid id)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var dbProduct = Ctx.Products.FirstOrDefault(u => u.Id == id);
if (dbProduct != null)
{
//get assignedUsers for this product
var assignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == id).ToList();
//remove assignedUsers
foreach (var item in assignedUsers)
{
RemoveAssignedUserByUserId(item.Id);
}
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
return Task.FromResult(false);
}
}
}
//4. (IPermissionService) AssignPermissionToUserForContextAsync
public Task<bool> AssignPermissionToUserForContextAsync(AssignedUser assignedUser, PermissionsType permission)
{
var _assIgnedUser = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUser.Id);
if(_assIgnedUser != null)
{
//user exists
var _permissionInt = GetPermissionFromPermissionType(permission);
var permissionContextMapping = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == assignedUser.Id);
var currentPermissions = permissionContextMapping.Permissions;
var newPermissions = currentPermissions + _permissionInt.Result;
permissionContextMapping.Permissions = newPermissions;
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
else
{
//user does not exist, let's create it
return Task.FromResult(false);
}
}
#endregion
#region AssignedUsers
//22. (IServiceProviderDataService) Create assignedUser
public Task<AssignedUser> CreateAssignedUserAsync(AssignedUser assignedUser)
{
Ctx.AssignedUsers.Add(assignedUser);
Console.WriteLine($"Saving assignedUser to db {assignedUser.Id}, {assignedUser.ContextId}, {assignedUser.EmployeeUserId}, {assignedUser.UserRoles}");
return Ctx.SaveChangesAsync().ContinueWith(x => assignedUser);
}
//23. (IServiceProviderDataService) Get Assigned Users By ProductId
public Task<List<AssignedUser>> GetAssignedUsersByProductIdAsync(Guid productId)
{
return Ctx.AssignedUsers.Where(x => x.ContextId == productId).ToListAsync();
}
//24 . (IServiceProviderDataService) Remove Assigned Users By Product Id
public Task RemoveAssignedUsersByContextId(Guid contextId)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var assignedUsers = Ctx.AssignedUsers.Where(x => x.ContextId == contextId).ToList();
//remove assignedUsers
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
}
//25. (IServiceProviderDataService) Remove Assigned from product by AssignedUserId
public Task RemoveAssignedUser(AssignedUser assignedUser, bool removeFromGroups)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var assignedUserToRemove = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUser.Id);
//remove assignedUsers
if (assignedUserToRemove != null)
{
if(removeFromGroups)
{
//remove permissiongroupusermappings
RemoveAssingedUserFromAllProductPermissionGroups(assignedUserToRemove.Id);
}
Ctx.AssignedUsers.Remove(assignedUserToRemove);
}
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
}
public Task RemoveAssignedUserByUserId(Guid assignedUserId)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var assignedUser = Ctx.AssignedUsers.FirstOrDefault(x => x.Id == assignedUserId);
//remove assignedUsers
if (assignedUser != null)
{
//CleanUp
//remove permissioncontextmappings
RemoveAssignedUserContextMappingByAssignedUserId(assignedUserId);
//remove permissiongroupusermappings
RemoveAssingedUserFromAllProductPermissionGroups(assignedUserId);
}
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
}
public Task RemoveAssignedUserContextMappingByAssignedUserId(Guid AssignedUserId)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
PermissionContextMapping? contextMapping = Ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == AssignedUserId);
//remove assignedUsers
if(contextMapping != null)
{
Ctx.PermissionContextMappings.Remove(contextMapping);
}
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
}
public Task RemoveAssingedUserFromAllProductPermissionGroups(Guid assignedUserId)
{
using (var transaction = Ctx.Database.BeginTransaction())
{
var permissionGroupUserMapping = Ctx.PermissionGroupUserMappings.Where(x => x.AssignedUserId == assignedUserId);
//remove assignedUsers
if (permissionGroupUserMapping != null)
{
foreach (var item in permissionGroupUserMapping)
{
Ctx.PermissionGroupUserMappings.Remove(item);
}
}
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
}
#endregion
}
}

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.Identity.Client;
using TIAM.Database.DbContexts;
using TIAM.Entities.TransferDestinations;
@ -19,9 +20,23 @@ public class TransferDestinationDal : TiamDalBase<TransferDestinationDbContext>
public Task<bool> CreateTransferDestinationAsync(TransferDestination transferDestination)
{
transferDestination.Created = DateTime.UtcNow;
transferDestination.Modified = DateTime.UtcNow;
//transferDestination.Created = DateTime.UtcNow;
//transferDestination.Modified = DateTime.UtcNow;
Ctx.TransferDestinations.Add(transferDestination);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
public Task<bool> UpdateTransferDestinationAsync(TransferDestination transferDestination)
{
//transferDestination.Modified = DateTime.UtcNow;
Ctx.TransferDestinations.Update(transferDestination);
return Ctx.SaveChangesAsync().ContinueWith(x => x.Result > 0);
}
public Task<List<TransferDestination>> GetTransferDestinations()
{
return Ctx.TransferDestinations.ToListAsync();
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Database.DbContexts;
using Microsoft.EntityFrameworkCore;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
namespace TIAM.Database.DbContexts
{
public class ServiceProviderDbContext : TiamDbContextBase
{
public virtual DbSet<TiamServiceProvider> ServiceProviders { get; set; }
public virtual DbSet<TiamProduct> Products { get; set; }
public virtual DbSet<AssignedUser> AssignedUsers { get; set; }
public virtual DbSet<PermissionsType> PermissionsTypes { get; set; }
public virtual DbSet<PermissionGroup> PermissionGroups { get; set; }
public virtual DbSet<PermissionGroupUserMapping> PermissionGroupUserMappings { get; set; }
public virtual DbSet<PermissionContextMapping> PermissionContextMappings { get; set; }
public ServiceProviderDbContext() //: this(string.Empty)
{
}
public ServiceProviderDbContext(DbContextOptions<ServiceProviderDbContext> options) //: this(string.Empty)
{
}
public ServiceProviderDbContext(string name) : base(name)
{
}
public ServiceProviderDbContext(DbContextOptions<DbContext> options, string name) : base(options, name)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableDetailedErrors(true);
base.OnConfiguring(optionsBuilder);
}
}
}

View File

@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using AyCode.Database.DbContexts;
using Microsoft.EntityFrameworkCore;
using TIAM.Entities.TransferDestinations;
using TIAM.Entities.Permissions;
using TIAM.Entities.Users;
namespace TIAM.Database.DbContexts

View File

@ -13,6 +13,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="DataLayers\DTOs\" />
<Folder Include="Extensions\" />
</ItemGroup>

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Entities.Groups;
namespace TIAM.Entities.Groups
{
public class Group : GroupBase
{
public Group() { }
public Group(bool isPublic) : this(Guid.NewGuid(), isPublic) { }
public Group(Guid id, bool isPublic) : base(id, isPublic)
{ }
}
}

View File

@ -10,13 +10,22 @@ public class PermissionContextMapping : IEntityGuid, ITimeStampInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public Guid ContextId { get; set; }
public Guid SubjectId { get; set; }
public Guid SubjectId { get; set; } //group or user
public short SubjectType { get; set; }
public short SubjectType { get; set; } //1 for user, 2 for group
public int Permissions { get; set; }
public bool IsBuiltin { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public PermissionContextMapping(Guid subjectId, short subjectType, int permissions, bool isBuiltin) : this(Guid.NewGuid(), subjectId, subjectType, permissions, isBuiltin) { }
public PermissionContextMapping(Guid id, Guid subjectId, short subjectType, int permissions, bool isBuiltin)
{
Id = id;
SubjectId = subjectId;
SubjectType = subjectType;
Permissions = permissions;
IsBuiltin = isBuiltin;
}
}

View File

@ -1,19 +1,30 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using AyCode.Entities.Groups;
using AyCode.Interfaces.Entities;
using AyCode.Interfaces.TimeStampInfo;
using TIAM.Entities.Groups;
namespace TIAM.Entities.Permissions;
[Table("PermissionGroups")]
public class PermissionGroup : IEntityGuid, ITimeStampInfo
public class PermissionGroup : GroupBase
{
public PermissionGroup() { }
public PermissionGroup( Guid contextId, bool isPublic, string groupName, bool isBuiltin) : this(Guid.NewGuid(), contextId, isPublic, groupName, isBuiltin) { }
public PermissionGroup(Guid id, Guid contextId, bool isPublic, string groupName, bool isBuiltin) : base(id, isPublic)
{
Id = id;
ContextId = contextId;
IsPublic = isPublic;
GroupName = groupName;
IsBuiltin = isBuiltin;
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
string GroupName { get; set; }
bool IsBuiltin { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public Guid ContextId { get; set; }
public bool IsPublic { get; set; }
public string? GroupName { get; set; }
public bool IsBuiltin { get; set; }
}

View File

@ -10,9 +10,20 @@ public class PermissionGroupUserMapping : IEntityGuid, ITimeStampInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public Guid UserId { get; set; }
public Guid AssignedUserId { get; set; }
public Guid PermissionContextMappingId { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public PermissionGroupUserMapping(Guid assignedUserId, Guid permissionContectMappingId) : this (Guid.NewGuid(), assignedUserId, permissionContectMappingId)
{ }
public PermissionGroupUserMapping(Guid id, Guid assignedUserId, Guid permissionContectMappingId)
{
Id = id;
AssignedUserId = assignedUserId;
PermissionContextMappingId = permissionContectMappingId;
}
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using AyCode.Interfaces.Entities;
using AyCode.Interfaces.TimeStampInfo;
namespace TIAM.Entities.Permissions;
//[Table("PermissionGroups")]
public class PermissionGroup_Old : IEntityGuid, ITimeStampInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public Guid ContextId { get; set; } //Kell egy ownerID (ami itt contextId), mert különben létrehozás után nem tudjuk kié a csoport
string? GroupName { get; set; }
bool IsBuiltin { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}

View File

@ -18,4 +18,12 @@ public class PermissionsType : IEntityGuid, ITimeStampInfo
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public PermissionsType(Guid contextId, string permissionName) : this(Guid.NewGuid(), contextId, permissionName) { }
public PermissionsType(Guid id, Guid contextId, string permissionName)
{
Id = Guid.NewGuid();
ContextId = contextId;
PermissionName = permissionName;
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace TIAM.Entities.Products.DTOs
{
public class AssignedPermissionModel
{
public Guid ContextId { get; set; }
public Guid SubjectId { get; set; } //user or group id
public short SubjectType { get; set; } //user or group
public string Name { get; set; } //user email or group name
public int PermissionsValue { get; set; }
public AssignedPermissionModel(Guid contextId, Guid subjectId, short subjectType, string name, int permissionsValue)
{
ContextId = contextId;
SubjectId = subjectId;
SubjectType = subjectType;
Name = name;
PermissionsValue = permissionsValue;
}
}
}

View File

@ -6,7 +6,7 @@ using TIAM.Core;
namespace TIAM.Entities.Products;
[Table("Product")]
public class Product : IEntityGuid, ITimeStampInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
@ -22,4 +22,17 @@ public class Product : IEntityGuid, ITimeStampInfo
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public Product(Guid id, ProductType type, Guid userMediaId, string name, string description, float price, string jsonDetails)
{
Id = id;
ProductType = type;
UsermediaId = userMediaId;
Name = name;
Description = description;
Price = price;
JsonDetails = jsonDetails;
Created = DateTime.Now;
Modified = DateTime.Now;
}
}

View File

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using AyCode.Interfaces.Entities;
using AyCode.Interfaces.TimeStampInfo;
using TIAM.Core;
namespace TIAM.Entities.Products;
[Table("Products")]
public class TiamProduct : Product
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid OwnerId { get; set; }
public TiamProduct(Guid ownerId, ProductType type, Guid userMediaId, string name, string description, float price, string jsonDetails) : this(Guid.NewGuid(), ownerId, type, userMediaId, name, description, price, jsonDetails) { }
public TiamProduct(Guid id, Guid ownerId, ProductType type, Guid userMediaId, string name, string description, float price, string jsonDetails) : base(id, type, userMediaId, name, description, price, jsonDetails)
{
OwnerId = ownerId;
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Entities.ServiceProviders;
namespace TIAM.Entities.ServiceProviders
{
public class TiamServiceProvider : ServiceProviderBase
{
public TiamServiceProvider() { }
public TiamServiceProvider(string name, Guid ownerId) : this(Guid.NewGuid(), name, ownerId) { }
public TiamServiceProvider(Guid id, string name, Guid ownerId) : base(id, name, ownerId)
{
}
}
}

View File

@ -10,11 +10,24 @@ public class AssignedUser : IEntityGuid, ITimeStampInfo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public Guid ProductId { get; set; }
public Guid ContextId { get; set; }
public Guid EmployeeUserId { get; set; }
public int UserRoles { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public AssignedUser(Guid contextId, Guid employeeUserId, int userRoles) : this(Guid.NewGuid(), contextId, employeeUserId, userRoles)
{
}
public AssignedUser(Guid id, Guid contextId, Guid employeeUserId, int userRoles)
{
Id = id;
ContextId = contextId;
EmployeeUserId = employeeUserId;
UserRoles = userRoles;
}
}

View File

@ -3,7 +3,7 @@ using TIAMMobileApp.Services;
using TIAMWebApp.Shared.Application.Interfaces;
using DevExpress.Blazor;
using TIAMMobilApp.Services;
using TIAMWebApp.Shared.Application.Utility;
using System.Resources;
using AyCode.Interfaces.StorageHandlers;
namespace TIAMMobileApp
@ -26,6 +26,7 @@ namespace TIAMMobileApp
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
builder.Logging.AddDebug();
builder.Services.AddLocalization();
#endif
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => true;
@ -48,7 +49,8 @@ namespace TIAMMobileApp
builder.Services.AddScoped<IUserDataService, UserDataServiceMobile>();
builder.Services.AddScoped<ISecureStorageHandler, SecureStorageHandler>();
builder.Services.AddScoped<ISessionService, SessionServiceMobile>();
builder.Services.AddSingleton<IComponentUpdateService, ComponentUpdateServiceMobile>();
builder.Services.AddSingleton(x => new ResourceManager("TIAMWebApp.Shared.Application.Resources", typeof(Main).Assembly));
return builder.Build();
}
}

View File

@ -0,0 +1,13 @@
using TIAMWebApp.Shared.Application.Interfaces;
namespace TIAMMobileApp.Services
{
public class ComponentUpdateServiceMobile : IComponentUpdateService
{
public event Action RefreshRequested;
public void CallRequestRefresh()
{
RefreshRequested?.Invoke();
}
}
}

View File

@ -9,5 +9,6 @@ namespace TIAMMobileApp.Services
public string? SessionId { get; set; }
public UserSessionModel? User { get; set; }
public IPAddress? IPAddress { get; set; }
public bool IsAuthenticated { get; set; }
}
}

View File

@ -6,3 +6,4 @@
@using Microsoft.JSInterop
@using TIAMMobileApp
@using TIAMMobileApp.Services
@using AyCode.Interfaces.StorageHandlers;

View File

@ -0,0 +1,130 @@
@page "/";
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models
@using TIAMWebApp.Shared.Application.Utility
@using Newtonsoft.Json
@using System.IdentityModel.Tokens.Jwt
@using TIAMWebApp.Shared.Application.Models.ClientSide
@using AyCode.Interfaces.StorageHandlers;
@using System.Globalization;
@inject NavigationManager NavManager
@inject IJSRuntime JSRuntime
@inject LogToBrowserConsole logToBrowserConsole
@inject IUserDataService UserDataService
@inject ISecureStorageHandler SecureStorageHandler
@inject ISessionService sessionService;
@inject HttpClient http;
<h3>AppLaunch</h3>
Loading....
@code {
string userDetailsStr;
string locale;
protected async override Task OnInitializedAsync()
{
var (_userDetailStr, _locale) = await GetLocalSettings();
userDetailsStr = _userDetailStr;
if(_locale != null)
{
locale = _locale;
Culture = new CultureInfo(locale);
logToBrowserConsole.LogToBC("Locale from settings: " + locale);
}
else
{
logToBrowserConsole.LogToBC("Default locale:" + Culture.Name);
}
logToBrowserConsole = new LogToBrowserConsole(JSRuntime);
//wait for 5 seconds
await Task.Delay(1000);
if (!string.IsNullOrWhiteSpace(userDetailsStr))
{
logToBrowserConsole.LogToBC(userDetailsStr);
var userBasicDetail = JsonConvert.DeserializeObject<UserBasicDetails>(userDetailsStr);
var handler = new JwtSecurityTokenHandler();
var jsontoken = handler.ReadToken(userBasicDetail?.AccessToken) as JwtSecurityToken;
if(userBasicDetail!= null)
Setting.UserBasicDetails = userBasicDetail;
if (jsontoken?.ValidTo < DateTime.UtcNow)
{
logToBrowserConsole.LogToBC("Token needs to be refreshed");
bool isTokenRefreshed = await UserDataService.RefreshToken();
if (isTokenRefreshed)
{
logToBrowserConsole.LogToBC("Token refreshed");
}
else
{
logToBrowserConsole.LogToBC("Couldn't refresh token");
SignOut();
NavManager.NavigateTo("/index");
return;
}
}
else
{
logToBrowserConsole.LogToBC("Valid token found");
}
string _userId = jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value;
string _email = jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
var user = await UserDataService.IsLoggedInAsync(Guid.Parse(_userId));
sessionService.User = user;
logToBrowserConsole.LogToBC($"Saved user in db is: {user.Email}, setting autenthicated state");
sessionService.IsAuthenticated = true;
NavManager.NavigateTo("/index");
}
else
{
logToBrowserConsole.LogToBC("No token stored yet");
NavManager.NavigateTo("/index");
}
}
public async Task<(string, string)> GetLocalSettings()
{
string userDetailsStr = await SecureStorageHandler.GetFromSecureStorageAsync(nameof(Setting.UserBasicDetails));
string locale = await SecureStorageHandler.GetFromSecureStorageAsync(nameof(Setting.Locale));
return (userDetailsStr, locale);
}
private void SignOut()
{
SecureStorageHandler.ClearAllSecureStorageAsync();
sessionService.User = null;
sessionService.IsAuthenticated = false;
}
CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
Thread.CurrentThread.CurrentCulture = value;
Thread.CurrentThread.CurrentUICulture = value;
CultureInfo.DefaultThreadCurrentCulture = value;
CultureInfo.DefaultThreadCurrentUICulture = value;
}
}
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using AyCode.Blazor.Components;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -4,7 +4,7 @@
<TopRow></TopRow>
<HeroSlider></HeroSlider>
<div class="container-fluid">
<div class="container">
<section>
<div class="text-center">

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;

using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,7 +8,7 @@ using System.Threading.Tasks;
namespace TIAMSharedUI.Pages.Components
{
public partial class AuctionComponent
public partial class AuctionComponent : ComponentBase
{
[Parameter]
public Guid UserId { get; set; }

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using AyCode.Blazor.Components;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,7 +9,7 @@ using TIAMWebApp.Shared.Application.Models;
namespace TIAMSharedUI.Pages.Components
{
public partial class AuctionItemComponent
public partial class AuctionItemComponent : ComponentBase
{
[Parameter]
public int AuctionItemId { get; set; }

View File

@ -0,0 +1,9 @@

<div style="position:fixed; background-color:black; color: white; bottom: 0px; width: 100%;">
<p>AuthComponent: </p><p>Logged in: @IsLoggedIn</p>
</div>
@code {
}

View File

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAMWebApp.Shared.Application.Interfaces;
namespace TIAMSharedUI.Pages.Components
{
public partial class AuthComponent : ComponentBase
{
[Inject]
public ISessionService sessionService { get; set; }
public bool IsLoggedIn = false;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
IsLoggedIn = sessionService.IsAuthenticated;
StateHasChanged();
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
}
}
}

View File

@ -0,0 +1,31 @@
@using System.Linq.Expressions
@using System.ComponentModel.DataAnnotations
<h2>Edit Form</h2>
<div class="wrapper">
<div class="card cw-480">
<EditForm Model="@Data"
OnValidSubmit="@HandleValidSubmit"
OnInvalidSubmit="@HandleInvalidSubmit"
Context="EditFormContext">
<DataAnnotationsValidator />
<div class="card-header text-center py-3">
<h4>Register with DevExpress</h4>
<p class="tm-8 mb-0 fw-normal fs-825">
Create a new account to see it in action
</p>
</div>
<div class="card-body">
@CreateEditFormFields()
</div>
</EditForm>
</div>
</div>
<p class="tm-8 cw-480 mt-2">
@FormSubmitResult
</p>
@code {
}

View File

@ -0,0 +1,149 @@
using AyCode.Entities.Users;
using DevExpress.Blazor;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using TIAM.Entities.TransferDestinations;
namespace TIAMSharedUI.Pages.Components
{
public partial class InputWizard : ComponentBase
{
string FormSubmitResult = "";
//TestUserData Data { get; set; } = new TestUserData();
TransferDestination Data { get; set; } = new TransferDestination();
string PhoneMask { get; set; } = "(999)000-0000";
void HandleValidSubmit()
{
FormSubmitResult = "You have been registred successully.";
}
void HandleInvalidSubmit()
{
FormSubmitResult = "Please correct all errors";
}
public RenderFragment CreateEditFormFields() => formLayoutBuilder =>
{
var propertyList = typeof(TransferDestination).GetProperties();
formLayoutBuilder.OpenComponent<DxFormLayout>(0);
formLayoutBuilder.AddAttribute(1, "ChildContent", (RenderFragment)((layoutItemBuilder) =>
{
int i = 0;
foreach (var property in propertyList)
{
var attrList = (DataTypeAttribute)property.GetCustomAttributes(typeof(DataTypeAttribute), false).First();
DisplayAttribute displayLabel = (DisplayAttribute)property.GetCustomAttributes(typeof(DisplayAttribute), false).First();
layoutItemBuilder.OpenComponent<DxFormLayoutItem>(i++);
layoutItemBuilder.AddAttribute(i++, "Caption", displayLabel.Name);
layoutItemBuilder.AddAttribute(i++, "ColSpanMd", 12);
//layoutItemBuilder.AddAttribute(i++, "CssClass", "form-field");
var access = Expression.Property(Expression.Constant(Data), property.Name);
var lambda = Expression.Lambda(typeof(Func<>).MakeGenericType(property.PropertyType), access);
layoutItemBuilder.AddAttribute(i++, "Template", (RenderFragment<Object>)((context) => ((editor) =>
{
var j = 0;
switch (attrList.DataType)
{
case DataType.Text:
{
editor.OpenComponent<DxTextBox>(j++);
editor.AddAttribute(j++, "Text", property.GetValue(Data));
editor.AddAttribute(j++, "TextExpression", lambda);
editor.AddAttribute(j++, "CssClass", "form-field");
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<System.String>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
case DataType.Password:
{
editor.OpenComponent<DxTextBox>(j++);
editor.AddAttribute(j++, "Password", true);
editor.AddAttribute(j++, "NullText", "Password");
editor.AddAttribute(j++, "Text", property.GetValue(Data));
editor.AddAttribute(j++, "TextExpression", lambda);
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<System.String>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
case DataType.PhoneNumber:
{
editor.OpenComponent<DxMaskedInput<String>>(j++);
editor.AddAttribute(j++, "Value", property.GetValue(Data));
editor.AddAttribute(j++, "Mask", PhoneMask);
editor.AddAttribute(j++, "ValueExpression", lambda);
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<System.String>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
case DataType.Date:
{
editor.OpenComponent<DxDateEdit<DateTime>>(j);
editor.AddAttribute(j++, "Date", property.GetValue(Data));
editor.AddAttribute(j++, "DateExpression", lambda);
editor.AddAttribute(j++, "DateChanged", EventCallback.Factory.Create<System.DateTime>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
case DataType.Custom:
{
editor.OpenComponent<DxComboBox<String, String>>(j);
editor.AddAttribute(j++, "Data", AdditionalData.Occupations);
editor.AddAttribute(j++, "Value", property.GetValue(Data));
editor.AddAttribute(j++, "ValueExpression", lambda);
editor.AddAttribute(j++, "ValueChanged", EventCallback.Factory.Create<System.String>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
case DataType.MultilineText:
{
editor.OpenComponent<DxMemo>(j);
editor.AddAttribute(j++, "Text", property.GetValue(Data));
editor.AddAttribute(j++, "TextExpression", lambda);
editor.AddAttribute(j++, "TextChanged", EventCallback.Factory.Create<System.String>(this, str => { property.SetValue(Data, str); }));
editor.CloseComponent();
break;
}
default:
break;
}
})));
layoutItemBuilder.CloseComponent();
layoutItemBuilder.OpenElement(i++, "div");
layoutItemBuilder.AddAttribute(i++, "class", "text-danger");
layoutItemBuilder.OpenComponent(i++, typeof(ValidationMessage<>).MakeGenericType(property.PropertyType));
layoutItemBuilder.AddAttribute(i++, "For", lambda);
layoutItemBuilder.CloseComponent();
layoutItemBuilder.CloseElement();
}
layoutItemBuilder.OpenComponent<DxFormLayoutItem>(i++);
layoutItemBuilder.AddAttribute(i++, "Template", (RenderFragment<Object>)((context) => ((editor) =>
{
editor.OpenComponent<DxButton>(i++);
editor.AddAttribute(i++, "SubmitFormOnClick", true);
editor.AddAttribute(i++, "Text", "Register");
editor.CloseComponent();
})));
layoutItemBuilder.CloseComponent();
}));
formLayoutBuilder.CloseComponent();
};
}
}

View File

@ -0,0 +1,20 @@
@using System.Globalization
<h3>SettingsBasic</h3>
<div class="col-12 col-sm-6">
<p>@localizer["Settings.Language"] : @Culture.DisplayName</p>
<div class="form-field d-flex align-items-center">
<DxComboBox Data="@Data"
TextFieldName="@nameof(Culture.DisplayName)"
@bind-Value="@Culture"
CssClass="cw-320"/>
</div>
</div>
<div class="col-12 col-sm-6"></div>
@code {
}

View File

@ -0,0 +1,107 @@
using AyCode.Blazor.Components;
using AyCode.Interfaces.StorageHandlers;
using DevExpress.XtraPrinting.Native;
using Microsoft.AspNetCore.Components;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAMSharedUI.Resources;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Models.ClientSide;
using TIAMWebApp.Shared.Application.Utility;
namespace TIAMSharedUI.Pages.Components
{
public partial class SettingsBasic : ComponentBase
{
[Inject]
public ISecureStorageHandler? secureStorageHandler { get; set; }
[Inject]
public IStringLocalizer<MyResources>? localizer { get; set; }
[Inject]
public NavigationManager navigationManager { get; set; }
[Inject]
public LogToBrowserConsole logToBrowserConsole { get; set; }
[Inject]
public IComponentUpdateService componentUpdateService { get; set; }
public CultureInfo SelectedCulture { get; set; }
IEnumerable<CultureInfo> Data { get; set; }
[Parameter]
public EventCallback<AuctionBidModel> LanguageChanged { get; set; }
private Task<string>? GetCurrentSettings()
{
return secureStorageHandler?.GetFromSecureStorageAsync("Locale");
}
private void SaveSettings()
{
secureStorageHandler?.SaveToSecureStorageAsync(nameof(Setting.Locale), SelectedCulture.Name);
componentUpdateService.CallRequestRefresh();
}
protected override async Task OnInitializedAsync()
{
Data = culture.ToList();
string? current = await GetCurrentSettings();
if (!string.IsNullOrEmpty(current))
{
logToBrowserConsole.LogToBC(current);
//SelectedCulture = culture.FirstOrDefault(x => x.Name == Setting.Locale);
foreach (var item in culture)
{
logToBrowserConsole.LogToBC(item.Name);
if (item.Name == current)
{
SelectedCulture = item;
break;
}
}
logToBrowserConsole.LogToBC("Selected: " + SelectedCulture.Name);
}
else
{
SelectedCulture = culture[0];
}
}
CultureInfo[] culture = new[]
{
new CultureInfo("en-US"),
new CultureInfo("hu-HU")
};
CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
Thread.CurrentThread.CurrentCulture = value;
Thread.CurrentThread.CurrentUICulture = value;
CultureInfo.DefaultThreadCurrentCulture = value;
CultureInfo.DefaultThreadCurrentUICulture = value;
SelectedCulture = value;
SaveSettings();
}
}
}
}
}

View File

@ -0,0 +1,11 @@
<h3>Member settings</h3>
<div class="col-12 col-sm-6">
</div>
<div class="col-12 col-sm-6"></div>
@code {
}

View File

@ -0,0 +1,9 @@

using Microsoft.AspNetCore.Components;
namespace TIAMSharedUI.Pages.Components
{
public partial class SettingsMember : ComponentBase
{
}
}

View File

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace TIAMSharedUI.Pages.Components
{
public class TestUserData
{
[Required(ErrorMessage = "The Username value should be specified.")]
[DataType(DataType.Text)]
[Display(Name = "User Name")]
public string Username { get; set; }
[Required(ErrorMessage = "The Password value should be specified.")]
[MinPasswordLength(6, "The Password must be at least 6 characters long.")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required(ErrorMessage = "The Email value should be specified.")]
[Email(ErrorMessage = "The Email value is invalid.")]
[DataType(DataType.Text)]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required(ErrorMessage = "The Phone value should be specified.")]
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone Number")]
public string Phone { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Birth Date")]
public DateTime BirthDate { get; set; } = new DateTime(1970, 1, 1);
[DataType("ComboBox")]
[Display(Name = "Occupation")]
public string Occupation { get; set; }
[DataType(DataType.MultilineText)]
[Display(Name = "Notes")]
public string Notes { get; set; }
}
public class AdditionalData
{
public static IEnumerable<string> Occupations { get; set; } = new List<string>() {
"Academic",
"Administrative",
"Art/Entertainment",
"College Student",
"Community & Social",
"Computers",
"Education",
"Engineering",
"Financial Services",
"Government",
"High School Student",
"Law",
"Managerial",
"Manufacturing",
"Medical/Health",
"Military",
"Non-government Organization",
"Other Services",
"Professional",
"Retail",
"Science & Research",
"Sports",
"Technical",
"University Student",
"Web Building",
};
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class MinPasswordLengthAttribute : ValidationAttribute
{
int MinLength { get; }
public MinPasswordLengthAttribute(int minLength, string errorMsg) : base(errorMsg)
{
MinLength = minLength;
}
public override bool IsValid(object value)
{
return ((string)value).Length >= MinLength;
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class EmailAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return Regex.IsMatch((string)value, @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*"
+ "@"
+ @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$");
}
}
}

View File

@ -0,0 +1,54 @@
@using TIAMWebApp.Shared.Application.Interfaces;
@using TIAMWebApp.Shared.Application.Models.PageModels;
@using TIAMWebApp.Shared.Application.Models;
@inject ISessionService sessionService;
<EditForm Model="@auctionBidModel" OnValidSubmit="GoToNextStep">
<DataAnnotationsValidator />
<h3>Step 1</h3>
<div class="form-field d-flex align-items-center">
<button class="btn btn-primary mt-3" type="submit">
<span class="@spinnerClass"></span>
Licitálok!
</button>
</div>
</EditForm>
@code {
[Parameter]
public AuctionBidModel auctionBidModel { get; set; }
[Parameter]
public int TargetProductId { get; set; }
[Parameter]
public EventCallback<string> onNext { get; set; }
[Parameter]
public EventCallback<AuctionBidModel> auctionBidModelChanged { get; set; }
public Guid UserId { get; set; }
private string spinnerClass = "";
private async Task GoToNextStep()
{
spinnerClass = "spinner-border spinner-border-sm";
await Task.Delay(500);
auctionBidModel.Id = Guid.NewGuid();
auctionBidModel.OwnerId = sessionService.User.UserId;
auctionBidModel.TargetProductId = TargetProductId;
spinnerClass = "";
await auctionBidModelChanged.InvokeAsync(auctionBidModel);
await onNext.InvokeAsync();
}
}

View File

@ -0,0 +1,73 @@
@using TIAMWebApp.Shared.Application.Models.PageModels;
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Interfaces;
@inject ISessionService sessionService;
<EditForm Model="@auctionBidModel" OnValidSubmit="GoToNextStep">
<DataAnnotationsValidator />
<h3>Step 1</h3>
<div class="form-field d-flex align-items-center">
<DxMaskedInput @bind-Value="@Email"
Id="Email"
CssClass="cw-320"
Mask="@EmailMask"
MaskMode="MaskMode.RegEx">
<DxRegExMaskProperties MaskAutoCompleteMode="@((MaskAutoCompleteMode)AutoCompleteMode)"
Placeholder="Placeholder"
PlaceholdersVisible="PlaceholderVisible" />
</DxMaskedInput>
</div>
<ValidationMessage For="@(() => auctionBidModel.Email)" />
<button class="btn btn-primary mt-3" type="submit">
<span class="@spinnerClass"></span>
Next
</button>
</EditForm>
@code {
[Parameter]
public AuctionBidModel? auctionBidModel { get; set; }
public string Email { get; set; } = "test@test.com";
[Parameter]
public EventCallback<string> onNext { get; set; }
[Parameter]
public EventCallback<AuctionBidModel> auctionBidModelChanged { get; set; }
IEnumerable<char> PredefinedPlaceholders { get; set; } = new List<char>() { '_', '#' };
string EmailMask { get; set; } = @"(\w|[.-])+@(\w|-)+\.(\w|-){2,4}";
MaskAutoCompleteMode AutoCompleteMode { get; set; } = MaskAutoCompleteMode.Strong;
char Placeholder { get; set; } = '_';
bool PlaceholderVisible { get; set; } = false;
private string spinnerClass = "";
private async Task GoToNextStep()
{
spinnerClass = "spinner-border spinner-border-sm";
await Task.Delay(500);
auctionBidModel.Email = Email;
spinnerClass = "";
await auctionBidModelChanged.InvokeAsync(auctionBidModel);
await onNext.InvokeAsync();
}
protected override async Task OnInitializedAsync()
{
Email = sessionService.User.Email;
await base.OnInitializedAsync();
}
}

View File

@ -0,0 +1,72 @@
@using System.Globalization;
@using TIAMWebApp.Shared.Application.Models.PageModels;
@using TIAMWebApp.Shared.Application.Models;
<h3>Step 3: Password</h3>
<EditForm Model="@auctionBidModel" OnValidSubmit="SubmitRegistration">
<DataAnnotationsValidator />
<div class="form-field d-flex align-items-center">
<DxMaskedInput @bind-Value="@auctionBidModel.BidAmount"
CssClass="cw-320"
Mask="@NumericMask.WholeNumber">
<DxNumericMaskProperties Culture="@CultureInfo.GetCultureInfo("en-US")" />
</DxMaskedInput>
</div>
<ValidationMessage For="@(() => auctionBidModel.BidAmount)" />
<a class="btn btn-primary mt-3" @onclick="GoToPreviousStep">Previous</a>
<button class="btn btn-primary mt-3" type="submit">
<span class="@spinnerClass"></span>
Next
</button>
</EditForm>
@code {
[Parameter]
public AuctionBidModel auctionBidModel { get; set; }
[Parameter]
public EventCallback<AuctionBidModel> AuctionBidModelChanged { get; set; }
[Parameter]
public EventCallback<string> onPrev { get; set; }
[Parameter]
public EventCallback onSubmit { get; set; }
private string spinnerClass = "";
public async Task SubmitRegistration()
{
spinnerClass = "spinner-border spinner-border-sm";
await Task.Delay(500);
spinnerClass = "";
await AuctionBidModelChanged.InvokeAsync(auctionBidModel);
await onSubmit.InvokeAsync();
}
private async Task GoToPreviousStep()
{
await onPrev.InvokeAsync();
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using AyCode.Blazor.Components;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,7 +11,7 @@ using TIAMWebApp.Shared.Application.Models;
namespace TIAMSharedUI.Pages
{
public partial class DbTestComponent: ComponentBase
public partial class DbTestComponent
{
[Parameter]
public string EmailAddress

View File

@ -1,4 +1,4 @@
@page "/"
@page "/index"
@using AyCode.Interfaces.StorageHandlers;
@using Newtonsoft.Json;
@using TIAMWebApp.Shared.Application.Interfaces
@ -7,26 +7,26 @@
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Utility;
@using System.IdentityModel.Tokens.Jwt;
@using TIAMSharedUI.Pages.Components;
@inject NavigationManager NavManager
@inject IUserDataService UserDataService;
@inject IJSRuntime jsRuntime;
@inject ISecureStorageHandler SecureStorageHandler
@inject ISessionService sessionService;
@inject IStringLocalizer<MyResources> localizer;
@using TIAMSharedUI.Shared
<PageTitle>Index</PageTitle>
<HeroSlider></HeroSlider>
<div class="container-fluid" style="align-content: center;">
<AuthComponent />
<div class="container" style="align-content: center;">
<div class="text-center">
<h1>Welcome</h1>
<h2>Please select!</h2>
<h1>@localizer.GetString("Index.Title")</h1>
<h2>@localizer.GetString("Index.Subtitle")</h2>
</div>
<div class="row">
@ -37,9 +37,9 @@
<img class="card-img" src="_content/TIAMSharedUI/images/m_transfer.jpg" alt="Card image">
<div class="card-img-overlay">
<h3 class="card-title">Transfer</h3>
<h3 class="card-title">@localizer.GetString("Index.Transfer")</h3>
<p class="card-text">Do you need a lift? Book a transfer now!</p>
<p class="card-text">@localizer.GetString("Index.Transfer.Desc")</p>
</div>
</div>
@ -49,8 +49,8 @@
<div class="card my-3 my-card text-white">
<img class="card-img" src="_content/TIAMSharedUI/images/m_tour.jpg" alt="Card image">
<div class="card-img-overlay">
<h3 class="card-title">Tours</h3>
<p class="card-text">Are you curious about the wonderful sights of Budapest or Hungary? Book a guided tour now!</p>
<h3 class="card-title">@localizer.GetString("Index.Tours")</h3>
<p class="card-text">@localizer.GetString("Index.Tours.Desc")</p>
</div>
</div>
@ -60,8 +60,8 @@
<div class="card my-3 my-card text-white">
<img class="card-img" src="_content/TIAMSharedUI/images/m_restaurant.jpg" alt="Card image">
<div class="card-img-overlay">
<h3 class="card-title">Clubcards</h3>
<p class="card-text">Join the club, and enjoy great offers during your stay!</p>
<h3 class="card-title">@localizer.GetString("Index.Clubcards")</h3>
<p class="card-text">@localizer.GetString("Index.Clubcards.Desc")</p>
</div>
</div>
@ -72,71 +72,7 @@
@code {
bool isUserLoggedIn;
int userType = 0;
int currentUserRole = 249;
public UserSessionModel MyUser;
//add a new dictionary for the role types
protected async override Task OnInitializedAsync()
{
//old
var logToBrowserConsole = new LogToBrowserConsole(jsRuntime);
//wait for 5 seconds
//await Task.Delay(5000);
string userDetailsStr = await SecureStorageHandler.GetFromSecureStorageAsync(nameof(Setting.UserBasicDetails));
logToBrowserConsole.LogToBC(userDetailsStr);
if (!string.IsNullOrWhiteSpace(userDetailsStr))
{
var userBasicDetail = JsonConvert.DeserializeObject<UserBasicDetails>(userDetailsStr);
var handler = new JwtSecurityTokenHandler();
var jsontoken = handler.ReadToken(userBasicDetail?.AccessToken) as JwtSecurityToken;
if (userBasicDetail != null)
Setting.UserBasicDetails = userBasicDetail;
if (jsontoken?.ValidTo < DateTime.UtcNow)
{
logToBrowserConsole.LogToBC("Token needs to be refreshed");
bool isTokenRefreshed = await UserDataService.RefreshToken();
if (isTokenRefreshed)
{
logToBrowserConsole.LogToBC("Token refreshed");
var myId = Guid.Parse(jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value);
//UserDataService.User.Email = jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
MyUser = await UserDataService.IsLoggedInAsync(myId);
logToBrowserConsole.LogToBC(MyUser.UserId.ToString());
}
else
{
logToBrowserConsole.LogToBC("Couldn't refresh token");
}
}
else
{
logToBrowserConsole.LogToBC("Valid token found");
var myId = Guid.Parse(jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value);
logToBrowserConsole.LogToBC(myId.ToString());
//UserDataService.User.Email = jsontoken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
MyUser = await UserDataService.IsLoggedInAsync(myId);
logToBrowserConsole.LogToBC(MyUser.UserId.ToString());
sessionService.User = MyUser;
logToBrowserConsole.LogToBC($"{sessionService.User.UserId.ToString()}, {sessionService.User.Email}.");
}
}
else
{
logToBrowserConsole.LogToBC("No token stored yet");
}
}
}

View File

@ -1,4 +1,4 @@
@page "/admin";
@page "/adminstart";
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models
@using TIAMWebApp.Shared.Application.Utility

View File

@ -1,9 +1,18 @@
@page "/login_old"
@page "/login"
@using System.IdentityModel.Tokens.Jwt;
@using System.Security.Claims;
@using Newtonsoft.Json.Linq;
@using System.Text.Json;
@using System.Reflection;
@using TIAMWebApp.Shared.Application.Interfaces;
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Models.PageModels;
@inject NavigationManager navManager
@inject IUserDataService userDataService
@using TIAMSharedUI.Pages.Components;
@using TIAMWebApp.Shared.Application.Models.ClientSide;
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Utility;
@using AyCode.Interfaces.StorageHandlers;
<PageTitle>Login</PageTitle>
<div class="wrapper">
@ -11,63 +20,46 @@
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
</div>
<div class="text-center mt-4 name">
Tour I Am
@localizer["LoginTitleText"]
</div>
<EditForm Model="@loginModel" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<!--ValidationSummary /-->
<div class="p-3 mt-3">
<div class="form-field d-flex align-items-center">
<span class="far fa-user"></span>
<input type="email" @bind-value="loginModel.Email" name="email" id="phoneNumber" placeholder="Phone number">
<ValidationMessage For="@(() => loginModel.Email)" />
</div>
<div class="form-field d-flex align-items-center">
<span class="fas fa-key"></span>
<input type="password" @bind-value="loginModel.Password" name="password" id="pwd" placeholder="Password">
<ValidationMessage For="@(() => loginModel.Password)" />
</div>
<div class="form-field d-flex align-items-center">
<form class="p-3 mt-3">
<div>
@switch (currentStep)
{
case 1:
<LoginStep1 @bind-LoginModel="loginModel" onLoginNext="GoToNextStep" />
;
break;
<select style="width:100%" @bind="CurrentValue" class="custom-select" title="Destination is required ">
<option value="0" selected disabled="disabled">(Choose account type)</option>
<option value="1" selected>Hotel</option>
<option value="2" selected>Transfer</option>
<option value="3" selected>Guide</option>
<option value="4" selected>Admin</option>
<option value="5" selected>UserModel</option>
<option value="6" selected>Driver</option>
</select>
case 2:
<LoginStep3 @bind-LoginModel="loginModel" onSubmit="SubmitLogin" onPrev="GoToPreviousStep" />
;
break;
}
</div>
<!--button class="btn btn-primary mt-3" @onclick="next">Login</button-->
<!--a class="btn btn-primary mt-3" @onclick="next">Login</a-->
<button class="btn btn-primary mt-3" type="submit">Login</button>
</form>
<p>@currentStep</p>
@{
if (!loggedIn)
{
<div>
<p>@localizer["LoginEmail"]: @loginModel.Email</p>
<p>@loginModel.Password</p>
</div>
</EditForm>
<p>@isUserLoggedIn</p><p>@CurrentValue</p>
}
}
<div class="text-center fs-6">
<a href="#">Forget password?</a> or <a href="register">Sign up</a>
No account yet? <a href="register">Sign up here!</a>
</div>
</div>
@code {
LoginModel loginModel = new();
LoginModel loginModel = new LoginModel("test@test", "test1234");
bool isUserLoggedIn;
int CurrentValue = 0;
public async Task next()
{
//var user = await userDataService.IsLoggedInAsync();
//user.IsLoggedIn = true;
//isUserLoggedIn = user.IsLoggedIn;
//user.UserType = (UserType)CurrentValue;
//navManager.NavigateTo("home");
}
public void Submit()
{
}
}

View File

@ -0,0 +1,165 @@
using Microsoft.AspNetCore.Components;
using System.IdentityModel.Tokens.Jwt;
using System.Text.Json;
using TIAMWebApp.Shared.Application.Models.ClientSide;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Utility;
using Microsoft.JSInterop;
using AyCode.Interfaces.StorageHandlers;
using System.ComponentModel.DataAnnotations;
using TIAMSharedUI.Resources;
using System.Resources;
using Microsoft.Extensions.Localization;
using AyCode.Blazor.Components;
using Azure.Core;
namespace TIAMSharedUI.Pages
{
public partial class Login : ComponentBase
{
[Inject]
public NavigationManager navManager { get; set; }
[Inject]
public IUserDataService userDataService { get; set; }
[Inject]
public LogToBrowserConsole logToBrowserConsole { get; set; }
[Inject]
public IJSRuntime jsRuntime { get; set; }
[Inject]
public ISecureStorageHandler secureStorageHandler { get; set; }
[Inject]
public IStringLocalizer<MyResources> localizer { get; set; }
[Inject]
public ISessionService sessionService { get; set; }
//fill loginmodel with fake but valid data
//LoginModel loginModel = new();
//[Display(Name = "LoginTitleText", ResourceType = typeof(MyResources))]
public string TitleText { get; set; } = "dda,mnd,amn,a";
private int currentStep = 1;
bool loggedIn = false;
private void GoToNextStep()
{
currentStep++;
}
private void GoToPreviousStep()
{
currentStep--;
}
private async void SubmitLogin()
{
currentStep = 1;
logToBrowserConsole.LogToBC("Login started: " + "Email: " + loginModel.Email + ", Password: " + loginModel.Password);
var response = await userDataService.AuthenticateUser(loginModel);
//var response = await UserDataservice.TestUserApi(30);
logToBrowserConsole.LogToBC("Login started");
logToBrowserConsole.LogToBC(response);
if (!string.IsNullOrEmpty(response))
{
//get token and save to local storage
//parse to Mainresponse from json string
//var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response);
var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (Mainresponse != null)
{
//check for bad request
//TODO: fix hacky solution
string AuthResponseJson = JsonSerializer.Serialize(Mainresponse.Content);
var AuthResponse = JsonSerializer.Deserialize<AuthenticationResponse>(AuthResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
string accessToken = AuthResponse.AccessToken;
var token = ProcessToken(accessToken);
string _userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value;
string _email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
var myId = Guid.Parse(_userId);
//userDataService.User.Email = _email;
var userBasicDetails = new UserBasicDetails(_userId, _email, AuthResponse.AccessToken, AuthResponse.RefreshToken);
string userBasicDetailsJson = JsonSerializer.Serialize(userBasicDetails);
//save to local storage
await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userBasicDetailsJson);
if (!Mainresponse.IsSuccess)
{
//await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok");
//display error message via jsinterop
logToBrowserConsole.LogToBC("Invalid credentials");
navManager.NavigateTo("login");
}
else
{
//await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok");
//display success message via jsinterop
logToBrowserConsole.LogToBC("Successful login");
var user = await userDataService.IsLoggedInAsync(myId);
SaveToSessionInfo(user);
user.UserType = UserType.Admin;
navManager.NavigateTo("index");
}
}
}
else
{
//api error
//await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
//display error message via jsinterop
logToBrowserConsole.LogToBC("An error occured while trying to login");
navManager.NavigateTo("login");
}
}
protected override void OnInitialized()
{
base.OnInitialized();
if(sessionService.IsAuthenticated)
{
navManager.NavigateTo("index");
}
}
public JwtSecurityToken ProcessToken(string accessToken)
{
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(accessToken) as JwtSecurityToken;
return token;
}
/// <summary>
/// This method stores the user data in the session service so we know during navigation that the user is logged in.
/// </summary>
/// <param name="user"></param>
protected void SaveToSessionInfo(UserSessionModel user)
{
sessionService.User = user;
sessionService.IsAuthenticated = true;
}
}
}

View File

@ -1,7 +1,3 @@
.wrapper {
max-width: 400px;
}
select :focus-visible {
border-color: transparent !important;
}

View File

@ -1,165 +0,0 @@
@page "/login"
@using System.IdentityModel.Tokens.Jwt;
@using System.Security.Claims;
@using Newtonsoft.Json.Linq;
@using System.Text.Json;
@using System.Reflection;
@using TIAMWebApp.Shared.Application.Interfaces;
@using TIAMWebApp.Shared.Application.Models.PageModels;
@using TIAMSharedUI.Pages.Components;
@using TIAMWebApp.Shared.Application.Models.ClientSide;
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Utility;
@using AyCode.Interfaces.StorageHandlers;
@inject NavigationManager navManager
@inject LogToBrowserConsole logToBrowserConsole
@inject IUserDataService userDataService
@inject IJSRuntime jsRuntime
@inject ISecureStorageHandler SecureStorageHandler
<PageTitle>Login</PageTitle>
<div class="wrapper">
<div class="my-logo">
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
</div>
<div class="text-center mt-4 name">
Let's get you inside!
</div>
<form class="p-3 mt-3">
<div>
@switch (currentStep)
{
case 1:
<LoginStep1 @bind-LoginModel="loginModel" onLoginNext="GoToNextStep" />
;
break;
case 2:
<LoginStep3 @bind-LoginModel="loginModel" onSubmit="SubmitLogin" onPrev="GoToPreviousStep" />
;
break;
}
</div>
</form>
<p>@currentStep</p>
@{
if (!loggedIn)
{
<div>
<p>@loginModel.Email</p>
<p>@loginModel.Password</p>
</div>
}
}
<div class="text-center fs-6">
No account yet? <a href="register">Sign up here!</a>
</div>
</div>
@code {
LoginModel loginModel = new();
private int currentStep = 1;
bool loggedIn = false;
private void GoToNextStep()
{
currentStep++;
}
private void GoToPreviousStep()
{
currentStep--;
}
private async void SubmitLogin()
{
currentStep = 1;
logToBrowserConsole.LogToBC("Login started: " + "Email: " + loginModel.Email + ", Password: " + loginModel.Password);
var response = await userDataService.AuthenticateUser(loginModel);
//var response = await UserDataservice.TestUserApi(30);
logToBrowserConsole.LogToBC("Login started");
logToBrowserConsole.LogToBC(response);
if (!string.IsNullOrEmpty(response))
{
//get token and save to local storage
//parse to Mainresponse from json string
//var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response);
var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (Mainresponse != null)
{
//check for bad request
string AuthResponseJson = JsonSerializer.Serialize(Mainresponse.Content);
var AuthResponse = JsonSerializer.Deserialize<AuthenticationResponse>(AuthResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
string accessToken = AuthResponse.AccessToken;
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(accessToken) as JwtSecurityToken;
string _userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value;
string _email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
var myId = Guid.Parse(_userId);
//userDataService.User.Email = _email;
var userBasicDetails = new UserBasicDetails(_userId, _email, AuthResponse.AccessToken, AuthResponse.RefreshToken);
string userBasicDetailsJson = JsonSerializer.Serialize(userBasicDetails);
//save to local storage
await SecureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userBasicDetailsJson);
if (!Mainresponse.IsSuccess)
{
//await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok");
//display error message via jsinterop
logToBrowserConsole.LogToBC("Invalid credentials");
navManager.NavigateTo("login");
}
else
{
//await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok");
//display success message via jsinterop
logToBrowserConsole.LogToBC("Successful login");
var user = await userDataService.IsLoggedInAsync(myId);
user.UserType = UserType.Admin;
navManager.NavigateTo("home");
}
}
}
else
{
//api error
//await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
//display error message via jsinterop
logToBrowserConsole.LogToBC("An error occured while trying to login");
navManager.NavigateTo("login");
}
}
}

View File

@ -1,3 +0,0 @@
.wrapper {
max-width: 400px;
}

View File

@ -0,0 +1,73 @@
@page "/login_old"
@using TIAMWebApp.Shared.Application.Interfaces;
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Models.PageModels;
@inject NavigationManager navManager
@inject IUserDataService userDataService
<PageTitle>Login</PageTitle>
<div class="wrapper">
<div class="my-logo">
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
</div>
<div class="text-center mt-4 name">
Tour I Am
</div>
<EditForm Model="@loginModel" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<!--ValidationSummary /-->
<div class="p-3 mt-3">
<div class="form-field d-flex align-items-center">
<span class="far fa-user"></span>
<input type="email" @bind-value="loginModel.Email" name="email" id="phoneNumber" placeholder="Phone number">
<ValidationMessage For="@(() => loginModel.Email)" />
</div>
<div class="form-field d-flex align-items-center">
<span class="fas fa-key"></span>
<input type="password" @bind-value="loginModel.Password" name="password" id="pwd" placeholder="Password">
<ValidationMessage For="@(() => loginModel.Password)" />
</div>
<div class="form-field d-flex align-items-center">
<select style="width:100%" @bind="CurrentValue" class="custom-select" title="Destination is required ">
<option value="0" selected disabled="disabled">(Choose account type)</option>
<option value="1" selected>Hotel</option>
<option value="2" selected>Transfer</option>
<option value="3" selected>Guide</option>
<option value="4" selected>Admin</option>
<option value="5" selected>UserModel</option>
<option value="6" selected>Driver</option>
</select>
</div>
<!--button class="btn btn-primary mt-3" @onclick="next">Login</button-->
<!--a class="btn btn-primary mt-3" @onclick="next">Login</a-->
<button class="btn btn-primary mt-3" type="submit">Login</button>
</div>
</EditForm>
<p>@isUserLoggedIn</p><p>@CurrentValue</p>
<div class="text-center fs-6">
<a href="#">Forget password?</a> or <a href="register">Sign up</a>
</div>
</div>
@code {
LoginModel loginModel = new LoginModel("", "");
bool isUserLoggedIn;
int CurrentValue = 0;
public async Task next()
{
//var user = await userDataService.IsLoggedInAsync();
//user.IsLoggedIn = true;
//isUserLoggedIn = user.IsLoggedIn;
//user.UserType = (UserType)CurrentValue;
//navManager.NavigateTo("home");
}
public void Submit()
{
}
}

View File

@ -0,0 +1,7 @@
.wrapper{
max-width:400px;
}
select :focus-visible {
border-color: transparent !important;
}

View File

@ -0,0 +1,26 @@
@page "/settings"
@using TIAMSharedUI.Pages.Components
@using TIAMSharedUI.Pages.User
@using TIAMWebApp.Shared.Application.Models.ClientSide;
<div class="container-fluid">
<h3>@localizer["Settings.Title"]</h3>
<div class="row">
<!--SettingsBasic LanguageChanged="Refresh"></SettingsBasic-->
<SettingsBasic></SettingsBasic>
</div>
@if (@UserIsLoggedIn)
{
<hr />
<div class="row">
<SettingsMember></SettingsMember>
</div>
}
</div>
@code {
}

View File

@ -0,0 +1,50 @@
using AyCode.Blazor.Components;
using AyCode.Interfaces.StorageHandlers;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using TIAMSharedUI.Pages.Components;
using TIAMSharedUI.Resources;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Models.ClientSide;
namespace TIAMSharedUI.Pages
{
public partial class Settings : ComponentBase
{
[Inject]
public ISecureStorageHandler? secureStorageHandler { get; set; }
[Inject]
public IStringLocalizer<MyResources>? localizer { get; set; }
[Inject]
public ISessionService sessionService { get; set; }
public string Language { get; set; } = "en-US";
private AuthComponent Auth;
private bool UserIsLoggedIn = false;
protected override async Task OnInitializedAsync()
{
base.OnInitialized();
UserIsLoggedIn = sessionService.IsAuthenticated;
GetCurrentSettings();
}
public void SaveSettings()
{
secureStorageHandler.SaveToSecureStorageAsync(Setting.Locale, "hu-HU");
}
public void GetCurrentSettings()
{
secureStorageHandler.GetFromSecureStorageAsync(Setting.Locale);
}
public void ResetSettings()
{
secureStorageHandler.DeleteFromSecureStorageAsync(Setting.Locale);
}
}
}

View File

@ -1,10 +1,13 @@
@page "/dbtest"
@using TIAMSharedUI.Pages.Components
<h3>TestPage</h3>
<ChooseDestination></ChooseDestination>
<hr/>
<DbTestComponent></DbTestComponent>
<InputWizard></InputWizard>
@code {

View File

@ -1,10 +1,9 @@
@page "/tours"
@using TIAMSharedUI.Shared
<TopRow></TopRow>
<HeroSlider></HeroSlider>
<div class="container-fluid">
<div class="container">
<section class="game-section" style="max-width: 100%; overflow-x:hidden">
<div class="text-center">

View File

@ -0,0 +1,833 @@
@page "/admin"
@using TIAMSharedUI.Shared
@using TIAMWebApp.Shared.Application.Models;
@using TIAMWebApp.Shared.Application.Interfaces;
@layout AdminLayout
@inject IPopulationStructureDataProvider DataProvider
@inject ISupplierService SupplierService
@inject IUserDataService UserDataService
<PageTitle>Transfer</PageTitle>
<div class="text-center m-5">
<h1>Dashboard</h1>
<h2 style="font-size:small">Have a nice day!</h2>
</div>
<!--We need to check if the user is owner of a swerviceprovider-->
<div class="container-fluid">
@{
if(userType == 4)
{
<!--App admin-->
<div class="row py-3">
<div class=" col-12 col-xl-3 col-lg-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Transfers</span>
<p class="text-muted mb-0">Summary</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<h5>New</h5>
<p>12</p>
<h5>Scheduled</h5>
<p>182</p>
<h5>Finished</h5>
<p>15665</p>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Manage transgfers</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3 col-lg-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Service providers</span>
<p class="text-muted mb-0">Summary</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<h5>Guides</h5>
<p>32</p>
<h5>Hotels</h5>
<p>82</p>
<h5>Restaurants</h5>
<p>15</p>
<h5>Transfer company</h5>
<p>1</p>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Manage service providers</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3 col-lg-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Finances</span>
<p class="text-muted mb-0">Summary</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<h5>Income</h5>
<p>$32 456</p>
<h5>Comission to be paid</h5>
<p>$5 345</p>
<h5>Service fees to be paid</h5>
<p>$23 871</p>
<h5>Revenue</h5>
<p>$3 240</p>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Manage service providers</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3 col-lg-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Affiliates</span>
<p class="text-muted mb-0">Summary</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<h5>Top affiliate</h5>
<p>Hotel Bambara</p>
<h5>Comission Earned</h5>
<p>$1 315</p>
<hr />
<h5>Top referred item</h5>
<p>Buda castle tour</p>
<hr />
<h5>Level 1 affiliates</h5>
<p>132</p>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Manage affiliates</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Hotel details</span>
</div>
<div>
<h6 class="mb-0"> <a href="#">All settings</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<DxGrid Data="@AffiliateData">
<Columns>
<DxGridDataColumn FieldName="AffiliateId" Width="5%" />
<DxGridDataColumn FieldName="IncomeThisMonth" Width="15%" />
<DxGridDataColumn FieldName="IncomeAlltime" Width="15%" />
<DxGridDataColumn FieldName="CompanyName" />
<DxGridDataColumn FieldName="Status" Width="10%" />
</Columns>
</DxGrid>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Population Data</span>
<p class="text-muted mb-0">12,March 2020 </p>
</div>
<div>
<h6 class="mb-0"> <a href="#">View source</a> </h6>
</div>
</div>
</div>
<div class="card-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<DxChart T="PopulationAgeStructureItem"
Data="@ChartsData"
Width="100%" Height="300px">
<DxChartTitle Text="Population: Age Structure">
<DxChartSubTitle Text="Data Estimate for 2020" />
</DxChartTitle>
<DxChartBarSeries Name="0-14 years"
T="PopulationAgeStructureItem"
TArgument="string"
TValue="int"
ArgumentField="pasi => pasi.Country"
ValueField="pasi => pasi.Population"
SummaryMethod="Enumerable.Sum"
Filter='pasi => pasi.AgeGroup == "0-14 years"' />
<DxChartBarSeries Name="15-64 years"
T="PopulationAgeStructureItem"
TArgument="string"
TValue="int"
ArgumentField="pasi => pasi.Country"
ValueField="pasi => pasi.Population"
SummaryMethod="Enumerable.Sum"
Filter='pasi => pasi.AgeGroup == "15-64 years"' />
<DxChartBarSeries Name="65 years and older"
T="PopulationAgeStructureItem"
TArgument="string"
TValue="int"
ArgumentField="pasi => pasi.Country"
ValueField="pasi => pasi.Population"
SummaryMethod="Enumerable.Sum"
Filter='pasi => pasi.AgeGroup == "65 years and older"' />
<DxChartLegend Position="RelativePosition.Outside"
HorizontalAlignment="HorizontalAlignment.Center"
VerticalAlignment="VerticalEdge.Bottom" />
<DxChartTooltip Enabled="true"
Position="RelativePosition.Outside">
<div style="margin: 0.75rem">
<div class="fw-bold">@context.Point.Argument</div>
<div>Age Group: @context.Point.SeriesName</div>
<div>Population: @($"{context.Point.Value:N0}")</div>
</div>
</DxChartTooltip>
</DxChart>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Affiliates</span>
<p class="text-muted mb-0">Details</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<style>
.dxbl-grid {
--dxbl-grid-font-family: inherit;
--dxbl-grid-font-size: 0.75rem;
--dxbl-grid-line-height: 1.4285;
--dxbl-grid-min-width: 240px;
--dxbl-grid-bg: #e7e6f7;
--dxbl-grid-color: #58457b;
}
</style>
<DxGrid Data="@Data">
<Columns>
<DxGridDataColumn FieldName="CompanyName" AllowSort="true" />
<DxGridDataColumn FieldName="ContactName" />
<DxGridDataColumn FieldName="ContactTitle" Width="3%" />
<DxGridDataColumn FieldName="Country" Width="10%" />
<DxGridDataColumn FieldName="City" Width="10%" />
<DxGridDataColumn FieldName="Address" />
<DxGridDataColumn FieldName="Phone" Width="10%" />
</Columns>
</DxGrid>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
</div>
<!-- App admin end-->
<!-- Hotel admin-->
}
else if(userType == 1)
{
<div class="row py-3">
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Hotel details</span>
</div>
<div>
<h6 class="mb-0"> <a href="#">All settings</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<div class="flex-fill">
<h5 class="bold">Your QR code</h5>
<p class="text-muted"> Use this in printed material, to gain referrals</p>
</div>
<div>
<img class="align-self-center img-fluid"
src="_content/TIAMSharedUI/images/myqr.png" width="128">
</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 class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">My orders</span>
</div>
<div>
<h6 class="mb-0"> <a href="#">All settings</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<DxGrid Data="@OrderData">
<Columns>
<DxGridDataColumn FieldName="Date" DisplayFormat="D" MinWidth="100">
<CellDisplayTemplate>
<a class="d-block text-left" href="transferdetails">@context.Value</a>
</CellDisplayTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="Income" Width="15%" />
<DxGridDataColumn FieldName="TransactionId" Width="15%" />
<DxGridDataColumn FieldName="Status" Width="10%" />
</Columns>
</DxGrid>
</div>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Hotel details</span>
</div>
<div>
<h6 class="mb-0"> <a href="#">All settings</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Panel title</span>
<p class="text-muted mb-0">Subtitle</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<div class="flex-fill">
<h5 class="bold">Some info</h5>
<p class="text-muted"> Budapest, Dózsa György út 35, 1146</p>
</div>
<div>
<!--img class="align-self-center img-fluid"
src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/E-commerce/Products/6.webp" width="250"-->
</div>
</div>
<ul id="progressbar-1" class="mx-0 mt-0 mb-5 px-0 pt-0 pb-4">
<li class="step0 active" id="step1">
<span style="margin-left: 22px; margin-top: 12px;">PLACED</span>
</li>
<li class="step0 active text-center" id="step2"><span>WAITING FOR PICK UP</span></li>
<li class="step0 text-muted text-end" id="step3">
<span style="margin-right: 22px;">FINISHED</span>
</li>
</ul>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Affiliates</span>
<p class="text-muted mb-0">Details</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<style>
.dxbl-grid {
--dxbl-grid-font-family: inherit;
--dxbl-grid-font-size: 0.75rem;
--dxbl-grid-line-height: 1.4285;
--dxbl-grid-min-width: 240px;
--dxbl-grid-bg: #e7e6f7;
--dxbl-grid-color: #58457b;
}
</style>
<DxGrid Data="@Data">
<Columns>
<DxGridDataColumn FieldName="CompanyName" AllowSort="true" />
<DxGridDataColumn FieldName="ContactName" />
<DxGridDataColumn FieldName="ContactTitle" Width="3%" />
<DxGridDataColumn FieldName="Country" Width="10%" />
<DxGridDataColumn FieldName="City" Width="10%" />
<DxGridDataColumn FieldName="Address" />
<DxGridDataColumn FieldName="Phone" Width="10%" />
</Columns>
</DxGrid>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Hotel admin end-->
}
}
<!-- Stats admin-->
<div class="row py-3">
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Panel title</span>
<p class="text-muted mb-0">Subtitle</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<div class="flex-fill">
<h5 class="bold">Some info</h5>
<p class="text-muted"> Budapest, Dózsa György út 35, 1146</p>
</div>
<div>
<!--img class="align-self-center img-fluid"
src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/E-commerce/Products/6.webp" width="250"-->
</div>
</div>
<ul id="progressbar-1" class="mx-0 mt-0 mb-5 px-0 pt-0 pb-4">
<li class="step0 active" id="step1">
<span style="margin-left: 22px; margin-top: 12px;">PLACED</span>
</li>
<li class="step0 active text-center" id="step2"><span>WAITING FOR PICK UP</span></li>
<li class="step0 text-muted text-end" id="step3">
<span style="margin-right: 22px;">FINISHED</span>
</li>
</ul>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Panel title</span>
<p class="text-muted mb-0">Subtitle</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<div class="flex-fill">
<h5 class="bold">Some info</h5>
<p class="text-muted"> Budapest, Dózsa György út 35, 1146</p>
</div>
<div>
<!--img class="align-self-center img-fluid"
src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/E-commerce/Products/6.webp" width="250"-->
</div>
</div>
<ul id="progressbar-1" class="mx-0 mt-0 mb-5 px-0 pt-0 pb-4">
<li class="step0 active" id="step1">
<span style="margin-left: 22px; margin-top: 12px;">PLACED</span>
</li>
<li class="step0 active text-center" id="step2"><span>WAITING FOR PICK UP</span></li>
<li class="step0 text-muted text-end" id="step3">
<span style="margin-right: 22px;">FINISHED</span>
</li>
</ul>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
<div class="card card-admin" style="border-radius: 16px;">
<div class="card-header py-2 px-4">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold text-body">Panel title</span>
<p class="text-muted mb-0">Subtitle</p>
</div>
<div>
<h6 class="mb-0"> <a href="#">All details</a> </h6>
</div>
</div>
</div>
<div class="card-body card-admin-body py-2 px-4">
<div class="d-flex flex-row mb-4 pb-2">
<div class="flex-fill">
<h5 class="bold">Some info</h5>
<p class="text-muted"> Budapest, Dózsa György út 35, 1146</p>
</div>
<div>
<!--img class="align-self-center img-fluid"
src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/E-commerce/Products/6.webp" width="250"-->
</div>
</div>
<ul id="progressbar-1" class="mx-0 mt-0 mb-5 px-0 pt-0 pb-4">
<li class="step0 active" id="step1">
<span style="margin-left: 22px; margin-top: 12px;">PLACED</span>
</li>
<li class="step0 active text-center" id="step2"><span>WAITING FOR PICK UP</span></li>
<li class="step0 text-muted text-end" id="step3">
<span style="margin-right: 22px;">FINISHED</span>
</li>
</ul>
<div class="d-flex flex-row mb-4 pb-2">
<h4> Some <span class="small text-muted"> conclusion </span></h4>
</div>
</div>
<div class="card-footer py-2 px-4">
<div class="d-flex justify-content-between">
<a href="#!">Modify</a>
<div class="border-start h-100"></div>
</div>
</div>
</div>
</div>
<div class=" col-12 col-xl-3">
</div>
</div>
</div>
@code {
object? OrderData { get; set; }
object? AffiliateData { get; set; }
IEnumerable<PopulationAgeStructureItem>? ChartsData;
object? Data { get; set; }
bool isUserLoggedIn;
int userType = 0;
protected override async Task OnInitializedAsync()
{
base.OnInitialized();
OrderData = new object[]
{
new {
Date = DateTime.Now.AddDays(3),
Income = "$5",
TransactionId = "POX987532582",
Status = "Finished"
},
new {
Date = DateTime.Today.AddDays(-2),
Income = "$5",
TransactionId = "POX645646382",
Status = "Finished"
},
new {
Date = DateTime.Today.AddDays(-6),
Income = "$8",
TransactionId = "POX645766311",
Status = "Finished"
},
};
AffiliateData = new object[]
{
new {
AffiliateId = 1,
IncomeThisMonth = "$5",
IncomeAlltime = "9425",
CompanyName = "Upgen Ltd.",
Status = "Active"
},
new {
AffiliateId = 2,
IncomeThisMonth = "$538",
IncomeAlltime = "13425",
CompanyName = "Kovacs hotel Ltd.",
Status = "Active"
},
new {
AffiliateId = 3,
IncomeThisMonth = "$0",
IncomeAlltime = "134200",
CompanyName = "Innosaurus Ltd.",
Status = "Passive"
},
};
ChartsData = await DataProvider.QueryData();
var suppliers = await SupplierService.GetSuppliersAsync();
Data = suppliers.Select(s =>
{
return new
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Country = s.Country,
City = s.City,
Address = s.Address,
Phone = s.Phone
};
});
}
[Parameter] public bool ShowSeriesPointMarkers { get; set; }
[Parameter] public bool ShowSeriesLabels { get; set; }
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TIAMSharedUI.Pages.User
{
public partial class Home
{
}
}

View File

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

View File

@ -0,0 +1,279 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TIAMSharedUI.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class MyResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MyResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TIAMSharedUI.Resources.MyResources", typeof(MyResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Blehhhh.
/// </summary>
public static string Bleh {
get {
return ResourceManager.GetString("Bleh", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clubcards.
/// </summary>
public static string Index_Clubcards {
get {
return ResourceManager.GetString("Index.Clubcards", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Join the club, and enjoy great offers during your stay!.
/// </summary>
public static string Index_Clubcards_Desc {
get {
return ResourceManager.GetString("Index.Clubcards.Desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please select!.
/// </summary>
public static string Index_Subtitle {
get {
return ResourceManager.GetString("Index.Subtitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Welcome!.
/// </summary>
public static string Index_Title {
get {
return ResourceManager.GetString("Index.Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Tours.
/// </summary>
public static string Index_Tours {
get {
return ResourceManager.GetString("Index.Tours", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Are you curious about the wonderful sights of Budapest or Hungary? Book a guided tour now!.
/// </summary>
public static string Index_Tours_Desc {
get {
return ResourceManager.GetString("Index.Tours.Desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Transfer.
/// </summary>
public static string Index_Transfer {
get {
return ResourceManager.GetString("Index.Transfer", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Do you need a lift? Book a transfer now!.
/// </summary>
public static string Index_Transfer_Desc {
get {
return ResourceManager.GetString("Index.Transfer.Desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Email.
/// </summary>
public static string LoginEmail {
get {
return ResourceManager.GetString("LoginEmail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password.
/// </summary>
public static string LoginPassword {
get {
return ResourceManager.GetString("LoginPassword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Let&apos;s get you inside!.
/// </summary>
public static string LoginTitleText {
get {
return ResourceManager.GetString("LoginTitleText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Home.
/// </summary>
public static string NavMenu_Home {
get {
return ResourceManager.GetString("NavMenu.Home", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Login.
/// </summary>
public static string NavMenu_Login {
get {
return ResourceManager.GetString("NavMenu.Login", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
public static string NavMenu_Settings {
get {
return ResourceManager.GetString("NavMenu.Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sign out.
/// </summary>
public static string NavMenu_SignOut {
get {
return ResourceManager.GetString("NavMenu.SignOut", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Transfer.
/// </summary>
public static string NavMenu_Transfer {
get {
return ResourceManager.GetString("NavMenu.Transfer", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Register.
/// </summary>
public static string RegisterRegister {
get {
return ResourceManager.GetString("RegisterRegister", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Language.
/// </summary>
public static string Settings_Language {
get {
return ResourceManager.GetString("Settings.Language", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
public static string Settings_Title {
get {
return ResourceManager.GetString("Settings.Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Next.
/// </summary>
public static string Transfer_Next {
get {
return ResourceManager.GetString("Transfer.Next", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Previous.
/// </summary>
public static string Transfer_Previous {
get {
return ResourceManager.GetString("Transfer.Previous", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Start typing or swipe to select a preset destination!.
/// </summary>
public static string Transfer_Subtitle {
get {
return ResourceManager.GetString("Transfer.Subtitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Book a transfer.
/// </summary>
public static string Transfer_Title {
get {
return ResourceManager.GetString("Transfer.Title", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Bleh" xml:space="preserve">
<value>Blehhhh</value>
</data>
<data name="Index.Clubcards" xml:space="preserve">
<value>Klubkártyák</value>
</data>
<data name="Index.Clubcards.Desc" xml:space="preserve">
<value>Csatlakozz a klubhoz, és élvezd az klubtagság nyújtotta előnyöket az ittléted alatt!</value>
</data>
<data name="Index.Subtitle" xml:space="preserve">
<value>Válassz az alábbiak közül!</value>
</data>
<data name="Index.Title" xml:space="preserve">
<value>Üdvözlünk!</value>
</data>
<data name="Index.Tours" xml:space="preserve">
<value>Vezetett túrák</value>
</data>
<data name="Index.Tours.Desc" xml:space="preserve">
<value>Megnéznéd Budapest vagy Magyarország legszebb látványosságait? Foglalj vezetett túrát most!</value>
</data>
<data name="Index.Transfer" xml:space="preserve">
<value>Transzfer</value>
</data>
<data name="Index.Transfer.Desc" xml:space="preserve">
<value>Kéne egy fuvar? Foglalj most!</value>
</data>
<data name="LoginEmail" xml:space="preserve">
<value>E-mail</value>
</data>
<data name="LoginPassword" xml:space="preserve">
<value>Jelszó</value>
</data>
<data name="LoginTitleText" xml:space="preserve">
<value>Lépjünk csak be!</value>
</data>
<data name="NavMenu.Home" xml:space="preserve">
<value>Főoldal</value>
</data>
<data name="NavMenu.Login" xml:space="preserve">
<value>Belépés</value>
</data>
<data name="NavMenu.Settings" xml:space="preserve">
<value>Beállítások</value>
</data>
<data name="NavMenu.SignOut" xml:space="preserve">
<value>Kijelentkezés</value>
</data>
<data name="NavMenu.Transfer" xml:space="preserve">
<value>Transzfer</value>
</data>
<data name="RegisterRegister" xml:space="preserve">
<value>Regisztráció</value>
</data>
<data name="Settings.Language" xml:space="preserve">
<value>Nyelv</value>
</data>
<data name="Settings.Title" xml:space="preserve">
<value>Beállítások</value>
</data>
<data name="Transfer.Next" xml:space="preserve">
<value>Tovább</value>
</data>
<data name="Transfer.Previous" xml:space="preserve">
<value>Vissza</value>
</data>
<data name="Transfer.Subtitle" xml:space="preserve">
<value>Írj be valamit, vagy húzz balra előre elmentett uticélokért</value>
</data>
<data name="Transfer.Title" xml:space="preserve">
<value>Foglalj transzfert!</value>
</data>
</root>

View File

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Bleh" xml:space="preserve">
<value>Blehhhh</value>
</data>
<data name="Index.Clubcards" xml:space="preserve">
<value>Clubcards</value>
</data>
<data name="Index.Clubcards.Desc" xml:space="preserve">
<value>Join the club, and enjoy great offers during your stay!</value>
</data>
<data name="Index.Subtitle" xml:space="preserve">
<value>Please select!</value>
</data>
<data name="Index.Title" xml:space="preserve">
<value>Welcome!</value>
</data>
<data name="Index.Tours" xml:space="preserve">
<value>Tours</value>
</data>
<data name="Index.Tours.Desc" xml:space="preserve">
<value>Are you curious about the wonderful sights of Budapest or Hungary? Book a guided tour now!</value>
</data>
<data name="Index.Transfer" xml:space="preserve">
<value>Transfer</value>
</data>
<data name="Index.Transfer.Desc" xml:space="preserve">
<value>Do you need a lift? Book a transfer now!</value>
</data>
<data name="LoginEmail" xml:space="preserve">
<value>Email</value>
</data>
<data name="LoginPassword" xml:space="preserve">
<value>Password</value>
</data>
<data name="LoginTitleText" xml:space="preserve">
<value>Let's get you inside!</value>
</data>
<data name="NavMenu.Home" xml:space="preserve">
<value>Home</value>
</data>
<data name="NavMenu.Login" xml:space="preserve">
<value>Login</value>
</data>
<data name="NavMenu.Settings" xml:space="preserve">
<value>Settings</value>
</data>
<data name="NavMenu.SignOut" xml:space="preserve">
<value>Sign out</value>
</data>
<data name="NavMenu.Transfer" xml:space="preserve">
<value>Transfer</value>
</data>
<data name="RegisterRegister" xml:space="preserve">
<value>Register</value>
</data>
<data name="Settings.Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="Settings.Title" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Transfer.Next" xml:space="preserve">
<value>Next</value>
</data>
<data name="Transfer.Previous" xml:space="preserve">
<value>Previous</value>
</data>
<data name="Transfer.Subtitle" xml:space="preserve">
<value>Start typing or swipe to select a preset destination!</value>
</data>
<data name="Transfer.Title" xml:space="preserve">
<value>Book a transfer</value>
</data>
</root>

View File

@ -0,0 +1,74 @@
@using TIAMSharedUI.Pages.Components
@using TIAMWebApp.Shared.Application.Interfaces
@using AyCode.Interfaces.StorageHandlers
@using Microsoft.Extensions.Localization
@inject ISecureStorageHandler SecureStorageHandler
@inject ISessionService sessionService;
@inject IStringLocalizer<MyResources> localizer
<nav class="navbar sticky-top navbar-expand-lg">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img height="25" src="_content/TIAMSharedUI/images/logo_wide.png" alt="TourIam Logo" title="TourIAm Logo" /></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<!--NavLink class="nav-link" href="" Match="NavLinkMatch.All"-->
<NavLink class="nav-link" href="index">
<!--span class="oi oi-home" aria-hidden="true"></span-->
@localizer.GetString("NavMenu.Home")
</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="transfer">
@localizer.GetString("NavMenu.Transfer")
</NavLink>
</li><li class="nav-item">
<NavLink class="nav-link" href="swagger">
API
</NavLink>
</li>
<li class="nav-item dropdown">
<NavLink class="nav-link" href="settings">
@localizer.GetString("NavMenu.Settings")
</NavLink>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
@if(!myUser)
{
<li class="nav-item">
<NavLink class="nav-link" href="login">
@localizer.GetString("NavMenu.Login")
</NavLink>
</li>
}
<li class="nav-item">
<div class="btn-nav">
<NavLink class="btn btn-primary btn-small navbar-btn" href="#" @onclick="SignOut">
@localizer.GetString("NavMenu.SignOut")
</NavLink>
</div>
</li>
</ul>
</div>
</div>
</nav>
@code {
}

View File

@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAMWebApp.Shared.Application.Interfaces;
namespace TIAMSharedUI.Shared.Components
{
public partial class Navbar : ComponentBase
{
[Inject]
public NavigationManager navigationManager { get; set; }
[Inject]
public IComponentUpdateService componentUpdateService { get; set; }
private bool collapseNavMenu = true;
private bool myUser = false;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
//componentUpdateService.RefreshRequested += RefreshMe;
private void RefreshMe()
{
StateHasChanged();
}
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
private void NavigateBack()
{
}
private void SignOut()
{
SecureStorageHandler.ClearAllSecureStorageAsync();
sessionService.User = null;
sessionService.IsAuthenticated = false;
}
protected override void OnInitialized()
{
base.OnInitialized();
if (sessionService.User != null)
{
myUser = true;
}
else
{
myUser = false;
}
componentUpdateService.RefreshRequested += RefreshMe;
}
}
}

View File

@ -0,0 +1,80 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
padding: 0px;
}
.top-row {
height: 3.5rem;
}
.navbar-brand {
font-size: 1.1rem;
}
.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.oi-2 {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}
.nav-item {
font-size: large;
margin: auto;
display: flex;
align-content: center;
}
/*.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}*/
.nav-item ::deep a {
color: #58457b;
/*border-radius: 15px;*/
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
margin: auto;
padding-left: 30px;
padding-right: 30px;
}
.nav-item ::deep a.active {
/*background-color: #475bd6;*/
color: #475bd6;
}
.nav-item ::deep a:hover {
/*background-color: #f7279f;*/
color: #f7279f;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
.nav-scrollable {
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@ -1,6 +1,7 @@
@inherits LayoutComponentBase
@using AyCode.Interfaces.StorageHandlers;
@using Newtonsoft.Json;
@using TIAMSharedUI.Shared.Components
@using TIAMWebApp.Shared.Application.Interfaces
@using TIAMWebApp.Shared.Application.Models.ClientSide;
@using AyCode.Blazor.Components;
@ -8,23 +9,23 @@
@using TIAMWebApp.Shared.Application.Utility;
@using System.IdentityModel.Tokens.Jwt;
@inject NavigationManager NavManager
@inject IUserDataService UserDataService;
@inject IJSRuntime jsRuntime;
@inject ISecureStorageHandler SecureStorageHandler
@inject ISessionService sessionService;
<div class="page">
<div class="my-sidebar">
<!--div-- class="page"-->
<div>
<Navbar/>
<!--div class="my-sidebar">
<NavMenu />
</div>
</div-->
<main>
<article class="content">
@if (Setting.UserBasicDetails != null)
{
<TopRow />
}
@Body
</article>
</main>
@ -35,4 +36,5 @@
@code {
}

View File

@ -1,6 +1,8 @@
@using TIAMWebApp.Shared.Application.Interfaces
@using AyCode.Interfaces.StorageHandlers;
@using AyCode.Interfaces.StorageHandlers
@using Microsoft.Extensions.Localization
@inject ISecureStorageHandler SecureStorageHandler
@inject IStringLocalizer<MyResources> localizer
<div class="top-row ps-3 navbar navbar-light">
<div class="container-fluid">
@ -51,6 +53,10 @@
<NavLink class="nav-link" href="login">
Login
</NavLink>
</div><div class="nav-item px-3">
<NavLink class="nav-link" href="settings">
Settings
</NavLink>
</div>
<hr />
<div class="nav-item px-3">

View File

@ -14,6 +14,7 @@
<ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="23.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
@ -34,4 +35,20 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\MyResources.Designer.cs">
<DependentUpon>MyResources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\MyResources.resx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<LastGenOutput>MyResources.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -5,4 +5,7 @@
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using Microsoft.Extensions.Localization;
@using TIAMSharedUI.Resources;
@using TIAMWebApp.Shared.Application.Models.ClientSide;
@using DevExpress.Blazor

View File

@ -4,6 +4,8 @@ using DevExpress.Blazor;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.JSInterop;
using System.Reflection;
using System.Resources;
using TIAMWebApp.Client;
using TIAMWebApp.Client.Services;
using TIAMWebApp.Shared.Application.Interfaces;
@ -12,7 +14,7 @@ using TIAMWebApp.Shared.Application.Utility;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddLocalization();
builder.Services.AddScoped<IWeatherForecastService, WeatherForecastService>();
builder.Services.AddScoped<ITransferDataService, TransferDataService>();
builder.Services.AddScoped<IPopulationStructureDataProvider, PopulationStructureDataProvider>();
@ -22,11 +24,15 @@ builder.Services.AddScoped<ISecureStorageHandler, SecureStorageHandler>();
builder.Services.AddScoped<LogToBrowserConsole>();
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddSingleton<ISessionService, SessionServiceWeb>();
builder.Services.AddSingleton<IComponentUpdateService, ComponentUpdateServiceWeb>();
builder.Services.AddScoped<IServiceProviderDataService, ServiceProviderDataServiceWeb>();
//WebSpecific
builder.Services.AddScoped<SessionStorageAccessor>();
builder.Services.AddSingleton(x => new ResourceManager("TIAMWebApp.Client.Resources.MyResources", typeof(Program).Assembly));
//WebSpecific end
builder.Services.AddSingleton(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
await builder.Build().RunAsync();

View File

@ -0,0 +1,13 @@
using TIAMWebApp.Shared.Application.Interfaces;
namespace TIAMWebApp.Client.Services
{
public class ComponentUpdateServiceWeb : IComponentUpdateService
{
public event Action RefreshRequested;
public void CallRequestRefresh()
{
RefreshRequested?.Invoke();
}
}
}

View File

@ -0,0 +1,128 @@
using System.Collections;
using System.Collections.Generic;
using System.Net.Http.Json;
using System.Text.Json;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.Products.DTOs;
using TIAM.Entities.TransferDestinations;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Models.ClientSide;
using TIAMWebApp.Shared.Application.Utility;
namespace TIAMWebApp.Client.Services
{
public class PermissionService : IPermissionService
{
private readonly HttpClient http;
private readonly LogToBrowserConsole logToBrowserConsole;
public PermissionService(HttpClient http, LogToBrowserConsole logToBrowserConsole)
{
this.http = http;
this.logToBrowserConsole = logToBrowserConsole;
}
//1. create a permission to be assigned to users to access a context
public Task CreatePermissionForContextByContextIdAsync(Guid contextId)
{
throw new NotImplementedException();
}
//2. get the contexts where the user has permission
public Task<List<AssignedPermissionModel>> GetPermissionContextsByUserIdAsync(Guid userId)
{
throw new NotImplementedException();
}
/// <summary>
///this is the method that checks if there are any permissions for a context already to determine the next bit to be used in the bitmask
/// </summary>
/// <param name="contextId"></param>
/// <returns>The next bit to set</returns>
//3. get the users who have permission for a context
public Task<List<AssignedPermissionModel>?> GetPermissionsForContextByContextIdAsync(Guid contextId)
{
var url = APIUrls.GetPermissionsForContextByContextId;
var response = http.PostAsJsonAsync(url, contextId);
//get the dictionary from the response
var result = response.Result.Content.ReadAsStringAsync().Result;
//deserialize the json string to a dictionary
List<AssignedPermissionModel>? permissions = JsonSerializer.Deserialize<List<AssignedPermissionModel>>(result);
//return the list of permissions
return Task.FromResult(permissions);
}
//4. give a user permission to access a context
public Task AssignPermissionToUserForContextAsync(Guid contextId, Guid userId)
{
throw new NotImplementedException();
}
//5. remove a user's permission to access a context
public Task RemovePermissionFromUserByContextIdAsync(Guid contextId, Guid permissionId, Guid userId)
{
throw new NotImplementedException();
}
//6. remove all permissions of a user for a context
public Task RemoveAllPermissionsByContextIdAsync(Guid contextId, Guid userId)
{
throw new NotImplementedException();
}
//7. remove all permissions of a user (BAN user from all contexts, even the system)
public Task RemoveAllPermissionsByUserIdAsync(Guid userId)
{
throw new NotImplementedException();
}
//8. create permission group
public Task CreatePermissionGroupForContextAsync(Guid contextId, string name)
{
throw new NotImplementedException();
}
//9. add user to permission group
public Task AddUserToPermissionGroupAsync(Guid permissionGroupId, Guid userId)
{
throw new NotImplementedException();
}
//10. create permission type
public Task<bool> CreatePermissionTypeAsync(string name, Guid contextId)
{
//chech if the context already has permissiontypes
//if it does, get the next bit value
//if it doesn't, use 1
//create the permissiontype
return Task.FromResult(false);
}
//11. get permission types for context
public Task<List<PermissionsType>>? GetPermissionTypesForContextByContextIdAsync(Guid contextId)
{
return http.GetFromJsonAsync<List<PermissionsType>>(APIUrls.GetPermissionGroupsForContextByContextId);
}
//12. get permission groups for context
public Task GetPermissionGroupsForContextByContextIdAsync(Guid contextId)
{
throw new NotImplementedException();
}
}
}

View File

@ -19,7 +19,7 @@ namespace TIAMWebApp.Client.Services
public async Task SaveToSecureStorageAsync(string key, string value)
{
await localStoragService.SetItemAsync(key, value);
await ssa.SetValueAsync(key, value);
//await ssa.SetValueAsync(key, value);
}
@ -27,20 +27,20 @@ namespace TIAMWebApp.Client.Services
public async Task<string> GetFromSecureStorageAsync(string key)
{
return await localStoragService.GetItemAsync<string>(key);
return await ssa.GetValueAsync<string>(key);
//return await ssa.GetValueAsync<string>(key);
}
public async Task DeleteFromSecureStorageAsync(string key)
{
await localStoragService.RemoveItemAsync(key);
await ssa.RemoveAsync(key);
//await ssa.RemoveAsync(key);
}
public async Task ClearAllSecureStorageAsync()
{
await localStoragService.ClearAsync();
await ssa.Clear();
//await ssa.Clear();
}
}
}

View File

@ -0,0 +1,116 @@
using AyCode.Interfaces.StorageHandlers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Net.Http.Json;
using TIAM.Database.DataLayers.Users;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Utility;
namespace TIAMWebApp.Client.Services
{
public class ServiceProviderDataServiceWeb : IServiceProviderDataService
{
private readonly HttpClient http;
private readonly ISecureStorageHandler secureStorageHandler;
private readonly IJSRuntime jsRuntime;
private readonly LogToBrowserConsole logToBrowserConsole;
public ServiceProviderDataServiceWeb(HttpClient http, ISecureStorageHandler secureStorageHandler, IJSRuntime jSRuntime)
{
this.http = http;
this.secureStorageHandler = secureStorageHandler;
this.jsRuntime = jSRuntime;
this.logToBrowserConsole = new LogToBrowserConsole(jsRuntime);
}
//22.
public Task<bool> CreateAssignedUserAsync(AssignedUser assignedUser)
{
throw new NotImplementedException();
}
//19.
public Task<bool> CreateProductAsync(Product product)
{
throw new NotImplementedException();
}
//15.
public Task<bool> CreateServiceProviderAsync(TiamServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
//21.
public Task DeleteProductAsync(Guid productId)
{
throw new NotImplementedException();
}
//13.
public Task DeleteServiceProviderAsync(Guid serviceProviderId)
{
throw new NotImplementedException();
}
//23.
public Task<List<AssignedUser>> GetAssignedUsersByProductIdAsync(Guid productId)
{
throw new NotImplementedException();
}
//17.
public async Task<Dictionary<Guid, string>?> GetPropertiesByOwnerIdAsync(Guid id)
{
var url = APIUrls.GetServiceProvidersByOwnerId;
var response = await http.PostAsJsonAsync(url, id);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<Dictionary<Guid, string>>();
return result;
}
else
{
return null;
}
}
//18.
public Task<TiamServiceProvider?> GetServiceProviderByIdAsync(Guid id)
{
throw new NotImplementedException();
}
//16.
public Task<List<TiamServiceProvider>> GetServiceProvidersAsync()
{
throw new NotImplementedException();
}
//24.
public Task RemoveAssignedUsersByContextIdAsync(Guid productId)
{
throw new NotImplementedException();
}
//20.
public Task<bool> UpdateProductAsync(Product product)
{
throw new NotImplementedException();
}
//14.
public Task<bool> UpdateServiceProviderAsync(TiamServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
}

View File

@ -9,5 +9,6 @@ namespace TIAMWebApp.Client.Services
public string? SessionId { get; set; }
public UserSessionModel? User { get; set; }
public IPAddress? IPAddress { get; set; }
public bool IsAuthenticated { get; set; } = false;
}
}

View File

@ -21,14 +21,16 @@ namespace TIAMWebApp.Client.Services
private readonly ISecureStorageHandler secureStorageHandler;
private readonly IJSRuntime jsRuntime;
private readonly LogToBrowserConsole logToBrowserConsole;
private readonly IServiceProviderDataService serviceProviderDataService;
public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public UserDataServiceWeb(HttpClient http, ISecureStorageHandler secureStorageHandler, IJSRuntime jSRuntime)
public UserDataServiceWeb(HttpClient http, ISecureStorageHandler secureStorageHandler, IJSRuntime jSRuntime, IServiceProviderDataService serviceProviderDataService)
{
this.http = http;
this.secureStorageHandler = secureStorageHandler;
this.jsRuntime = jSRuntime;
this.logToBrowserConsole = new LogToBrowserConsole(jsRuntime);
this.serviceProviderDataService = serviceProviderDataService;
}
@ -50,13 +52,15 @@ namespace TIAMWebApp.Client.Services
public async Task<UserSessionModel> IsLoggedInAsync(Guid id)
{
UserSessionModel User = null;
//api call to get user
var dbUser = await GetUserByIdAsync(id);
if (dbUser != null)
{
User = new UserSessionModel(dbUser.Id, UserType.User, dbUser.Email, 1);
//get user's properties
var hasProperties = await serviceProviderDataService.GetPropertiesByOwnerIdAsync(dbUser.Id);
//create user session model
User = new UserSessionModel(dbUser.Id, UserType.User, dbUser.Email, hasProperties, 1);
return User;
}
else
@ -67,6 +71,8 @@ namespace TIAMWebApp.Client.Services
}
public async Task<string> TestUserApi(int Param)
{
var url = APIUrls.UserTest;

View File

@ -7,3 +7,4 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using TIAMWebApp.Client
@using AyCode.Interfaces.StorageHandlers;

View File

@ -34,7 +34,7 @@
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
</body>

View File

@ -22,145 +22,63 @@ using TIAM.Entities.Users;
using TIAMWebApp.Server.ModelsTIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Utility;
using TIAM.Entities.Auctions;
using AyCode.Interfaces.Messages;
using AyCode.Entities.Messages;
using TIAMWebApp.Shared.Application.Models.ClientSide.Messages;
using AyCode.Models.Messages;
using AyCode.Models.Enums;
namespace TIAMWebApp.Server.Controllers
{
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class EmailAPIController : ControllerBase
public class MessageAPIController : ControllerBase
{
private AuctionDal _auctionDal;
private readonly IConfiguration _configuration;
private readonly IWebHostEnvironment _webHostEnvironment;
PasswordHasher hasher = new PasswordHasher();
private IMessageSenderService _messageSenderService;
private readonly ILogger<UserAPIController> _logger;
private readonly ILogger<MessageAPIController> _logger;
public EmailAPIController(ILogger<UserAPIController> logger, IConfiguration configuration, IWebHostEnvironment webHostEnvironment, AuctionDal auctionDal)
public MessageAPIController(ILogger<MessageAPIController> logger, IConfiguration configuration, IWebHostEnvironment webHostEnvironment, IMessageSenderService messageSenderService)
{
_logger = logger;
_configuration = configuration;
_webHostEnvironment = webHostEnvironment;
_auctionDal = auctionDal;
_messageSenderService = messageSenderService;
}
[AllowAnonymous]
[HttpPost]
[Route("SendEmail")]
public async Task<IActionResult> SendEmail([FromBody] AuctionBid SerializedAuctionBidModel)
public async Task<IActionResult> SendEmail([FromBody] EmailMessageSenderModel SerializedMessageSenderModel)
{
Console.WriteLine("CreateBid called");
//if (string.IsNullOrEmpty(SerializedAuctionBidModel.GetRawText()))
//{
// return BadRequest("SerializedAuctionBidModel is required");
//}
//else
//{
//AuctionBidModel? bid = JObject.Parse(SerializedAuctionBidModel.GetRawText()).ToObject<AuctionBidModel>();
AuctionBid bid = SerializedAuctionBidModel;
AuctionBid finalizedBidModel;
if(bid != null)
if (SerializedMessageSenderModel != null)
{
//add userModel to users array
//Array.Resize(ref users, users.Length + 1);
//users[users.Length - 1] = new UserModel(user.Email, user.PhoneNumber, user.Password);
var userId = bid.OwnerId;
var targetProductId = bid.TargetProductId;
string? email = bid?.Email;
string? phoneNumber = bid?.PhoneNumber;
int bidAmount = bid?.BidAmount ?? 0;
bool isValid = false;
if (SerializedMessageSenderModel.MessageType == MessageTypesEnum.email && SerializedMessageSenderModel.Message is EmailMessage)
{
Console.WriteLine($"EmailMessage!!!");
var result = await _messageSenderService.SendMessageAsync(SerializedMessageSenderModel.Message, (int)SerializedMessageSenderModel.MessageType);
Console.WriteLine("SendEmail result: " + result);
return Ok(result);
if(userId == Guid.Empty || string.IsNullOrEmpty(email) || targetProductId==0 || bidAmount == 0)
{
return BadRequest("Invalid request");
}
else
{
Console.WriteLine($"Bid to be created: {userId}, {targetProductId}, {email}, {phoneNumber}, {bidAmount}, {isValid}");
finalizedBidModel = new AuctionBid(userId, targetProductId, email, phoneNumber, bidAmount);
await _auctionDal.CreateBidAsync(finalizedBidModel);
return Ok(finalizedBidModel.Id);
}
}
else
{
return BadRequest("Invalid request");
}
//}
// Access BaseClass properties
}
[AllowAnonymous]
[HttpGet]
[Route("GetBids")]
public Task<List<AuctionBid>> GetBids()
{
//var users = await _userDal.Ctx.Users.ToListAsync();//.GetUsersAsync();
//return users;
return _auctionDal.GetBids();
}
[AllowAnonymous]
[HttpGet]
[Route("GetBidsByEmail")]
public async Task<List<AuctionBid>> GetUserByEmail(string email)
{
return await _auctionDal.GetBidsByEmail(email);
}
[AllowAnonymous]
[HttpPost]
[Route("ValidateBid")]
public async Task<IActionResult> ValidateBid([FromBody] AuctionBid SerializedAuctionBidModel)
{
Console.WriteLine("ValidateBid called");
//var validateBid = JObject.Parse(SerializedAuctionBidModel.GetRawText()).ToObject<AuctionBidModel>();
//check if bid exists
AuctionBid? dbBid = null;
//Console.WriteLine(validateBid?.Id);
Console.WriteLine(SerializedAuctionBidModel?.Id);
//if (validateBid != null)
if (SerializedAuctionBidModel != null)
{
//dbBid = await _auctionDal.GetBidById(validateBid.Id);
dbBid = await _auctionDal.GetBidById(SerializedAuctionBidModel.Id);
}
//check if password is valid
//bool isValidUser = await _userManager.CheckPasswordAsync(userModel, authenticateUser.Password);
//mocking
if (dbBid is null)
{
return Unauthorized("Not found in DB");
}
else
{
//if (dbBid.Email == validateBid?.Email)
if (dbBid.Email == SerializedAuctionBidModel?.Email)
{
Console.WriteLine("Bid is valid");
dbBid.IsValid = true;
//Update userModel with refreshToken!!
await _auctionDal.UpdateBidAsync(dbBid);
return Ok(dbBid.IsValid);
}
else
{
return Unauthorized("Emails not matching");
}
}
return BadRequest("Invalid request");
}

View File

@ -0,0 +1,163 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System.Text.Json;
using TIAM.Database.DataLayers.ServiceProviders;
using TIAM.Entities.Permissions;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
using TIAMWebApp.Shared.Application.Models;
namespace TIAMWebApp.Server.Controllers
{
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ServiceProviderAPIController : ControllerBase
{
private ServiceProviderDal _serviceProviderDal;
private readonly ILogger<ServiceProviderAPIController> _logger;
public ServiceProviderAPIController(ILogger<ServiceProviderAPIController> logger, ServiceProviderDal serviceProviderDal)
{
_logger = logger;
_serviceProviderDal = serviceProviderDal;
}
//15.
[HttpPost]
[Route("CreateServiceProvider")]
public async Task<IActionResult> CreateServiceProvider([FromBody] ServiceProviderModel SerializedServiceProviderModel)
{
Console.WriteLine("CreateUser called");
if (SerializedServiceProviderModel == null)
{
return BadRequest("SerializedLoginModel is required");
}
else
{
//ServiceProviderModel? serviceProvider = JObject.Parse(SerializedServiceProviderModel.GetRawText()).ToObject<ServiceProviderModel>();
ServiceProviderModel? serviceProvider = SerializedServiceProviderModel;
if (serviceProvider != null)
{
//add userModel to users array
//Array.Resize(ref users, users.Length + 1);
//users[users.Length - 1] = new UserModel(user.Email, user.PhoneNumber, user.Password);
var id = Guid.NewGuid();
string? name = SerializedServiceProviderModel?.Name;
Guid ownerId = SerializedServiceProviderModel?.OwnerId ?? Guid.Empty;
if (name is null || ownerId == Guid.Empty)
{
return BadRequest("Invalid request");
}
else
{
Console.WriteLine($"ServiceProvider to be created: {id}, {name}, {ownerId}");
await _serviceProviderDal.CreateServiceProviderAsync(new TiamServiceProvider(id, name, ownerId));
}
}
return Ok("yes");
}
}
//16.
[AllowAnonymous]
[HttpGet]
[Route("GetServiceProviders")]
public Task<List<TiamServiceProvider>> GetServiceProviders()
{
//var users = await _serviceProviderDal.Ctx.Users.ToListAsync();//.GetUsersAsync();
//return users;
return _serviceProviderDal.GetServiceProvidersAsync();
}
//18.
[AllowAnonymous]
[HttpPost]
[Route("GetServiceProviderById")]
public async Task<TiamServiceProvider?> GetServiceProviderById([FromBody] Guid id)
{
Console.WriteLine($"GetServiceProviderById called with id: {id}");
return await _serviceProviderDal.GetServiceProviderByIdAsync(id);
}
//17.
[AllowAnonymous]
[HttpPost]
[Route("GetServiceProvidersByOwnerId")]
public async Task<Dictionary<Guid, string>> GetServiceProvidersByOwnerId(Guid ownerId)
{
Console.WriteLine($"GetServiceProvidersByOwnerId called with ownerId: {ownerId}");
var serviceProviders = await _serviceProviderDal.GetServiceProvidersAsync();
//return serviceProviders.Where(x => x.OwnerId == ownerId).ToList();
var myServiceproviders = serviceProviders.Where(x => x.OwnerId == ownerId).ToDictionary(x => x.Id, x => x.Name);
//put serviceprovider id and name into a dictionary
return myServiceproviders;
}
//22.
[AllowAnonymous]
[HttpPost]
[Route("CreateAssignedUser")]
public async Task<IActionResult> CreateAssignedUser(Guid productId, Guid userId)
{
if(productId == Guid.Empty || userId == Guid.Empty)
{
return BadRequest("Invalid request");
}
else
{
Console.WriteLine($"CreateAssignedUsers called with ownerId: {productId}, {userId}");
AssignedUser assignedUser = new AssignedUser(productId, userId, 1);
var result = await _serviceProviderDal.CreateAssignedUserAsync(assignedUser);
return Ok(result);
}
}
//23.
[AllowAnonymous]
[HttpPost]
[Route("GetAssignedUsersForProduct")]
public async Task<Dictionary<Guid, string>> GetAssignedUsersForProduct(Guid serviceProviderId)
{
Console.WriteLine($"GetAssignedUsersForServiceProvider called with serviceProviderId: {serviceProviderId}");
Dictionary<Guid, string> assignedUserDictionary = new Dictionary<Guid, string>();
var serviceProviders = await _serviceProviderDal.GetServiceProvidersAsync();
var myServiceproviders = serviceProviders.Where(x => x.Id == serviceProviderId).ToDictionary(x => x.Id, x => x.Name);
//put serviceprovider id and name into a dictionary
return myServiceproviders;
}
}
}

View File

@ -0,0 +1,138 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System.Text.Json;
using TIAM.Database.DataLayers.ServiceProviders;
using TIAM.Database.DataLayers.Users;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.Products.DTOs;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Models.PageModels;
namespace TIAMWebApp.Server.Controllers
{
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class UserPermissionAPIController : ControllerBase
{
private ServiceProviderDal _serviceProviderDal;
private readonly ILogger<UserPermissionAPIController> _logger;
public UserPermissionAPIController(ILogger<UserPermissionAPIController> logger, ServiceProviderDal serviceProviderDal)
{
_logger = logger;
_serviceProviderDal = serviceProviderDal;
}
//1. create a permission to be assigned to users to access a context
//public Task CreatePermissionForContextByContextIdAsync(Guid contextId);
//2. get the contexts where the user has permission
[AllowAnonymous]
[HttpGet]
[Route("GetPermissionContextByUserId")]
public async Task<IActionResult> GetPermissionContextByUserId(Guid userId)
{
if (userId == Guid.Empty)
{
return BadRequest("UserId is required");
}
else
{
Console.WriteLine($"GetPermissionContextByUserId called with userId: {userId}");
List<AssignedPermissionModel> response = await _serviceProviderDal.GetPermissionContextByUserIdAsync(userId);
return Ok(response);
}
}
//3. get permissions of all users and groups for context by contextId
[AllowAnonymous]
[HttpGet]
[Route("GetPermissionsForContextByContextId")]
public async Task<IActionResult> GetPermissionsForContextByContextId(Guid contextId)
{
if (contextId == Guid.Empty)
{
return BadRequest("ContextId is required");
}
else
{
Console.WriteLine($"GetPermissionsForContextByContextId called with contextId: {contextId}");
Dictionary<Guid, int> permissionsDictionary = new Dictionary<Guid, int>();
var permissions = await _serviceProviderDal.GetPermissionsForContextByContextIdAsync(contextId);
return Ok(permissions);
}
}
//4. give a user permission to access a context
//public Task AssignPermissionToUserForContextAsync(Guid contextId, Guid userId);
[AllowAnonymous]
[HttpPost]
[Route("AssignPermissionToUserForContext")]
public async Task<IActionResult> AssignPermissionToUserForContext(AssignPermissionModel assignPermissionModel)
{
Console.WriteLine("AssignPermissionToUserForContext called");
if (assignPermissionModel == null)
{
return BadRequest("ContextId and UserId are required");
}
else
{
var response = await _serviceProviderDal.AssignPermissionToUserForContextAsync(assignPermissionModel.AssignedUser, assignPermissionModel.PermissionsType);
return Ok(response);
}
}
//5. remove a user's permission to access a context
//public Task RemovePermissionFromUserByContextIdAsync(Guid contextId, Guid permissionId, Guid userId);
//6. remove all permissions of a user for a context
//public Task RemoveAllPermissionsByContextIdAsync(Guid contextId, Guid userId);
//7. remove all permissions of a user (BAN user from all contexts, even the system)
//public Task RemoveAllPermissionsByUserIdAsync(Guid userId);
//8. create permission group
//public Task CreatePermissionGroupForContextAsync(Guid contextId, string name);
//9. add user to permission group
//public Task AddUserToPermissionGroupAsync(Guid permissionGroupId, Guid userId);
//10. create permission type
//public Task<bool> CreatePermissionTypeAsync(string name, Guid contextId, int bitValue);
[AllowAnonymous]
[HttpPost]
[Route("CreatePermissionType")]
public async Task<IActionResult> CreatePermissionType(string name, Guid contextId)
{
Console.WriteLine("CreatePermissionType called");
if (String.IsNullOrEmpty(name) || contextId == Guid.Empty)
{
return BadRequest("SerializedPermissionTypeModel is required");
}
else
{
PermissionsType permissionType = new PermissionsType(contextId, name);
var response = await _serviceProviderDal.CreatePermissionsTypeAsync(permissionType);
return Ok(response);
}
}
//11. get permission types for context
//public Task<List<PermissionsType>>? GetPermissionTypesForContextByContextIdAsync(Guid contextId);
//12. get permission groups for context
//public Task GetPermissionGroupsForContextByContextIdAsync(Guid contextId);
}
}

View File

@ -13,6 +13,9 @@ using Microsoft.OpenApi.Models;
using TIAMWebApp.Shared.Application.Models;
using TIAM.Database.DataLayers.Users;
using TIAM.Database.DataLayers.TransferDestinations;
using AyCode.Interfaces.Messages;
using TIAMWebApp.Server.Services;
using TIAM.Database.DataLayers.ServiceProviders;
var builder = WebApplication.CreateBuilder(args);
@ -24,6 +27,7 @@ builder.Services.AddRazorPages();
builder.Services.AddScoped<UserDal>();
builder.Services.AddScoped<AdminDal>();
builder.Services.AddScoped<AuctionDal>();
builder.Services.AddScoped<ServiceProviderDal>();
builder.Services.AddScoped<TransferDestinationDal>();
builder.Services.AddSwaggerGen(swagger =>
@ -79,7 +83,7 @@ builder.Services.AddAuthentication(f =>
});
builder.Services.AddScoped<IMessageSenderService, NoticeSenderService>();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

View File

@ -1,79 +0,0 @@
using AyCode.Interfaces.Messages;
using SendGrid;
using SendGrid.Helpers.Mail;
using AyCode.Models.Enums;
using AyCode.Entities.Messages;
using AyCode.Models.Messages;
using TIAM.Database.DataLayers.Users;
namespace TIAMWebApp.Server.Controllers
{
public class MessageService : IMessageSenderService
{
private readonly HttpClient http;
private readonly IConfiguration _configuration;
public UserDal _userDal;
public MessageService(HttpClient http, IConfiguration configuration, UserDal userDal)
{
this.http = http;
_configuration = configuration;
_userDal = userDal;
}
public async Task<bool> SendMessageAsync(IMessageBase message, int[] messageTypes)
{
foreach (var messageType in messageTypes)
{
switch (messageType)
{
case (int)MessageTypesEnum.email:
await SendMailWithSendgrid(((EMailMessage)message));
break;
case (int)MessageTypesEnum.sms:
//await SendSmsWithTwilio(message.Message);
break;
case (int)MessageTypesEnum.push:
//await SendPushWithFirebase(message.Message);
break;
case (int)MessageTypesEnum.chat:
//await SendChatWithSignalR(message.Message);
default:
break;
}
}
//return true here
return await Task.FromResult(true);
}
public async Task<string> SendMailWithSendgrid(EMailMessage message)
{
//resolve user!!!
var senderUser = _userDal.Ctx.Users.FirstOrDefault(x => x.Id == message.SenderId);
var receiverUser = _userDal.Ctx.Users.FirstOrDefault(x => x.Id == message.ReceiverId);
string apiKey = _configuration["SendGrid:Key"];
var _client = new SendGridClient(apiKey);
var _from = new EmailAddress("", "");
if(message.SenderId == null)
{
_from = new EmailAddress("noreply@tiam.com", "TourIAm mailservice");
}
else
{
_from = new EmailAddress(senderUser.Email, senderUser.Email);
}
var _subject = message.Subject;
var _to = new EmailAddress(receiverUser.Email, receiverUser.Email);
var _plainTextContent = message.Message;
var _htmlContent = message.HtmlContent;
var _msg = MailHelper.CreateSingleEmail(_from, _to, message.Subject, _plainTextContent, _htmlContent);
var response = await _client.SendEmailAsync(_msg).ConfigureAwait(false);
return response.StatusCode.ToString();
}
}
}

View File

@ -0,0 +1,89 @@
using AyCode.Interfaces.Messages;
using SendGrid;
using SendGrid.Helpers.Mail;
using AyCode.Models.Enums;
using AyCode.Entities.Messages;
using AyCode.Models.Messages;
using TIAM.Database.DataLayers.Users;
namespace TIAMWebApp.Server.Services
{
public class NoticeSenderService : IMessageSenderService
{
private readonly IConfiguration _configuration;
public UserDal _userDal;
public NoticeSenderService(IConfiguration configuration, UserDal userDal)
{
_configuration = configuration;
_userDal = userDal;
}
public async Task<string> SendMessageAsync<TNotice>(TNotice message, int messageType) where TNotice : class, INoticeBase
{
string result = "";
switch (messageType)
{
case (int)MessageTypesEnum.email:
if (message is EmailMessage emailMessage)
{
Console.WriteLine($"EmailMessage!!!");
// Access DerivedClass properties
var _subject = emailMessage.Subject;
result = await SendMailWithSendgrid(emailMessage);
}
else
{
// Access BaseClass properties
result = "Invalid message";
}
break;
case (int)MessageTypesEnum.sms:
//await SendSmsWithTwilio(message.Message);
break;
case (int)MessageTypesEnum.push:
//await SendPushWithFirebase(message.Message);
break;
case (int)MessageTypesEnum.chat:
//await SendChatWithSignalR(message.Message);
default:
break;
}
return result;
}
public async Task<string> SendMailWithSendgrid(EmailMessage message)
{
Console.WriteLine($"Sender: {message.SenderId}");
Console.WriteLine($"Message: {message.Message}");
//resolve user!!!
var senderUser = _userDal.Ctx.Users.FirstOrDefault(x => x.Id == message.SenderId);
var receiverUser = _userDal.Ctx.Users.FirstOrDefault(x => x.Id == message.ReceiverId);
string apiKey = _configuration["SendGrid:Key"];
var _client = new SendGridClient(apiKey);
var _from = new EmailAddress("", "");
if (message.SenderId == Guid.Empty)
{
_from = new EmailAddress("noreply@tiam.com", "TourIAm mailservice");
}
else
{
_from = new EmailAddress(senderUser.Email, senderUser.Email);
}
var _subject = message.Subject;
var _to = new EmailAddress(receiverUser.Email, receiverUser.Email);
var _plainTextContent = message.Message;
var _htmlContent = message.HtmlContent;
var _msg = MailHelper.CreateSingleEmail(_from, _to, message.Subject, _plainTextContent, _htmlContent);
var response = await _client.SendEmailAsync(_msg).ConfigureAwait(false);
return response.StatusCode.ToString();
}
}
}

View File

@ -11,6 +11,7 @@
"Audience": "http://localhost:7116"
},
"SendGrid": {
"Key": ""
//"Key": "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"
"Key": "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"
}
}

View File

@ -15,7 +15,8 @@
"Audience": "http://localhost:5000"
},
"SendGrid": {
"Key": ""
//"Key": "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"
"Key": "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"
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TIAMWebApp.Shared.Application.Interfaces
{
public interface IComponentUpdateService
{
event Action RefreshRequested;
void CallRequestRefresh();
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.Products.DTOs;
using TIAM.Entities.ServiceProviders;
namespace TIAMWebApp.Shared.Application.Interfaces
{
public interface IPermissionService
{
//1. create a permission to be assigned to users to access a context
public Task CreatePermissionForContextByContextIdAsync(Guid contextId);
//2. get the contexts where the user has permission
public Task<List<AssignedPermissionModel>> GetPermissionContextsByUserIdAsync(Guid userId);
//3. get the users who have permission for a context
public Task<List<AssignedPermissionModel>> GetPermissionsForContextByContextIdAsync(Guid contextId);
//4. give a user permission to access a context
public Task AssignPermissionToUserForContextAsync(Guid contextId, Guid userId);
//5. remove a user's permission to access a context
public Task RemovePermissionFromUserByContextIdAsync(Guid contextId, Guid permissionId, Guid userId);
//6. remove all permissions of a user for a context
public Task RemoveAllPermissionsByContextIdAsync(Guid contextId, Guid userId);
//7. remove all permissions of a user (BAN user from all contexts, even the system)
public Task RemoveAllPermissionsByUserIdAsync(Guid userId);
//8. create permission group
public Task CreatePermissionGroupForContextAsync(Guid contextId, string name);
//9. add user to permission group
public Task AddUserToPermissionGroupAsync(Guid permissionGroupId, Guid userId);
//10. create permission type
public Task<bool> CreatePermissionTypeAsync(string name, Guid contextId);
//11. get permission types for context
public Task<List<PermissionsType>>? GetPermissionTypesForContextByContextIdAsync(Guid contextId);
//12. get permission groups for context
public Task GetPermissionGroupsForContextByContextIdAsync(Guid contextId);
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;
using TIAMWebApp.Shared.Application.Models;
namespace TIAMWebApp.Shared.Application.Interfaces
{
public interface IServiceProviderDataService
{
//17. (IServiceProviderDataService) get service providers by ownerId
public Task<Dictionary<Guid, string>?> GetPropertiesByOwnerIdAsync(Guid id);
//13. delete service provider
public Task DeleteServiceProviderAsync(Guid serviceProviderId);
//14 Update service provider
public Task<bool> UpdateServiceProviderAsync(TiamServiceProvider serviceProvider);
//15. Create service provider
public Task<bool> CreateServiceProviderAsync(TiamServiceProvider serviceProvider);
//16. (IServiceProviderDataService) get all service providers
public Task<List<TiamServiceProvider>> GetServiceProvidersAsync();
//18. (IServiceProviderDataService) get serviceProvider by Id
public Task<TiamServiceProvider?> GetServiceProviderByIdAsync(Guid id);
//19. (IServiceProviderDataService) Create product
public Task<bool> CreateProductAsync(Product product);
//20. (IServiceProviderDataService) Update product
public Task<bool> UpdateProductAsync(Product product);
//21. (IServiceProviderDataService) Delete product
public Task DeleteProductAsync(Guid productId);
//22. (IServiceProviderDataService) Create assignedUser
public Task<bool> CreateAssignedUserAsync(AssignedUser assignedUser);
//23. (IServiceProviderDataService) Get Assigned Users By ProductId
public Task<List<AssignedUser>> GetAssignedUsersByProductIdAsync(Guid productId);
//24. (IServiceProviderDataService) Remove Assigned Users from Product
public Task RemoveAssignedUsersByContextIdAsync(Guid productId);
}
}

View File

@ -13,5 +13,6 @@ namespace TIAMWebApp.Shared.Application.Interfaces
public string? SessionId { get; set; }
public UserSessionModel? User { get; set; }
public IPAddress? IPAddress { get; set; }
public bool IsAuthenticated { get; set; }
}
}

View File

@ -15,10 +15,27 @@ namespace TIAMWebApp.Shared.Application.Models
public const string AuthenticateUser = "api/UserAPI/AuthenticateUser";
public const string CreateUser = "api/UserAPI/CreateUser";
public const string RefreshToken = "/api/UserAPI/RefreshToken";
public const string WeatherForecast = "api/WeatherForecastAPI";
public const string PopulationStructure = "PopulationStructureAPI";
public const string GetTransferDestinations = "api/TransferDataAPI/GetTransferDestinations";
public const string GetTransferDestinationByCoordinates = "api/TransferDataAPI/GetTransferDestinationByCoordinates";
public const string GetTransferDestinationByAddress = "api/TransferDataAPI/GetTransferDestinationByAddress";
public const string GetServiceProvidersByOwnerId = "api/ServiceProviderAPI/GetServiceProvidersByOwnerId";
//AssingedUsers
public const string CreateAssignedUser = "api/ServiceProviderAPI/CreateAssignedUser";
public const string GetAssignedUsersForServiceProvider = "api/ServiceProviderAPI/GetAssignedUsersForServiceProvider";
//permissions
//1
public const string GetPermissionsForContextByContextId = "api/UserPermissionAPI/GetPermissionsForContextByContextId";
//2. get the contexts where the user has permission
public const string GetPermissionContextByUserId = "api/UserPermissionAPI/GetPermissionContextByUserId";
//12
public const string GetPermissionGroupsForContextByContextId = "api/UserPermissionAPI/GetPermissionGroupsForContextByContextId";
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAM.Entities.Permissions;
using TIAM.Entities.Users;
namespace TIAMWebApp.Shared.Application.Models
{
public class AssignPermissionModel
{
public AssignedUser AssignedUser { get; set; }
public PermissionsType PermissionsType { get; set; }
public AssignPermissionModel(AssignedUser assignedUser, PermissionsType permissionsType) {
AssignedUser = assignedUser;
PermissionsType = permissionsType;
}
}
}

View File

@ -0,0 +1,24 @@
using AyCode.Models.Enums;
using AyCode.Models.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TIAMWebApp.Shared.Application.Models.ClientSide.Messages
{
public class EmailMessageSenderModel : MessageSenderModel<EmailMessage>
{
public EmailMessageSenderModel()
{
}
public EmailMessageSenderModel(EmailMessage message, MessageTypesEnum messageType)
{
Message = message;
MessageType = messageType;
}
}
}

View File

@ -0,0 +1,61 @@
using AyCode.Entities.Messages;
using AyCode.Interfaces.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AyCode.Models.Enums;
using AyCode.Models.Messages;
namespace TIAMWebApp.Shared.Application.Models.ClientSide.Messages
{
public class MessageSenderModel<TMessageType> where TMessageType : NoticeBase
{
public TMessageType Message { get; set; }
//public NoticeBase? Message { get; set; }
public MessageTypesEnum MessageType { get; set; }
public MessageSenderModel()
{
}
public MessageSenderModel(TMessageType message, MessageTypesEnum messageType)
{
Message = message;
MessageType = messageType;
}
/*public MessageSenderModel(EmailMessage message, MessageTypesEnum messageType)
{
if (message is EmailMessage)
{
Message = new EmailMessage();
Message = message as EmailMessage;
Message = message;
}
/*else if (message is SmsMessage)
{
Message = message as SmsMessage;
}
else if (message is PushMessage)
{
Message = message as PushMessage;
}
else if (message is ChatMessage)
{
Message = message as ChatMessage;
}
else
{
Message = message;
}
MessageType = messageType;
}*/
}
}

View File

@ -10,5 +10,7 @@ namespace TIAMWebApp.Shared.Application.Models.ClientSide
{
public static UserBasicDetails UserBasicDetails { get; set; }
public const string BaseUrl = "https://localhost:7116";
public const bool DarkMode = false;
public static string Locale { get; set; }
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
@ -9,9 +10,20 @@ namespace TIAMWebApp.Shared.Application.Models.PageModels
{
public class LoginModel
{
[Required(ErrorMessage = "The email address value should be specified.")]
[DataType(DataType.Text)]
[Display(Name = "Email-string")]
public string? Email { get; set; }
[Required(ErrorMessage = "The password should be specified.")]
[DataType(DataType.Password)]
[Display(Name = "Login-Password")]
public string? Password { get; set; }
public LoginModel(string email, string password)
{
Email = email;
Password = password;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TIAMWebApp.Shared.Application.Models
{
public class ServiceProviderModel
{
public Guid Id { get; set; }
public string? Name { get; set; }
public Guid OwnerId { get; set; }
public ServiceProviderModel() { }
public ServiceProviderModel(Guid id, string name, Guid ownerId)
{
Id = id;
Name = name;
OwnerId = ownerId;
}
}
}

View File

@ -1,4 +1,5 @@
using TIAM.Entities.Users;
using System.Collections.Generic;
using TIAM.Entities.Users;
namespace TIAMWebApp.Shared.Application.Models
{
@ -7,16 +8,19 @@ namespace TIAMWebApp.Shared.Application.Models
public Guid UserId { get; set; }
public UserType UserType { get; set; }
public string Email { get; set; }
public Dictionary<Guid, string>? HasProperties { get; set; }
public int UserRoles { get; set; }
public Dictionary<int, string> UserRolesDictionary { get; set; }
public UserSessionModel(Guid userId, UserType userType, string email, int userRoles)
public UserSessionModel(Guid userId, UserType userType, string email, Dictionary<Guid, string>? hasProperties, int userRoles)
{
UserId = userId;
UserType = userType;
Email = email;
UserRoles = userRoles;
UserRolesDictionary = new Dictionary<int, string>();
HasProperties = hasProperties;
//UserRoles = userRoles;
//UserRolesDictionary = new Dictionary<int, string>();
}
}

View File

@ -12,6 +12,7 @@
<ItemGroup>
<Folder Include="Models\DTO\" />
<Folder Include="Models\ServerSide\Messages\" />
</ItemGroup>
<ItemGroup>
@ -45,5 +46,11 @@
<Reference Include="AyCode.Interfaces.Server">
<HintPath>..\..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Interfaces.Server.dll</HintPath>
</Reference>
<Reference Include="AyCode.Models">
<HintPath>..\..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Models.dll</HintPath>
</Reference>
<Reference Include="AyCode.Services">
<HintPath>..\..\..\AyCode.Core\AyCode.Services.Server\bin\Debug\net8.0\AyCode.Services.dll</HintPath>
</Reference>
</ItemGroup>
</Project>